---
title: "Quick start"
description: "Send your first SMS through Twilio with SMS SDK in three steps."
---

By the end of this page, a server-side script sends one SMS through Twilio and prints the provider's message ID.

- Using Telnyx, Plivo, or Vonage? Swap in the adapter from its [provider page](/providers/overview).
- No provider account yet? Use the [`memory()` adapter](/guides/local-testing).

You need a Twilio Account SID, Auth Token, and a Twilio number that can text your destination. Registering that number for 10DLC or toll-free is up to you. See [Sender registration and consent](/guides/sender-registration-and-consent).

## 1. Install

```package-install
npm install @opencoredev/sms-sdk
```

## 2. Create the client

Set three environment variables on your server. Never send them to a browser.

```bash .env
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=your_auth_token
TWILIO_FROM=+15550100001
```

Create the client in its own module so the rest of your app imports one instance:

```ts sms.ts
import { createSmsClient, isE164 } from "@opencoredev/sms-sdk";
import { twilio } from "@opencoredev/sms-sdk/twilio";

const from = process.env.TWILIO_FROM;
if (!isE164(from)) {
  throw new Error("Set TWILIO_FROM to your Twilio number in E.164 format, such as +15550100001.");
}

export const sms = createSmsClient({
  adapters: [
    twilio({
      accountSid: process.env.TWILIO_ACCOUNT_SID ?? "",
      authToken: process.env.TWILIO_AUTH_TOKEN ?? "",
      from,
    }),
  ],
});
```

Creating the client makes no network request. A malformed Account SID or empty Auth Token makes `twilio()` throw a `ConfigurationError` at startup, not on the first send.

## 3. Send a message

```ts send.ts
import { isSmsError } from "@opencoredev/sms-sdk";
import { sms } from "./sms";

try {
  const result = await sms.send({
    to: "+14155550123", // replace with your own phone number
    body: "Hello from SMS SDK.",
    idempotencyKey: "quick-start:1",
  });
  console.log(`Accepted by ${result.provider}: ${result.providerId} (${result.delivery})`);
} catch (error) {
  if (isSmsError(error)) {
    console.error(error.code, error.message, `retrySafe: ${error.retrySafe}`);
  }
  throw error;
}
```

Run it with `npx tsx --env-file=.env send.ts` on Node.js or `bun send.ts` on Bun, which loads `.env` itself. It prints a line like `Accepted by twilio: SM… (queued)`, and the text reaches your phone shortly after.

`queued` means Twilio accepted the message, not that the phone got it. Delivery is reported later by [webhook](/receiving/delivery-status-webhooks).

If the send fails, read the error's `code` and `retrySafe`. `provider_auth` means Twilio rejected the credentials. `handoff_unknown` means SMS SDK cannot tell whether Twilio accepted the message, so check the Twilio console before you resend. [Errors](/reference/errors) lists every code.

## Next steps

- [Important defaults](/getting-started/important-defaults): what the client does without extra options.
- [Delivery status webhooks](/receiving/delivery-status-webhooks): learn when the message is delivered.
- [Retries and fallback](/sending/retries-and-fallback): add a second provider safely.
