JavaScript and TypeScript
The Stormedo JavaScript SDK supports Node.js 22 and newer. Create one client with a project API key and reuse it throughout your server application.
Install
Section titled “Install”npm install @stormedo/sdkpnpm add @stormedo/sdkyarn add @stormedo/sdkbun add @stormedo/sdkCreate a client
Section titled “Create a client”import { Stormedo } from "@stormedo/sdk";
const stormedo = new Stormedo(process.env.STORMEDO_TOKEN!);Keep STORMEDO_TOKEN in server-side configuration. Do not expose a project API key to browser code.
Send a request
Section titled “Send a request”const request = await stormedo.send("https://your-app.example/webhooks/stormedo", { body: { type: "order.created", orderId: "ord_123", }, delay: { minutes: 5 }, maxAttempts: 5,});
console.log(request.id, request.status);maxAttempts counts the initial attempt.
Forward exact bytes
Section titled “Forward exact bytes”Use rawBody when Stormedo must forward bytes unchanged.
await stormedo.send("https://your-app.example/events", { rawBody: new TextEncoder().encode("event=created"), contentType: "application/x-www-form-urlencoded", headers: { Authorization: "Bearer destination-token", },});The headers you provide are sent to the destination. Stormedo never forwards your project API key.
Send a batch
Section titled “Send a batch”Submit multiple independent requests in one API call:
const requests = await stormedo.sendBatch([ { url: "https://your-app.example/webhooks/orders", body: { type: "order.created", orderId: "ord_123" }, }, { url: "https://your-app.example/webhooks/inventory", body: { type: "inventory.sync", warehouseId: "wh_7" }, delay: { hours: 1 }, },]);
console.log(requests.map((request) => request.id));delay and timeout accept duration objects with days, hours, minutes,
and seconds. deliverAt accepts a Date.
Inspect request history
Section titled “Inspect request history”listRequests supports status, search, method, source, time range, cursor, and limit filters:
const page = await stormedo.listRequests({ status: "failed", method: "POST", limit: 25,});
console.log(page.items);
if (page.nextCursor) { const nextPage = await stormedo.listRequests({ status: "failed", method: "POST", limit: 25, cursor: page.nextCursor, });
console.log(nextPage.items);}Load request detail and completed attempts independently:
const detail = await stormedo.getRequest(request.id);const attempts = await stormedo.listRequestAttempts(request.id);
console.log(detail.status, attempts.length);Cancel and replay
Section titled “Cancel and replay”await stormedo.cancelRequest(request.id);const replay = await stormedo.replayRequest(request.id);
console.log(replay.id);Cancellation preserves the original request and attempt history. Replay creates a new request linked to the original.
Manage recurring schedules
Section titled “Manage recurring schedules”Create schedules with cron or fixed-interval timing:
import { cronTiming, intervalTiming } from "@stormedo/sdk";
const schedule = await stormedo.createSchedule({ name: "sync-inventory", timing: cronTiming("0 */6 * * *", "Asia/Kolkata"), url: "https://your-app.example/inventory/sync", body: { fullSync: true }, maxAttempts: 4,});
await stormedo.updateSchedule(schedule.id, { timing: intervalTiming({ hours: 4 }),});
const schedules = await stormedo.listSchedules();const definition = await stormedo.getSchedule(schedule.id);
console.log(schedules.length, definition.status);
await stormedo.pauseSchedule(schedule.id);await stormedo.resumeSchedule(schedule.id);await stormedo.deleteSchedule(schedule.id);cronTiming accepts a five-field cron expression and an IANA timezone.
intervalTiming accepts days, hours, and minutes; the combined duration
must be a whole number of minutes from one minute through 30 days. Pass a future
Date as startsAt to choose the first run time.
Handle API errors
Section titled “Handle API errors”API and network failures throw StormedoError. Use code for program logic and requestId when contacting Stormedo support.
import { StormedoError } from "@stormedo/sdk";
try { await stormedo.getRequest("req_33uZSQsVaf8aZjDuzkuAq");} catch (error) { if (error instanceof StormedoError) { console.error(error.code, error.status, error.requestId, error.details); }}Next step
Section titled “Next step”Read Delivery verification before processing signed requests at your destination.