Skip to content
SMS SDK
Esc
↑↓navigate↵open⌘Jpreview
On this page

Overview

SMS SDK sends and receives transactional SMS through Twilio, Telnyx, Plivo, or Vonage with one typed TypeScript API.

SMS SDK (@opencoredev/sms-sdk) sends transactional SMS through Twilio, Telnyx, Plivo, or Vonage with one TypeScript API, and turns their delivery and inbound webhooks into one event shape.

What it solves

Each provider has its own request format, error codes, status names, and webhook signatures. Code written for one is hard to move, and the failure cases are easy to get wrong:

  • A timeout does not tell you whether the provider created the message. Retrying it, or failing over to a second provider, can text the recipient twice.
  • A 201 means the provider queued the message. Delivery is reported later, by webhook.
  • A provider that cannot schedule or send MMS may ignore the field or fail in its own way.
  • Each provider signs callbacks differently, and a proxy in front of your app often breaks verification.

With SMS SDK, a send either resolves with an accepted result or throws a typed error that says whether a retry is safe. Unsupported fields throw before any request. Webhooks are verified before any field is read.

The core idea

import { createSmsClient, HandoffUnknownError } from "@opencoredev/sms-sdk";
import { telnyx } from "@opencoredev/sms-sdk/telnyx";

const sms = createSmsClient({
  adapters: [telnyx({ apiKey: process.env.TELNYX_API_KEY ?? "", from: "+15550100001" })],
});

try {
  const result = await sms.send({
    to: "+14155550123",
    body: "Your order has shipped.",
    idempotencyKey: "order:123:shipped:v1",
  });
  console.log(result.providerId, result.delivery); // the provider's message ID, "queued"
} catch (error) {
  if (error instanceof HandoffUnknownError) {
    // The provider may have accepted it. Check before sending again.
  }
  throw error;
}

Replace telnyx(...) with twilio(...), plivo(...), or vonage(...) to change provider. The send() call stays the same. Runnable versions are in the examples.

Packages

One npm package, no runtime or peer dependencies. Each part is a subpath import, and importing one adapter never loads another.

Import What it gives you
@opencoredev/sms-sdk createSmsClient, error classes, types, isE164, estimateSegments, memoryIdempotencyStore
@opencoredev/sms-sdk/twilio The twilio() adapter
@opencoredev/sms-sdk/telnyx The telnyx() adapter
@opencoredev/sms-sdk/plivo The plivo() adapter
@opencoredev/sms-sdk/vonage The vonage() adapter (Vonage Messages API)
@opencoredev/sms-sdk/webhooks parseSmsWebhook() and per-provider verify helpers
@opencoredev/sms-sdk/testing The memory() adapter, mockFetch(), signed webhook builders, the adapter contract harness
@opencoredev/sms-sdk/encoding estimateSegments, isGsm7, GSM-7 tables, SEGMENT_LIMITS

The sms-sdk doctor command checks your configuration without sending. See Doctor CLI.

Providers

  • Twilio: Programmable Messaging, API version 2010-04-01. Supported.
  • Telnyx: Messaging API v2. Supported.
  • Plivo: Message API. Partial: most rejections cannot be classified.
  • Vonage: Messages API v1, SMS channel. Partial: error classification is inferred, no short codes or MMS.

Providers overview compares them.

Scope and limits

SMS SDK is a transport library. It does not include:

  • Conversation threads, an inbox, chatbots, WhatsApp, RCS, or iMessage.
  • An OTP verification service, a hosted API, a dashboard, or number purchasing.
  • 10DLC, toll-free, or sender ID registration. You do that with each provider. See Sender registration and consent.
  • Exactly-once delivery. None of the four providers offer send idempotency, so no SMS library can promise it. SMS SDK reports an unknown outcome instead of guessing. See Idempotency.

It runs on the server only, on Node.js 20+ or Bun 1.1+. See Installation.

Next steps