Skip to main content
POST
/
sms
/
send
{
  "success": true,
  "message": "<string>",
  "message_id": "<string>",
  "provider": "<string>",
  "status": "<string>"
}

Documentation Index

Fetch the complete documentation index at: https://docs.burki.dev/llms.txt

Use this file to discover all available pages before exploring further.

This endpoint allows you to send SMS messages through one of your AI assistants. The system automatically determines which telephony provider (Twilio, Telnyx, or Vonage) to use based on the assistant configuration associated with the from_phone_number.

How It Works

  1. Assistant Lookup: The system identifies the assistant based on the from_phone_number
  2. Provider Selection: Automatically uses the assistant’s configured telephony provider
  3. Queue or Send: Either queues the message (with rate limiting) or sends immediately
  4. Response: Returns success status with message ID, provider, and delivery status
Multi-Provider Support: Your assistants can use different telephony providers. The system automatically routes SMS messages through the correct provider based on which assistant owns the phone number.

Request Body

ParameterTypeRequiredDescription
from_phone_numberstringYesSender phone number (must be assigned to an assistant)
to_phone_numberstringYesRecipient phone number in E.164 format
messagestringYesSMS message content (max 1600 characters)
media_urlsarrayNoList of media URLs for MMS messages
queuebooleanNoIf true (default), queue with rate limiting. If false, send immediately
idempotency_keystringNoUnique key to prevent duplicate sends on retries (max 256 chars)

Basic Request

{
  "from_phone_number": "+1234567890",
  "to_phone_number": "+1555123456",
  "message": "Hello! This is a follow-up message from your AI assistant."
}

With All Options

{
  "from_phone_number": "+1234567890",
  "to_phone_number": "+1555123456",
  "message": "Hello! This is a follow-up message from your AI assistant.",
  "media_urls": ["https://example.com/image.jpg"],
  "queue": false,
  "idempotency_key": "order:12345:confirmation"
}

Queue vs Immediate Send

When queue: true (default):
  • Messages are queued and sent with rate limiting
  • Helps avoid carrier throttling
  • Better for bulk sends
  • Returns status: "queued"
{
  "queue": true
}

Idempotency

The idempotency_key parameter prevents duplicate messages when retrying failed requests:
{
  "from_phone_number": "+1234567890",
  "to_phone_number": "+1555123456",
  "message": "Your order #12345 has shipped!",
  "idempotency_key": "order:12345:shipped:notification"
}
Header Alternative: You can also provide the idempotency key via the Idempotency-Key header. If both are provided, the header takes precedence.

Response

A successful request returns a 200 OK status with details about the message.
{
  "success": true,
  "message_id": "8ad70ee5-3d47-4fa4-a6ab-c9f2238d5f54",
  "message": "SMS queued successfully via telnyx",
  "provider": "telnyx",
  "status": "queued"
}

Response Fields

FieldTypeDescription
successbooleanWhether the operation was successful
message_idstringUnique identifier for the message
messagestringHuman-readable status message
providerstringTelephony provider used (twilio, telnyx, or vonage)
statusstringDelivery status: queued, sent, or failed
For queued messages, message_id is Burki’s queue UUID. After delivery, use the status endpoint to inspect the provider’s message ID when available.

Error Responses

400 Bad Request

Returned when the request is malformed or contains invalid data.
{
  "detail": "Invalid to_phone_number format. Use E.164 format (e.g., +1234567890)"
}
Common causes:
  • Missing required fields (from_phone_number, to_phone_number, message)
  • Invalid phone number format (must be E.164)
  • Empty message content
  • Message exceeds 1600 characters

403 Forbidden

Returned when the authenticated user does not own the assistant or phone number used as from_phone_number.
{
  "detail": "Unauthorized: phone number belongs to different organization"
}

404 Not Found

Returned when no assistant is found for the specified from_phone_number.
{
  "detail": "No assistant found for phone number +1234567890"
}

500 Internal Server Error

Returned when the telephony provider fails to send the message.
{
  "detail": "Failed to send SMS via telnyx"
}

Use Cases

Customer Service Follow-up

Send follow-up messages after customer service calls:
{
  "from_phone_number": "+1234567890",
  "to_phone_number": "+1555123456",
  "message": "Thanks for calling! Here's the link we discussed: https://support.example.com/article/123",
  "queue": false
}

Appointment Reminders

Send automated appointment reminders with idempotency:
{
  "from_phone_number": "+1234567890",
  "to_phone_number": "+1555123456",
  "message": "Reminder: Your appointment is tomorrow at 2:00 PM. Reply CONFIRM to confirm or RESCHEDULE to change the time.",
  "idempotency_key": "appointment:456:reminder:24h"
}

Bulk Notifications (Queued)

For sending many messages, use the queue to avoid rate limits:
{
  "from_phone_number": "+1234567890",
  "to_phone_number": "+1555123456",
  "message": "Flash sale! 50% off all items today only. Shop now: example.com/sale",
  "queue": true
}

Document Sharing (MMS)

Send documents or images via MMS:
{
  "from_phone_number": "+1234567890",
  "to_phone_number": "+1555123456",
  "message": "Here are the documents you requested:",
  "media_urls": [
    "https://yourdomain.com/documents/contract.pdf",
    "https://yourdomain.com/images/diagram.png"
  ]
}

Authentication

