Send SMS with the API

With the Callr REST API, sending an SMS is quick and easy — just a simple POST request to the /sms endpoint. You can set the destination number, message content, sender ID, traffic type, and encoding.

🗒️

Reference

Send SMS


📲 Example: Send an SMS

const baseUrl = 'https://api.callr.com/v2.0/sms'
const apiKey = '<callr-api-key>' // Get your API key from https://app.callr.com/api/keys
const number = '+33639981020' // E.164 formatted phone number

const params = new URLSearchParams({
  to: number,
  trafficType: 'marketing'
})

const url = `${baseUrl}?${params.toString()}`

const options = {
  method: 'POST',
  headers: {
    accept: 'application/json',
    'content-type': 'application/json',
    'x-api-key': apiKey
  },
  body: JSON.stringify({ text: 'Hello world!' })
}

try {
  const res = await fetch(url, options)
  const json = await res.json()
  console.log(json)
} catch (err) {
  console.error(err)
}
import requests

api_key = '<callr-api-key>'  # Replace with your Callr API key
number = '+33639981020'      # Destination number (E.164 format)
text = 'Hello world!'

url = f'https://api.callr.com/v2.0/sms?to={number}&trafficType=marketing'
headers = {
    'accept': 'application/json',
    'content-type': 'application/json',
    'x-api-key': api_key
}
payload = {
    'text': text
}

try:
    response = requests.post(url, headers=headers, json=payload)
    response.raise_for_status()
    print(response.json())
except requests.exceptions.RequestException as e:
    print(f"Error sending SMS: {e}")
<?php

$apiKey = '<callr-api-key>'; // Replace with your Callr API key
$number = '+33639981020';     // Destination number
$text = 'Hello world!';

$url = 'https://api.callr.com/v2.0/sms?to=' . urlencode($number) . '&trafficType=marketing';

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'accept: application/json',
    'content-type: application/json',
    'x-api-key: ' . $apiKey
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['text' => $text]));

$response = curl_exec($ch);
$err = curl_error($ch);
curl_close($ch);

if ($err) {
    echo "cURL Error: $err";
} else {
    echo $response;
}
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

func main() {
	apiKey := "<callr-api-key>" // Replace with your Callr API key
	number := "+33639981020"
	text := "Hello world!"

	url := fmt.Sprintf("https://api.callr.com/v2.0/sms?to=%s&trafficType=marketing", number)

	payload := map[string]string{
		"text": text,
	}
	body, _ := json.Marshal(payload)

	req, _ := http.NewRequest("POST", url, bytes.NewBuffer(body))
	req.Header.Set("accept", "application/json")
	req.Header.Set("content-type", "application/json")
	req.Header.Set("x-api-key", apiKey)

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Error sending SMS:", err)
		return
	}
	defer resp.Body.Close()

	var result map[string]interface{}
	json.NewDecoder(resp.Body).Decode(&result)
	fmt.Println(result)
}
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var apiKey = "<callr-api-key>"; // Replace with your Callr API key
        var number = "+33639981020";     // Destination number
        var text = "Hello world!";

        var client = new HttpClient();
        var url = $"https://api.callr.com/v2.0/sms?to={Uri.EscapeDataString(number)}&trafficType=marketing";

        var requestBody = new StringContent(
            "{\"text\":\"" + text + "\"}",
            Encoding.UTF8,
            "application/json"
        );

        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.Add("x-api-key", apiKey);

        try
        {
            var response = await client.PostAsync(url, requestBody);
            var responseContent = await response.Content.ReadAsStringAsync();
            Console.WriteLine(responseContent);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error sending SMS: {ex.Message}");
        }
    }
}

📋 Request Parameters

ParameterTypeRequiredDescription
tostring✅ YesDestination phone number in E.164 format (e.g., +33639981020)
textstring✅ YesThe SMS body text (1 to 3200 characters)
fromstringNoSender ID (phone number or alphanumeric, max 11 characters). Requires prior approval.
trafficTypestringNo"marketing" (default) or "alerting". Required by some carriers.
encodingstringNoForce "gsm" or "unicode" encoding. Defaults to automatic detection.

