API Reference

Complete API reference for SMS endpoints.

Authentication

All SMS API endpoints require authentication via API key:

Authorization: Bearer YOUR_API_KEY

Or use the X-API-Key header:

X-API-Key: YOUR_API_KEY

Both SENDING and SERVER API key types can access SMS endpoints.

Base URL

https://api.usetransactional.com/v1

Send SMS

Send a single SMS message using a pool template.

Request

POST /sms

Body Parameters

ParameterTypeRequiredDescription
tostringYesRecipient phone number in E.164 format
templateAliasstringConditionalPool template alias or custom alias
templateIdnumberConditionalPool template ID
templateModelobjectNoVariables for template substitution
tagstringNoTag for filtering (max 255 chars)
metadataobjectNoCustom key-value metadata

Note: Either templateAlias or templateId is required.

Example Request

curl -X POST https://api.usetransactional.com/v1/sms \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155551234",
    "templateAlias": "otp-verification",
    "templateModel": {
      "code": "123456"
    },
    "tag": "verification",
    "metadata": {
      "userId": "user_123"
    }
  }'

Response

{
  "to": "+14155551234",
  "submittedAt": "2024-01-01T00:00:00.000Z",
  "messageId": "sms_abc123",
  "errorCode": 0,
  "message": "OK"
}

Error Codes

CodeDescription
0Success
1001Invalid phone number format
1002Template not found
1003Template not approved for organization
1004No pool number available for country
1005SMS not enabled for organization
1006Recipient opted out (suppressed)

Send Batch SMS

Send up to 500 SMS messages in a single request.

Request

POST /sms/batch

Body

Array of message objects (same structure as single send):

[
  {
    "to": "+14155551234",
    "templateAlias": "otp-verification",
    "templateModel": { "code": "123456" }
  },
  {
    "to": "+14155555678",
    "templateAlias": "otp-verification",
    "templateModel": { "code": "789012" }
  }
]

Example Request

curl -X POST https://api.usetransactional.com/v1/sms/batch \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "to": "+14155551234",
      "templateAlias": "otp-verification",
      "templateModel": { "code": "123456" }
    },
    {
      "to": "+14155555678",
      "templateAlias": "otp-verification",
      "templateModel": { "code": "789012" }
    }
  ]'

Response

[
  {
    "to": "+14155551234",
    "submittedAt": "2024-01-01T00:00:00.000Z",
    "messageId": "sms_abc123",
    "errorCode": 0,
    "message": "OK"
  },
  {
    "to": "+14155555678",
    "submittedAt": "2024-01-01T00:00:00.000Z",
    "messageId": "sms_def456",
    "errorCode": 0,
    "message": "OK"
  }
]

Get SMS Message

Retrieve details and status of a specific SMS message.

Request

GET /sms/{messageId}

Path Parameters

ParameterTypeDescription
messageIdstringThe message ID

Example Request

curl https://api.usetransactional.com/v1/sms/sms_abc123 \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

{
  "messageId": "sms_abc123",
  "providerMessageId": "SM12345",
  "from": "+18005551234",
  "to": "+14155551234",
  "body": "Your verification code is 123456",
  "status": "DELIVERED",
  "direction": "OUTBOUND",
  "segments": 1,
  "country": "US",
  "tag": "verification",
  "metadata": {
    "userId": "user_123"
  },
  "errorCode": null,
  "errorMessage": null,
  "queuedAt": "2024-01-01T00:00:00.000Z",
  "sentAt": "2024-01-01T00:00:01.000Z",
  "deliveredAt": "2024-01-01T00:00:02.000Z",
  "failedAt": null,
  "events": [
    {
      "eventType": "QUEUED",
      "timestamp": "2024-01-01T00:00:00.000Z"
    },
    {
      "eventType": "SENT",
      "timestamp": "2024-01-01T00:00:01.000Z"
    },
    {
      "eventType": "DELIVERED",
      "timestamp": "2024-01-01T00:00:02.000Z"
    }
  ]
}

Message Statuses

StatusDescription
QUEUEDMessage accepted, waiting to send
SENDINGMessage being sent to carrier
SENTMessage sent to carrier
DELIVEREDMessage delivered to recipient
FAILEDDelivery failed
UNDELIVEREDCarrier unable to deliver
BLOCKEDBlocked (e.g., suppressed)

List SMS Messages

List SMS messages with optional filters.

Request

GET /sms/messages

Query Parameters

ParameterTypeDefaultDescription
countnumber100Number to return (max 500)
offsetnumber0Pagination offset
statusstring-Filter by status
directionstring-OUTBOUND or INBOUND
tagstring-Filter by tag
fromDatestring-ISO 8601 start date
toDatestring-ISO 8601 end date

Example Request

curl "https://api.usetransactional.com/v1/sms/messages?count=50&status=DELIVERED&tag=verification" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

{
  "totalCount": 50,
  "messages": [
    {
      "messageId": "sms_abc123",
      "from": "+18005551234",
      "to": "+14155551234",
      "status": "DELIVERED",
      "direction": "OUTBOUND",
      "segments": 1,
      "country": "US",
      "tag": "verification",
      "queuedAt": "2024-01-01T00:00:00.000Z",
      "sentAt": "2024-01-01T00:00:01.000Z",
      "deliveredAt": "2024-01-01T00:00:02.000Z",
      "failedAt": null
    }
  ]
}

List Inbound Messages

List incoming SMS messages.

Request

