Skip to content

Node.js SDK

@fabric-messaging/sdk is the official, server-only TypeScript SDK. It targets Node.js 22+ and ships as ESM.

Terminal window
npm install @fabric-messaging/sdk
import { Fabric } from "@fabric-messaging/sdk";
const fabric = new Fabric({
apiKey: process.env.FABRIC_API_KEY!, // required; sk_test_ or sk_live_
timeout: 10_000, // ms per HTTP attempt, default 10_000
maxRetries: 2, // default 2
});
Option Default Notes
apiKey — Required. The prefix selects sandbox vs live.
timeout 10_000 Per HTTP attempt; total time can include retries and backoff.
maxRetries 2 Retries for eligible failures (see below).
fetch global fetch Inject a custom fetch implementation.
logger — A FabricLogger for request / response / retry events.

Fabric is also exported as MessagingClient. It throws if constructed in a browser.

There is no endpoint option: the SDK selects the Fabric endpoint, and your key prefix decides sandbox versus live. To point a local build at a development server, set FABRIC_BASE_URL in the environment — the same variable the CLI reads. It must be HTTPS unless it is loopback, and it may not carry credentials, a query string or a fragment.

Each namespace maps to a part of the API:

Namespace Methods
fabric.messages preview(key, …) · send(key, …) · retrieveDelivery(id) · listDeliveries() · iterateDeliveries() · listDeliveryWebhooks(id)
fabric.sms send · sendBatch · retrieve · retrieveBatch · list · iterate
fabric.email send · retrieve · list · iterate
fabric.whatsapp send · retrieve · list · iterate
fabric.verify start · check
fabric.senderIds create · list
fabric.wallet retrieve
fabric.webhooks create · list · remove · listDeliveries · iterateDeliveries · replayDelivery · verify

Every request-returning method resolves to a FabricResponse<T>:

{ data: T; requestId?: string; retryCount: number; statusCode: number }

Read your result from .data; .requestId is worth logging for support.

The SDK retries automatically on 429, 500, 502, 503, and 504. A request is retried only if it is a GET, or if the endpoint durably implements Idempotency-Key and the caller supplied a valid key. Direct SMS/Email sends and Verify start accept an optional key; batch, WhatsApp, and managed sends require one. Sender-ID, Verify check, and webhook-management writes do not implement replay storage and are never retried automatically. Backoff is randomised exponential, capped at 4 seconds, and honours Retry-After on rate limits.

await fabric.sms.send(params, { idempotencyKey: "op-123" }); // now eligible for retry

Catch the exported classes rather than branching on message text:

import { RateLimitError, ValidationError, AuthenticationError } from "@fabric-messaging/sdk";
try {
await fabric.messages.send("order.shipped", opts);
} catch (err) {
if (err instanceof RateLimitError) {
// err.retryAfter (seconds) may be set
} else if (err instanceof ValidationError) {
// err.code, err.details.param
} else if (err instanceof AuthenticationError) {
// bad or revoked key
}
}
Class When
AuthenticationError 401 — key missing, malformed, or revoked.
AuthorizationError 403 — key lacks the required scope.
ValidationError 400 / 422, or a client-side input error before the request.
NotFoundError 404.
ConflictError 409 — e.g. an idempotency key reused with a different body.
RateLimitError 429 — carries retryAfter when the server sends it.
TimeoutError · ConnectionError · UserAbortedError Transport failures.
WebhookVerificationError A signature failed to verify.
ResponseValidationError The response did not match the expected shape.

Every error carries a stable code, and retryable tells you whether the SDK considered it eligible for a retry.