ℹ️

Note

If you leave from empty, Callr automatically sets an appropriate sender based on destination rules.


🔥 Status Lifecycle

Once the SMS is accepted, it will go through these statuses:

StatusMeaning
createdSMS has been created in the system
pendingSMS is waiting to be sent
sentSMS has been sent by Callr
remote-queuedSMS is queued on the carrier network
deliveredSMS was successfully delivered to the recipient

At any time, it may also move to:

StatusMeaning
errorSMS was rejected at creation
failedSMS was rejected by the carrier
expiredSMS expired before delivery

🧾 Response Fields

On a successful send (HTTP 202 Accepted), you will receive:

FieldTypeDescription
sidstringShort ID identifying the SMS
directionstringoutbound
fromstringSender phone number or alphanumeric sender
tostringDestination number
body.textstringBody text of the SMS
trafficTypestring"marketing" or "alerting"
statusstringCurrent status of the SMS
errorstringError message if applicable
createddatetimeWhen the SMS was created (RFC 3339 format)
sentdatetimeWhen the SMS was sent (if applicable)
delivereddatetimeWhen the SMS was delivered (if applicable)
updateddatetimeLast status update time
partsintegerNumber of SMS parts used
networkstringMCC MNC network code (e.g., 20801 for Orange France)
encodingstringgsm or unicode
coststringCost of the SMS in cents
paymentTypestringprepaid or postpaid
statusHistoryarrayList of all status transitions with timestamps

📦 Example Response

{
  "sid": "smsabcdef12345678",
  "direction": "outbound",
  "from": "TOPIMMO",
  "to": "+33639981020",
  "body": {
    "text": "Hello world!"
  },
  "trafficType": "marketing",
  "status": "sent",
  "cost": "4.50",
  "paymentType": "prepaid",
  "created": "2025-04-24T17:42:28Z",
  "updated": "2025-04-24T17:42:30Z",
  "sent": "2025-04-24T17:42:29Z",
  "delivered": null,
  "encoding": "gsm",
  "parts": 1,
  "network": "20801",
  "statusHistory": [
    {
      "before": "created",
      "after": "pending",
      "at": "2025-04-24T17:42:28Z"
    },
    {
      "before": "pending",
      "after": "sent",
      "at": "2025-04-24T17:42:29Z"
    }
  ]
}

🌐 Receive status updates with Webhooks

For webhook setup, go to the Webhooks section in the Callr Portal.

  1. Create a new webhook
  2. Select the event: v2.sms.outbound.updated
  3. Provide your HTTPS endpoint URL

Example payload

{
  "id": "a033174403257076580mk8v4KiGgZA32",
  "at": "2025-04-07T13:29:30.765Z",
  "sid": "pdszbxss",
  "type": "v2.sms.outbound.updated",
  "try": 0,
  "payload": {
    "direction": "outbound",
    "sid": "callrsid",
    "from": "SMS",
    "to": "+33639980010",
    "body": {
      "text": "Hello world!"
    },
    "trafficType": "marketing",
    "status": "delivered",
    "error": "",
    "created": "2024-04-24T17:42:28Z",
    "delivered": "2024-04-24T17:42:28Z",
    "updated": "2024-04-24T17:42:28Z",
    "sent": "2024-04-24T17:42:28Z",
    "parts": 1,
    "network": "20801",
    "encoding": "gsm",
    "cost": "2.0",
    "paymentType": "prepaid",
    "statusHistory": [
      {
        "after": "delivered",
        "before": "sent",
        "at": "2024-04-24T17:42:28Z"
      }
    ]
  }
}


⚡ Good to Know

  • GSM encoding supports 153 characters per SMS part (160 if there is only one part).
  • Unicode encoding supports 67 characters per SMS part (70 if there is only one part).
  • Multipart SMS are automatically handled by Callr and reassembled by carriers.
  • Some countries/carriers require "alerting" traffic type for critical messages (OTP, security alerts).