Skip to main content
500CallsDocs
Browse the docs

Send one SMS to many recipients

POST/v1/sms/messages/bulk

Sends the same body to every recipient in to, up to the per-request limit (1,000 by default). Each recipient is checked on its own: one that fails is created as rejected with its error and the others go ahead. If none passes, the request is refused with 422 and nothing is created. If the held total exceeds your available balance, nothing is accepted (402).

Scope
messages:send

Request

Every request needs an API key in the Authorization header, and the key needs the scope the endpoint names.

Parameters

  • Idempotency-Keyheaderstring

    1 to 64 characters from A-Z, a-z, 0-9, _ and -. Repeating a request with the same key and body within 24 hours returns the stored success response without acting again; the same key with a different body is refused with 409.

    • Matches ^[A-Za-z0-9_-]{1,64}$

Body

  • toarray of stringRequired

    The recipients, up to the per-request limit (1,000 by default), each in any common Nigerian or international format.

    • At least 1 items
    • At most 256 characters
  • fromstringRequired

    The sender ID: 3 to 11 letters, digits, spaces, hyphens or periods. It must be one of yours that can be used now.

    • 3 to 11 characters
    • Matches ^[A-Za-z0-9 .-]+$
  • bodystringRequired

    The message text sent to every recipient, exactly as given.

  • client_referencestringor null

    Your own reference, copied onto every message created.

    • 1 to 64 characters
    • Matches ^[\x20-\x7e]+$
  • send_atstring (date-time)or null

    Schedule the send for this time, between 1 minute and 90 days from now. Omit it to send now.

Example body
{  "to": [    "08031234567",    "+2348059876543",    "0803 123 4567",    "12345",    "+447700900123"  ],  "from": "ACMESTORES",  "body": "Hi! Our Lekki store opens at 9am tomorrow."}

Responses

202 Accepted

ReturnsSendResultEnvelope

Headers

  • Cache-ControlstringRequired

    Responses are never cached.

  • Idempotent-Replayedstring

    Present when this is the stored response of an earlier request with the same Idempotency-Key.

  • RateLimit-Limitinteger

    Requests per second your account may sustain.

  • RateLimit-Remaininginteger

    Whole requests left in your account's bucket.

  • RateLimit-Resetinteger

    Seconds until the bucket is full again.

  • X-Request-IdstringRequired

    This request's ID, also given as request_id in error bodies. Quote it to support.

Example response
{  "data": {    "object": "send_result",    "accepted": 2,    "currency": "NGN",    "held_amount": "5.8000",    "messages": [      {        "id": "msg_01M3KR6D868QPH5MEE2236DZS0",        "client_reference": null,        "error": null,        "held_amount": "2.9000",        "index": 0,        "input": "08031234567",        "segments": 1,        "status": "queued",        "to": "+2348031234567"      },      {        "id": "msg_01M3KR6D868QPH5MEE2236DZS1",        "client_reference": null,        "error": null,        "held_amount": "2.9000",        "index": 1,        "input": "+2348059876543",        "segments": 1,        "status": "queued",        "to": "+2348059876543"      },      {        "id": "msg_01M3KR6D868QPH5MEE2236DZS2",        "client_reference": null,        "error": {          "code": "duplicate_recipient",          "message": "The same number appears earlier in this request."        },        "held_amount": "0.0000",        "index": 2,        "input": "0803 123 4567",        "segments": 1,        "status": "rejected",        "to": "+2348031234567"      },      {        "id": "msg_01M3KR6D868QPH5MEE2236DZS3",        "client_reference": null,        "error": {          "code": "invalid_recipient",          "message": "Not a valid mobile number."        },        "held_amount": "0.0000",        "index": 3,        "input": "12345",        "segments": 1,        "status": "rejected",        "to": "12345"      },      {        "id": "msg_01M3KR6D868QPH5MEE2236DZS4",        "client_reference": null,        "error": {          "code": "destination_not_supported",          "message": "The destination country is not enabled."        },        "held_amount": "0.0000",        "index": 4,        "input": "+447700900123",        "segments": 1,        "status": "rejected",        "to": "+447700900123"      }    ],    "mode": "live",    "rejected": 3,    "requested": 5,    "reservation_id": "rsv_01M3KR6CZMBP3APZFHRGEMMMYE",    "segments": 2  }}

Errors

Each code links to its page. Branch on the code, never on the title or detail.

Example 422 response
{  "type": "https://docs.messaging.500calls.com/errors/validation_error",  "title": "Validation error",  "status": 422,  "code": "validation_error",  "detail": "No recipient could be accepted. No messages were created.",  "request_id": "req_01M3KR6CQ26S90NG2V790GVFTX",  "errors": [    {      "field": "to[0]",      "code": "invalid_recipient",      "message": "Not a valid mobile number."    },    {      "field": "to[1]",      "code": "invalid_recipient",      "message": "Not a valid mobile number."    }  ]}

Code samples

Each sample reads your key from the API_KEY_500CALLS environment variable.

cURL
curl -X POST 'https://api.messaging.500calls.com/v1/sms/messages/bulk' \  -H "Authorization: Bearer $API_KEY_500CALLS" \  -H 'Content-Type: application/json' \  -H 'Idempotency-Key: order-78123-otp' \  -d '{  "to": [    "08031234567",    "+2348059876543",    "0803 123 4567",    "12345",    "+447700900123"  ],  "from": "ACMESTORES",  "body": "Hi! Our Lekki store opens at 9am tomorrow."}'
Python
import osimport requestsresponse = requests.post(    "https://api.messaging.500calls.com/v1/sms/messages/bulk",    headers={        "Authorization": f"Bearer {os.environ['API_KEY_500CALLS']}",        "Idempotency-Key": "order-78123-otp",    },    json={        "to": [            "08031234567",            "+2348059876543",            "0803 123 4567",            "12345",            "+447700900123",        ],        "from": "ACMESTORES",        "body": "Hi! Our Lekki store opens at 9am tomorrow.",    },    timeout=30,)print(response.status_code, response.json())
Node.js
const response = await fetch("https://api.messaging.500calls.com/v1/sms/messages/bulk", {  method: "POST",  headers: {    Authorization: `Bearer ${process.env.API_KEY_500CALLS}`,    "Content-Type": "application/json",    "Idempotency-Key": "order-78123-otp",  },  body: JSON.stringify({    "to": [      "08031234567",      "+2348059876543",      "0803 123 4567",      "12345",      "+447700900123"    ],    "from": "ACMESTORES",    "body": "Hi! Our Lekki store opens at 9am tomorrow."  }),});console.log(response.status, await response.json());
PHP
<?php$curl = curl_init('https://api.messaging.500calls.com/v1/sms/messages/bulk');curl_setopt_array($curl, [    CURLOPT_CUSTOMREQUEST => 'POST',    CURLOPT_HTTPHEADER => [        'Authorization: Bearer ' . getenv('API_KEY_500CALLS'),        'Content-Type: application/json',        'Idempotency-Key: order-78123-otp',    ],    CURLOPT_POSTFIELDS => json_encode([        'to' => [            '08031234567',            '+2348059876543',            '0803 123 4567',            '12345',            '+447700900123',        ],        'from' => 'ACMESTORES',        'body' => 'Hi! Our Lekki store opens at 9am tomorrow.',    ]),    CURLOPT_RETURNTRANSFER => true,]);$body = curl_exec($curl);$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);echo $status, PHP_EOL, $body, PHP_EOL;