Wraps Logo
DocsHome
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

npm install @wraps.dev/sms

Quick Start

TypeScriptexample.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

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

TypeScriptconfig.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

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

Send SMS

Send a single SMS message through your Wraps infrastructure.

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

Parameters

ParameterTypeDescription
tostringRecipient phone number (E.164 format)
messagestringMessage body
messageTypestringTRANSACTIONAL or PROMOTIONAL (optional)
fromstringOverride sender phone number (optional)
contextRecord<string, string>Custom metadata (optional)
dryRunbooleanValidate without sending (optional)

Example

TypeScriptsend-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

Send SMS messages to multiple recipients efficiently.

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

Example

TypeScriptsend-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

List and manage phone numbers in your AWS account.

TypeScriptlist-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

Get details for a specific phone number by ID.

TypeScriptget-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

Manage opt-out lists for compliance with messaging regulations.

Check Opt-Out Status

TypeScriptcheck-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

TypeScriptmanage-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

List all opted-out phone numbers with pagination support.

TypeScriptlist-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

The SDK throws typed errors for different failure scenarios.

ErrorDescription
ValidationErrorInvalid input parameters (includes field property)
OptedOutErrorRecipient has opted out (includes phoneNumber property)
SMSErrorAWS service error (includes code, retryable properties)
RateLimitErrorRate limit exceeded
TypeScripterror-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

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

TypeScriptrate-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

Helper functions for common SMS operations.

TypeScriptutilities.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

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

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

Destroy Infrastructure

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

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

Message Types

TypeUse CaseBest Practices
TRANSACTIONALOTP, alerts, notificationsTime-sensitive, user-initiated
PROMOTIONALMarketing, promotionsRequires explicit consent

TypeScript Support

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

TypeScripttyped-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

AWS End User Messaging charges per message segment:

ComponentCost (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
View on GitHub

Explore the source code, report issues, or contribute.

View Source