This endpoint requires authentication. Include your API key in the request headers:
curl -X POST "https://api.burki.dev/sms/send" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from_phone_number": "+1234567890",
    "to_phone_number": "+1555123456",
    "message": "Hello from your AI assistant!"
  }'
MethodPathPurpose
GET/sms/{message_id}/statusCheck queued, sent, failed, or cancelled status
DELETE/sms/{message_id}Cancel a queued message before delivery
GET/sms/queue/statsInspect queue statistics by provider

Rate Limits

SMS sending is subject to rate limits imposed by the underlying telephony providers:
  • Twilio: Varies by account type and message volume
  • Telnyx: Varies by account configuration
  • Vonage: Varies by account type
Provider Limits: Each telephony provider has its own rate limits and restrictions. Use the queue: true option (default) to let Burki handle rate limiting automatically.

Best Practices

Phone Number Format

Always use E.164 format for phone numbers:
  • Correct: +1234567890
  • Incorrect: (123) 456-7890, 123-456-7890, 1234567890

Idempotency Keys

Use meaningful idempotency keys that include:
  • The type of message (e.g., order, appointment, alert)
  • A unique identifier (e.g., order ID, appointment ID)
  • The specific action (e.g., confirmation, reminder)
Examples:
  • order:12345:confirmation
  • appointment:789:reminder:24h
  • chat:session123:msg:456:outbound

Message Content

  • Keep messages concise and clear
  • Include clear call-to-action when needed
  • Respect opt-out requests and regulatory requirements
  • Consider character limits for international SMS

Error Handling

Always handle potential errors in your code:
import requests

response = requests.post(
    "https://api.burki.dev/sms/send",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={
        "from_phone_number": "+1234567890",
        "to_phone_number": "+1555123456",
        "message": "Hello from your AI assistant!",
        "idempotency_key": "test:123:hello"
    }
)

if response.status_code == 200:
    data = response.json()
    print(f"SMS {data['status']} via {data['provider']}")
    print(f"Message ID: {data['message_id']}")
else:
    print(f"Error: {response.status_code} - {response.json()['detail']}")

Integration Examples

Node.js

const axios = require('axios');

async function sendSMS(fromPhone, toPhone, message, options = {}) {
  try {
    const response = await axios.post('https://api.burki.dev/sms/send', {
      from_phone_number: fromPhone,
      to_phone_number: toPhone,
      message: message,
      queue: options.queue ?? true,
      idempotency_key: options.idempotencyKey
    }, {
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json'
      }
    });
    
    console.log(`SMS ${response.data.status}:`, response.data);
    return response.data;
  } catch (error) {
    console.error('Failed to send SMS:', error.response.data);
    throw error;
  }
}

// Usage
sendSMS('+1234567890', '+1555123456', 'Hello!', {
  queue: false,
  idempotencyKey: 'test:123'
});

Python

import requests

def send_sms(from_phone, to_phone, message, media_urls=None, queue=True, idempotency_key=None):
    url = "https://api.burki.dev/sms/send"
    headers = {
        "Authorization": "Bearer YOUR_API_KEY",
        "Content-Type": "application/json"
    }
    
    payload = {
        "from_phone_number": from_phone,
        "to_phone_number": to_phone,
        "message": message,
        "queue": queue
    }
    
    if media_urls:
        payload["media_urls"] = media_urls
    
    if idempotency_key:
        payload["idempotency_key"] = idempotency_key
    
    response = requests.post(url, json=payload, headers=headers)
    
    if response.status_code == 200:
        return response.json()
    else:
        raise Exception(f"SMS failed: {response.json()['detail']}")

# Usage
result = send_sms(
    "+1234567890",
    "+1555123456",
    "Your order has shipped!",
    idempotency_key="order:789:shipped"
)
print(f"Status: {result['status']}")

PHP

<?php
function sendSMS($fromPhone, $toPhone, $message, $options = []) {
    $url = 'https://api.burki.dev/sms/send';
    $headers = [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json'
    ];
    
    $data = [
        'from_phone_number' => $fromPhone,
        'to_phone_number' => $toPhone,
        'message' => $message,
        'queue' => $options['queue'] ?? true
    ];
    
    if (isset($options['media_urls'])) {
        $data['media_urls'] = $options['media_urls'];
    }
    
    if (isset($options['idempotency_key'])) {
        $data['idempotency_key'] = $options['idempotency_key'];
    }
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($httpCode === 200) {
        return json_decode($response, true);
    } else {
        throw new Exception("SMS failed: " . $response);
    }
}
?>

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Body

application/json

Request model for sending SMS through an assistant.

from_phone_number
string
required

Sender phone number (must be assigned to an assistant)

to_phone_number
string
required

Recipient phone number in E.164 format (e.g., +1234567890)

message
string
required

SMS message content

Maximum string length: 1600
media_urls
string[] | null

Optional list of media URLs for MMS

queue
boolean
default:true

If True (default), queue the SMS with rate limiting. If False, send immediately.

idempotency_key
string | null

Optional idempotency key (e.g., 'chat:123:msg:456:outbound'). If provided, Burki will dedupe based on this key to prevent duplicate sends/persistence on retries. Can also be provided via Idempotency-Key header (header takes precedence).

Maximum string length: 256

Response

Successful Response

Response model for send SMS endpoint.

success
boolean
required
message
string
required
message_id
string | null
provider
string | null
status
string | null

Message status: 'queued', 'sent', 'failed'