Node.js
@divergent.dev/connect sends and manages SMS and email with the v2 API. It needs Node.js 18 or later, has no dependencies and comes with TypeScript types.
Installing
Section titled “Installing”npm install @divergent.dev/connect@previewThe 0.5.x versions are for the v1 API.
Setting up the client
Section titled “Setting up the client”import { ConnectClient } from "@divergent.dev/connect";
const connect = new ConnectClient({ apiKey: process.env.CONNECT_API_KEY, defaultSmsSender: "YourBrand", defaultEmailSender: "hello@yourcompany.com",});| Option | Description |
|---|---|
apiKey | Your v2 API key. Required |
defaultSmsSender | Used when an SMS or batch doesn’t set sender |
defaultEmailSender | Used when an email doesn’t set sender |
apiKeyId, signingSecret | Signs every request, for keys that need signed requests |
signingKey | Signs with an ECDSA P-256 private key instead, for keys registered with a public key |
baseUrl | Defaults to https://api.connect.ms |
fetch | Your own fetch. Defaults to the built-in one |
Every request is sent with Connect-Version: 2026-10-01, the version the client is written for.
Sending SMS
Section titled “Sending SMS”const sms = await connect.sms.send({ recipient: "+447700900123", content: "Hi Sam, your order has shipped.",});
console.log(sms.id, sms.status);The request and the returned message are the same as the API’s. See Send SMS and Track SMS.
| Method | API |
|---|---|
sms.send(request) | POST /v2/sms |
sms.get(id) | GET /v2/sms/{id} |
sms.list(query), sms.listAll(query) | GET /v2/sms |
sms.cancel(id) | DELETE /v2/sms/{id} |
sms.createBatch(request), sms.getBatch(id), sms.cancelBatch(id) | Batches |
Sending email
Section titled “Sending email”await connect.email.send({ recipient: "sam@example.com", subject: "Your order has shipped", content: { html: "<p>Hi Sam, your order is on its way.</p>", text: "Hi Sam, your order is on its way." },});Attachment content is base64. See Send Email.
The email methods are send, get, list, listAll and cancel, like sms.
Listing
Section titled “Listing”list returns one page, { data, nextCursor }. Pass nextCursor back as cursor for the next page. listAll fetches every page for you:
for await (const message of connect.sms.listAll({ status: "failed", since: "2026-10-01T00:00:00Z" })) { console.log(message.id, message.reason?.description);}Retries
Section titled “Retries”Every POST has an Idempotency-Key, so a retry never sends twice. The client makes one up, or you can pass your own:
await connect.sms.send(request, { idempotencyKey: "order-991-shipped" });Network errors, 5xx and 429 responses are retried twice, waiting for Retry-After when there is one.
Errors
Section titled “Errors”Any other error throws a ConnectApiError:
import { ConnectApiError } from "@divergent.dev/connect";
try { await connect.sms.send(request);} catch (e) { if (e instanceof ConnectApiError) console.log(e.status, e.code, e.detail, e.errors, e.requestId); else throw e;}errors lists validation problems by field. Quote requestId when you contact support.
Next steps
Section titled “Next steps”To receive events, see Node.js webhooks.