API Reference

SMS Development API

Complete API reference for integrating with sms-dev local development environment.

Overview

The sms-dev API provides both Relay-compatible endpoints for seamless integration and simulator-specific endpoints for development features.

Relay-Compatible Endpoints

These endpoints match the production Relay API exactly, allowing you to switch between development and production seamlessly.

  • • Same request/response format
  • • Compatible with Relay SDKs
  • • Easy production migration

Simulator-Only Endpoints

These endpoints are specific to sms-dev and provide development-focused features not available in production.

  • • Webhook configuration
  • • Message simulation
  • • Development status

Base URL

Development Environment

http://localhost:4001

By default, sms-dev runs on port 4001. You can customize this with the --api-port flag.

SDK Configuration

JavaScript/TypeScript:

import { Relay } from '@relay/sdk'

const relay = new Relay({
  baseUrl: 'http://localhost:4001'  // Point to sms-dev
})

Python:

from relay import Relay

relay = Relay(base_url='http://localhost:4001')

Authentication

No Authentication Required

sms-dev does not require API keys or authentication. This simplifies development but should never be used in production.

Example Request

curl -X POST http://localhost:4001/v1/messages \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+1234567890",
    "body": "Hello from sms-dev!"
  }'

Relay-Compatible Endpoints

These endpoints are fully compatible with the production Relay API and can be used with existing SDKs and code.

Send Message

Relay-Compatible
POST/v1/messages

Send an SMS message. In sms-dev, messages are simulated and appear instantly in the Virtual Phone UI.

Request Body

{
  "to": "+1234567890",           // Required: Recipient phone number
  "from": "+1987654321",         // Optional: Sender number  
  "body": "Hello world!"         // Required: Message content
}

Response

{
  "id": "sim_msg_abc123",
  "to": "+1234567890",
  "from": "+1987654321", 
  "body": "Hello world!",
  "status": "queued",
  "created_at": "2024-01-15T10:30:00Z",
  "delivered_at": null
}

Example

// Using fetch
const response = await fetch('http://localhost:4001/v1/messages', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    to: '+1234567890',
    body: 'Hello from my app!'
  })
})

const message = await response.json()
console.log('Message ID:', message.id)

Get Message

Relay-Compatible
GET/v1/messages/:id

Retrieve details of a specific message by its ID.

Response

{
  "id": "sim_msg_abc123",
  "to": "+1234567890",
  "from": "+1987654321",
  "body": "Hello world!",
  "status": "delivered",
  "created_at": "2024-01-15T10:30:00Z",
  "delivered_at": "2024-01-15T10:30:01Z"
}

Example

const response = await fetch('http://localhost:4001/v1/messages/sim_msg_abc123')
const message = await response.json()
console.log('Status:', message.status)

List Messages

Relay-Compatible
GET/v1/messages

Retrieve a paginated list of messages with optional filtering.

Query Parameters

ParameterTypeDescription
limitnumberNumber of messages to return (default: 20)
offsetnumberNumber of messages to skip (default: 0)
phonestringFilter by phone number (to or from)
statusstringFilter by message status

Response

{
  "messages": [
    {
      "id": "sim_msg_abc123",
      "to": "+1234567890",
      "from": "+1987654321",
      "body": "Hello world!",
      "status": "delivered",
      "created_at": "2024-01-15T10:30:00Z",
      "delivered_at": "2024-01-15T10:30:01Z"
    }
  ],
  "total": 1,
  "limit": 20,
  "offset": 0
}

Example

const response = await fetch('http://localhost:4001/v1/messages?limit=10&phone=1234567890')
const data = await response.json()
console.log(`Found ${data.total} messages`)

Simulator-Only Endpoints

These endpoints are specific to sms-dev and provide development features not available in production.

Development Status

Simulator-Only
GET/v1/dev/status

Get the current status of the sms-dev environment, including server information and statistics.

Development Only

This endpoint is not available in production Relay API and should only be used for development debugging.

Response

{
  "service": "sms-dev-api",
  "version": "1.0.0",
  "status": "running",
  "uptime": 3600,
  "stats": {
    "total_messages": 42,
    "total_conversations": 8,
    "webhook_deliveries": 15
  },
  "config": {
    "api_port": 4001,
    "ui_port": 4000,
    "webhook_url": "http://localhost:3000/webhook"
  }
}

Example

const response = await fetch('http://localhost:4001/v1/dev/status')
const status = await response.json()
console.log(`sms-dev has been running for ${status.uptime} seconds`)

Webhook Configuration

Simulator-Only
POST/v1/webhooks/configure

Configure the webhook URL for receiving inbound message notifications.

Request Body

{
  "url": "http://localhost:3000/webhook/sms"
}

Example

await fetch('http://localhost:4001/v1/webhooks/configure', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    url: 'http://localhost:3000/webhook/sms'
  })
})
GET/v1/webhooks/config

Get the current webhook configuration.

Response

{
  "url": "http://localhost:3000/webhook/sms",
  "configured_at": "2024-01-15T10:30:00Z"
}

Simulate Inbound Message

Simulator-Only
POST/v1/webhooks/simulate-inbound

Simulate an inbound SMS message that will be sent to your configured webhook URL.

Testing Feature

This endpoint simulates receiving an SMS reply from a user and forwards it to your webhook for testing conversation flows.

Request Body

{
  "from": "+1234567890",        // User's phone number
  "to": "+1987654321",          // Your app's number
  "body": "Yes, I'm interested" // User's reply message
}

Webhook Payload

Your webhook will receive this payload:

{
  "id": "sim_inbound_xyz789",
  "from": "+1234567890",
  "to": "+1987654321", 
  "body": "Yes, I'm interested",
  "received_at": "2024-01-15T10:35:00Z",
  "type": "inbound"
}

Example

// Simulate a user replying "YES" to an opt-in request
await fetch('http://localhost:4001/v1/webhooks/simulate-inbound', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    from: '+1234567890',
    to: '+1987654321',
    body: 'YES'
  })
})

Data Models

Message Object

FieldTypeRequiredDescription
idstringYesUnique message identifier
tostringYesRecipient phone number
fromstringOptionalSender phone number
bodystringYesMessage content
statusstringYesqueued, sent, delivered, failed
created_atstringYesISO 8601 timestamp
delivered_atstringOptionalISO 8601 timestamp when delivered

Error Object

All API errors return a consistent error format:

{
  "error": {
    "type": "validation_error",
    "message": "Missing required field: to",
    "details": {
      "field": "to",
      "code": "required"
    }
  }
}

Common Error Types

validation_errorInvalid request data
not_foundResource not found
internal_errorServer error

Next Steps

SDK Integration

Learn how to integrate sms-dev with popular frameworks and libraries.

View Examples →

CLI Reference

Learn about all available CLI commands and configuration options.

CLI Guide →