DIDfarm
  • Numbers
  • Trunks
  • Messaging
  • Connect
  • Pricing
  • Coverage
  • Help
🇬🇧 EN 🇳🇱 NL 🇩🇪 DE 🇫🇷 FR 🇪🇸 ES 🇧🇷 PT 🇸🇦 AR 🇨🇳 ZH 🇯🇵 JA 🇮🇳 HI
Sign in Get a Number
← Help Center
On this page
Authentication Base URL Send SMS List Messages Get Message List Numbers Delivery Webhooks Error Handling Rate Limits Code Examples

SMS API Reference

Developer Docs · 12 min read REST API SMS Bearer Auth
Quick start: Create an API key in your portal, then send your first SMS with a single API call. Messages are charged per-segment from your wallet balance. Inbound SMS is free.

Authentication

All API requests require a Bearer token in the Authorization header. Create an API key from the API Keys page in your portal.

AUTHORIZATION HEADER
Authorization: Bearer YOUR_API_KEY
Keep your API key secret. Do not expose it in client-side code, public repositories, or URLs. If compromised, revoke it immediately from the portal and create a new one.

Base URL

https://didfarm.com/api/v1/sms

Send SMS

POST /messages

Send an outbound SMS message from one of your SMS-enabled numbers.

Request body

ParameterTypeRequiredDescription
fromstringYes*Your SMS-enabled number in E.164 format (e.g. +16625163513)
from_number_idintegerYes*Alternatively, the numeric ID of your number (from GET /numbers)
tostringYesDestination number in E.164 format (e.g. +31612345678)
bodystringYesMessage text, max 1,600 characters
status_callback_urlstringNoURL to receive delivery status webhooks

* Provide either from or from_number_id, not both.

CURL
curl -X POST https://didfarm.com/api/v1/sms/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "+16625163513",
    "to": "+31612345678",
    "body": "Your order #1234 has shipped!"
  }'
RESPONSE (201 CREATED)
{
  "data": {
    "id": 42,
    "from": "+16625163513",
    "to": "+31612345678",
    "body": "Your order #1234 has shipped!",
    "direction": "outbound",
    "status": "queued",
    "segments": 1,
    "cost": 0.008,
    "currency": "EUR",
    "carrier": "didfarm",
    "created_at": "2026-04-03T10:15:30+00:00"
  }
}

List Messages

GET /messages

Retrieve your SMS messages with optional filtering and pagination.

Query parameters

ParameterTypeDescription
directionstringFilter by inbound or outbound
statusstringFilter by status: queued, sent, delivered, failed
number_idintegerFilter by DID number ID
fromstringFilter by sender number
tostringFilter by destination number
sincedatetimeOnly messages after this timestamp (ISO 8601)
pageintegerPage number (default: 1)
per_pageintegerResults per page (default: 25, max: 100)
CURL
curl https://didfarm.com/api/v1/sms/messages?direction=outbound&per_page=10 \
  -H "Authorization: Bearer YOUR_API_KEY"
RESPONSE
{
  "data": [
    {
      "id": 42,
      "from": "+16625163513",
      "to": "+31612345678",
      "body": "Your order #1234 has shipped!",
      "direction": "outbound",
      "status": "delivered",
      "segments": 1,
      "cost": 0.008,
      "currency": "EUR",
      "carrier": "didfarm",
      "created_at": "2026-04-03T10:15:30+00:00"
    }
  ],
  "meta": {
    "total": 156,
    "page": 1,
    "per_page": 10,
    "total_pages": 16
  }
}

Get Message

GET /messages/{'{id}'}

Retrieve a single message by ID, including delivery status and cost.

CURL
curl https://didfarm.com/api/v1/sms/messages/42 \
  -H "Authorization: Bearer YOUR_API_KEY"

List SMS Numbers

GET /numbers

List your active numbers that have SMS enabled. Use the id field as from_number_id when sending.

CURL
curl https://didfarm.com/api/v1/sms/numbers \
  -H "Authorization: Bearer YOUR_API_KEY"
RESPONSE
{
  "data": [
    { "id": 11, "number": "+16625163513", "country_code": "US", "number_type": "local", "sms_enabled": true },
    { "id": 6, "number": "+16315950406", "country_code": "US", "number_type": "local", "sms_enabled": true }
  ]
}

Delivery Status Webhooks

Receive real-time delivery updates by providing a status_callback_url when sending a message.