GET /sms/inbound

Query Parameters

ParameterTypeDefaultDescription
countnumber100Number to return (max 500)
offsetnumber0Pagination offset
fromNumberstring-Filter by sender number
toNumberstring-Filter by receiving number
fromDatestring-ISO 8601 start date
toDatestring-ISO 8601 end date

Example Request

curl "https://api.usetransactional.com/v1/sms/inbound?count=50" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

{
  "totalCount": 50,
  "messages": [
    {
      "messageId": "sms_inb_abc123",
      "providerMessageId": "SM12345",
      "from": "+14155551234",
      "to": "+18005551234",
      "body": "Thanks for the update!",
      "receivedAt": "2024-01-01T12:30:00.000Z"
    }
  ]
}

SDK Reference

TypeScript SDK

Installation

npm install transactional-sdk

Initialization

import { Transactional } from 'transactional-sdk';
 
const client = new Transactional({
  apiKey: process.env.TRANSACTIONAL_API_KEY,
});

Python SDK

Installation

pip install transactional

Initialization

from transactional import Transactional
import os
 
client = Transactional(api_key=os.environ["TRANSACTIONAL_API_KEY"])

SMS Methods (TypeScript)

// Send single SMS
const result = await client.sms.send({
  to: '+14155551234',
  templateAlias: 'otp-verification',
  templateModel: { code: '123456' },
});
 
// Send batch SMS
const results = await client.sms.sendBatch([
  { to: '+14155551234', templateAlias: 'otp', templateModel: { code: '111' } },
  { to: '+14155555678', templateAlias: 'otp', templateModel: { code: '222' } },
]);
 
// Get message details
const message = await client.sms.get('sms_abc123');
 
// List messages
const messages = await client.sms.list({
  count: 50,
  status: 'DELIVERED',
  tag: 'verification',
});
 
// List inbound messages
const inbound = await client.sms.listInbound({
  count: 50,
  fromDate: '2024-01-01T00:00:00Z',
});

SMS Methods (Python)

# Send single SMS
result = client.sms.send(
    to="+14155551234",
    template_alias="otp-verification",
    template_model={"code": "123456"},
)
 
# Send batch SMS
results = client.sms.send_batch([
    {"to": "+14155551234", "template_alias": "otp", "template_model": {"code": "111"}},
    {"to": "+14155555678", "template_alias": "otp", "template_model": {"code": "222"}},
])
 
# Get message details
message = client.sms.get("sms_abc123")
 
# List messages
messages = client.sms.list(
    count=50,
    status="DELIVERED",
    tag="verification",
)
 
# List inbound messages
inbound = client.sms.list_inbound(
    count=50,
    from_date="2024-01-01T00:00:00Z",
)

Suppressions Methods (TypeScript)

// List suppressions
const suppressions = await client.sms.suppressions.list();
 
// Check if suppressed
const isSuppressed = await client.sms.suppressions.check('+14155551234');
 
// Add suppression
await client.sms.suppressions.add({
  phoneNumber: '+14155551234',
  reason: 'MANUAL',
});
 
// Remove suppression
await client.sms.suppressions.remove('+14155551234');

Suppressions Methods (Python)

# List suppressions
suppressions = client.sms.suppressions.list()
 
# Check if suppressed
result = client.sms.suppressions.check("+14155551234")
if result.suppressed:
    print(f"Number is suppressed: {result.reason}")
 
# Add suppression
client.sms.suppressions.add(
    phone_number="+14155551234",
    reason="MANUAL",
)
 
# Remove suppression
client.sms.suppressions.remove("+14155551234")

Webhooks Methods (TypeScript)

// List webhooks
const webhooks = await client.sms.webhooks.list();
 
// Create webhook
const webhook = await client.sms.webhooks.create({
  url: 'https://your-app.com/webhooks/sms',
  events: ['sms.delivered', 'sms.failed'],
});
 
// Update webhook
await client.sms.webhooks.update(webhookId, {
  events: ['sms.delivered', 'sms.failed', 'sms.inbound'],
});
 
// Delete webhook
await client.sms.webhooks.delete(webhookId);

Webhooks Methods (Python)

# List webhooks
webhooks = client.sms.webhooks.list()
 
# Create webhook
webhook = client.sms.webhooks.create(
    url="https://your-app.com/webhooks/sms",
    events=["sms.delivered", "sms.failed"],
)
 
# Update webhook
client.sms.webhooks.update(
    webhook_id,
    events=["sms.delivered", "sms.failed", "sms.inbound"],
)
 
# Delete webhook
client.sms.webhooks.delete(webhook_id)

Rate Limits

EndpointLimit
POST /sms100 requests/second
POST /sms/batch10 requests/second
GET /sms/*100 requests/second

Rate limit headers are included in responses:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 99
X-RateLimit-Reset: 1704067200

Error Responses

All errors follow this format:

{
  "error": {
    "code": "SMS_NOT_ENABLED",
    "message": "SMS is not enabled for this organization",
    "statusCode": 403
  }
}

Common Error Codes

HTTP StatusError CodeDescription
400INVALID_REQUESTInvalid request body or parameters
401UNAUTHORIZEDInvalid or missing API key
403SMS_NOT_ENABLEDSMS not enabled for organization
404MESSAGE_NOT_FOUNDMessage ID not found
404TEMPLATE_NOT_FOUNDTemplate not found
429RATE_LIMITEDToo many requests
500INTERNAL_ERRORServer error