# SMS SDK Reference

Source: https://wraps.dev/docs/sms-sdk-reference

# @wraps.dev/sms SDK

A TypeScript-first SDK for sending SMS through your Wraps-deployed AWS End User Messaging infrastructure. Simple, type-safe, and intuitive API.

## Installation

Copy for AI

npmpnpmyarnbun

npm install @wraps.dev/sms

## Quick Start

Copy for AI

example.ts

```
import { WrapsSMS } from '@wraps.dev/sms';const sms = new WrapsSMS();const result = await sms.send({  to: '+14155551234',  message: 'Your verification code is 123456',});console.log(result.messageId);
```

## Initialization

Copy for AI

Create a new WrapsSMS client. The SDK automatically detects AWS credentials from your environment (OIDC, IAM roles, or environment variables).

Constructor

`new WrapsSMS(config?: WrapsSMSConfig)`

#### Options

-   `region` (optional): AWS region where your infrastructure is deployed. Auto-detected if not provided.
-   `credentials` (optional): AWS credentials object. Auto-detected if not provided.
-   `roleArn` (optional): IAM role ARN for OIDC authentication (Vercel, EKS, GitHub Actions).

Example with Options

config.ts

```
const sms = new WrapsSMS({  region: 'us-west-2',  credentials: {    accessKeyId: process.env.AWS_ACCESS_KEY_ID,    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,  },});
```

OIDC Authentication

oidc-auth.ts

```
// OIDC authentication (Vercel, EKS, GitHub Actions)const sms = new WrapsSMS({  roleArn: process.env.AWS_ROLE_ARN,});
```

## Send SMS

Copy for AI

Send a single SMS message through your Wraps infrastructure.

Method

`sms.send(options: SendOptions): Promise<SendResult>`

### Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `to` | string | Recipient phone number (E.164 format) |
| `message` | string | Message body |
| `messageType` | string | TRANSACTIONAL or PROMOTIONAL (optional) |
| `from` | string | Override sender phone number (optional) |
| `context` | Record<string, string> | Custom metadata (optional) |
| `dryRun` | boolean | Validate without sending (optional) |

### Example

send-sms.ts

```
const result = await sms.send({  to: '+14155551234',           // Required: E.164 format  message: 'Hello!',            // Required: Message body  messageType: 'TRANSACTIONAL', // Optional: TRANSACTIONAL or PROMOTIONAL  from: '+18005551234',         // Optional: Override sender  context: { userId: '123' },   // Optional: Custom metadata  dryRun: true,                 // Optional: Validate without sending});// Resultconsole.log(result.messageId); // 'msg-abc123'console.log(result.status);    // 'QUEUED'console.log(result.segments);  // 1
```

## Send Batch

Copy for AI

Send SMS messages to multiple recipients efficiently.

Method

`sms.sendBatch(options: BatchOptions): Promise<BatchResult>`

### Example

send-batch.ts

```
const result = await sms.sendBatch({  messages: [    { to: '+14155551234', message: 'Your order shipped!' },    { to: '+14155555678', message: 'Your order shipped!' },  ],  messageType: 'TRANSACTIONAL',});// Resultconsole.log(`Sent: ${result.queued}, Failed: ${result.failed}`);// Check individual resultsresult.results.forEach((r) => {  if (r.status === 'QUEUED') {    console.log(`Sent to ${r.to}: ${r.messageId}`);  } else {    console.log(`Failed to send to ${r.to}: ${r.error}`);  }});
```

## Phone Numbers

Copy for AI

List and manage phone numbers in your AWS account.

list-numbers.ts

```
const numbers = await sms.numbers.list();// Resultnumbers.forEach((n) => {  console.log(n.phoneNumber);      // '+18005551234'  console.log(n.numberType);       // 'TOLL_FREE'  console.log(n.messageType);      // 'TRANSACTIONAL'  console.log(n.twoWayEnabled);    // false});
```

## Get Phone Number

Copy for AI

Get details for a specific phone number by ID.

get-number.ts

```
const number = await sms.numbers.get('phone-number-id');// Returnsconsole.log(number.phoneNumberId); // 'phone-number-id'console.log(number.phoneNumber);   // '+18005551234'console.log(number.numberType);    // 'TOLL_FREE'console.log(number.messageType);   // 'TRANSACTIONAL'console.log(number.twoWayEnabled); // false
```

## Opt-Out Management

Copy for AI

Manage opt-out lists for compliance with messaging regulations.

Check Opt-Out Status

check-optout.ts

```
// Check if a number has opted outconst isOptedOut = await sms.optOuts.check('+14155551234');if (isOptedOut) {  console.log('User has opted out');}
```

Manage Opt-Outs

manage-optouts.ts