SEND WITH CALLBACK
curl -X POST https://didfarm.com/api/v1/sms/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "+16625163513",
    "to": "+31612345678",
    "body": "Hello!",
    "status_callback_url": "https://yourapp.com/webhooks/sms"
  }'

DIDfarm will POST to your URL when the message status changes:

WEBHOOK PAYLOAD
{
  "event": "sms.status_updated",
  "data": {
    "id": 42,
    "from": "+16625163513",
    "to": "+31612345678",
    "direction": "outbound",
    "status": "delivered",
    "segments": 1,
    "cost": 0.008,
    "currency": "EUR",
    "created_at": "2026-04-03T10:15:30+00:00",
    "updated_at": "2026-04-03T10:15:33+00:00"
  },
  "timestamp": "2026-04-03T10:15:33+00:00"
}

Verifying webhook signatures

Each webhook includes an X-DIDFarm-Signature header containing an HMAC-SHA256 signature of the JSON payload, signed with your application key.

VERIFY SIGNATURE (NODE.JS)
const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Error Handling

All errors return a JSON object with an error key:

{
  "error": {
    "code": "insufficient_balance",
    "message": "Wallet balance too low to send this message"
  }
}
HTTP StatusError CodeDescription
401unauthenticatedMissing or invalid API key
404not_foundMessage or number not found
422number_not_foundFrom number not found, inactive, or SMS not enabled
422validation_errorMissing or invalid request parameters
429rate_limitedToo many requests (see Rate Limits)
500send_failedCarrier rejected the message

Rate Limits

LimitValue
Requests per minute60
Messages per second10 (carrier limit)

Rate limit headers are included in every response:

  • X-RateLimit-Limit — maximum requests allowed
  • X-RateLimit-Remaining — requests remaining in window
  • Retry-After — seconds to wait (only on 429 responses)

Code Examples

Node.js

SEND SMS WITH NODE.JS (FETCH)
const API_KEY = 'your_api_key_here';

async function sendSms(from, to, body) {
  const res = await fetch('https://didfarm.com/api/v1/sms/messages', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ from, to, body }),
  });

  const data = await res.json();
  if (!res.ok) throw new Error(data.error?.message || 'Send failed');
  return data.data;
}

// Usage
const msg = await sendSms('+16625163513', '+31612345678', 'Hello!');
console.log(`Sent! ID: ${msg.id}, Status: ${msg.status}`);

Python

SEND SMS WITH PYTHON (REQUESTS)
import requests

API_KEY = 'your_api_key_here'
BASE_URL = 'https://didfarm.com/api/v1/sms'

def send_sms(from_number, to, body):
    resp = requests.post(
        f'{BASE_URL}/messages',
        headers={
            'Authorization': f'Bearer {API_KEY}',
            'Content-Type': 'application/json',
        },
        json={'from': from_number, 'to': to, 'body': body},
    )
    resp.raise_for_status()
    return resp.json()['data']

# Usage
msg = send_sms('+16625163513', '+31612345678', 'Hello from Python!')
print(f"Sent! ID: {msg['id']}, Status: {msg['status']}")

PHP

SEND SMS WITH PHP (CURL)
$apiKey = 'your_api_key_here';

$ch = curl_init('https://didfarm.com/api/v1/sms/messages');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer {$apiKey}",
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'from' => '+16625163513',
        'to'   => '+31612345678',
        'body' => 'Hello from PHP!',
    ]),
]);

$response = curl_exec($ch);
$data = json_decode($response, true);
echo "Sent! ID: {$data['data']['id']}\n";

Webhook receiver (Node.js / Express)

RECEIVE DELIVERY WEBHOOKS
const express = require('express');
const app = express();
app.use(express.json());

app.post('/webhooks/sms', (req, res) => {
  const { event, data } = req.body;

  if (event === 'sms.status_updated') {
    console.log(`Message ${data.id}: ${data.status}`);

    if (data.status === 'delivered') {
      // Message confirmed delivered
    } else if (data.status === 'failed') {
      // Handle delivery failure
    }
  }

  res.sendStatus(200);
});

app.listen(3000);

Ready to integrate?

Create an API key and send your first SMS in under a minute.

Get API key →
© 2026 DIDfarm · didfarm.com
About Blog Partners Coverage API Docs Status Privacy Terms Cookies Help

We use essential cookies to make DIDfarm work. With your consent, we also use analytics cookies to improve our service. Cookie Policy