```
// Add a phone number to the opt-out listawait sms.optOuts.add('+14155551234');// Remove a phone number from the opt-out listawait sms.optOuts.remove('+14155551234');// List all opted-out numbersconst optedOut = await sms.optOuts.list();optedOut.forEach((entry) => {  console.log(`${entry.phoneNumber} opted out at ${entry.optedOutAt}`);});
```

## List Opt-Outs

Copy for AI

List all opted-out phone numbers with pagination support.

list-optouts.ts

```
const result = await sms.optOuts.list({ limit: 20 });result.entries.forEach((entry) => {  console.log(`${entry.phoneNumber} opted out at ${entry.optedOutAt}`);});// Paginateif (result.nextToken) {  const nextPage = await sms.optOuts.list({    limit: 20,    nextToken: result.nextToken,  });}
```

## Error Handling

Copy for AI

The SDK throws typed errors for different failure scenarios.

| Error | Description |
| --- | --- |
| `ValidationError` | Invalid input parameters (includes `field` property) |
| `OptedOutError` | Recipient has opted out (includes `phoneNumber` property) |
| `SMSError` | AWS service error (includes `code`, `retryable` properties) |
| `RateLimitError` | Rate limit exceeded |

error-handling.ts

```
import { WrapsSMS, SMSError, ValidationError, OptedOutError } from '@wraps.dev/sms';try {  await sms.send({ to: '+14155551234', message: 'Hello!' });} catch (error) {  if (error instanceof ValidationError) {    console.log('Invalid input:', error.field);  } else if (error instanceof OptedOutError) {    console.log('User opted out:', error.phoneNumber);  } else if (error instanceof SMSError) {    console.log('AWS error:', error.code, error.message);    if (error.retryable) {      // Safe to retry    }  }}
```

## RateLimitError

Copy for AI

Thrown when AWS rate limits are exceeded. Includes a `retryAfter` property indicating how many seconds to wait before retrying.

rate-limit.ts

```
import { RateLimitError } from '@wraps.dev/sms';try {  await sms.send({ to: '+14155551234', message: 'Hello!' });} catch (error) {  if (error instanceof RateLimitError) {    console.log('Rate limited, retry after:', error.retryAfter, 'seconds');    console.log('Message:', error.message);  }}
```

## Utilities

Copy for AI

Helper functions for common SMS operations.

utilities.ts

```
import { calculateSegments, validatePhoneNumber } from '@wraps.dev/sms';// Calculate SMS segmentscalculateSegments('Hello!');           // 1calculateSegments('a'.repeat(200));    // 2calculateSegments('Hello emojis!');    // 1 (Unicode)// Validate phone numbersvalidatePhoneNumber('+14155551234', 'to'); // OKvalidatePhoneNumber('4155551234', 'to');   // Throws ValidationError
```

## sanitizePhoneNumber

Copy for AI

Utility function to sanitize phone numbers into E.164 format by removing formatting characters.

sanitize.ts

```
import { sanitizePhoneNumber } from '@wraps.dev/sms';sanitizePhoneNumber('(415) 555-1234');  // '+14155551234'sanitizePhoneNumber('+1-415-555-1234'); // '+14155551234'
```

## Destroy Infrastructure

Copy for AI

Remove all SMS infrastructure including phone numbers and opt-out lists. This action is irreversible.

destroy.ts

```
// Remove all SMS infrastructure (phone numbers, opt-out lists)await sms.destroy();
```

## Message Types

Copy for AI

| Type | Use Case | Best Practices |
| --- | --- | --- |
| `TRANSACTIONAL` | OTP, alerts, notifications | Time-sensitive, user-initiated |
| `PROMOTIONAL` | Marketing, promotions | Requires explicit consent |

## TypeScript Support

Copy for AI

The SDK is written in TypeScript and provides full type safety out of the box.

typed-usage.ts

```
import { WrapsSMS, SendOptions, SendResult } from '@wraps.dev/sms';const sms = new WrapsSMS();// TypeScript will validate all parametersconst options: SendOptions = {  to: '+14155551234',  message: 'Hello!',  messageType: 'TRANSACTIONAL',};const result: SendResult = await sms.send(options);
```

## Pricing

Copy for AI

AWS End User Messaging charges per message segment:

| Component | Cost (US) |
| --- | --- |
| Toll-free number | $2/month |
| Outbound SMS | ~$0.00849/segment |
| Carrier fees | ~$0.003-0.006/segment |

## Behavior Notes

Sequential Batch Processing

Batch sends are processed sequentially (not in parallel) to respect AWS rate limits. Each message is sent one at a time.

Default Message Type: TRANSACTIONAL

The default `messageType` is `TRANSACTIONAL`. Set to `PROMOTIONAL` for marketing messages.

## Next Steps

View on npm

Check out the package on npm for the latest version and changelog.

[View Package](https://www.npmjs.com/package/@wraps.dev/sms)

View on GitHub

Explore the source code, report issues, or contribute.

[View Source](https://github.com/wraps-team/wraps-js)
