Download OpenAPI specification:Download
The Batch SMS API enables you to efficiently send SMS messages to multiple recipients with a single API call. This API offers advanced processing features, including batch scheduling, notification callbacks, and detailed status tracking.
Use Authorization with OAuth2 Bearer token. See Authentication section for details on how to obtain the token.
Authorization: Bearer <token>
Content-Type should be application/json.
Content-Type: application/json
All create batch requests must be compressed with gzip.
Content-Encoding: gzip
The sender_id controls how the sender appears on recipient devices. Supported types and rules:
International
Alphanumeric
Shortcode
The sizes are estimates derived from test data, there will be variations in sizes depending on the actual content and how efficient the content can be compressed.
| Number of GSM-7 characters | Number of recipients/messages | Size - Uncompressed | Size - Compressed |
|---|---|---|---|
| 1530 (max size) | 10,000 | 0.9 MB | 0.1 MB |
| 1530 | 100,000 | 9.1 MB | 0.9 MB |
| 1530 | 1,000,000 | 91 MB | 8.4 MB |
| Number of GSM-7 characters | Number of recipients/messages | Size - Uncompressed | Size - Compressed |
|---|---|---|---|
| 160 | 10,000 | 2.6 MB | 1.3 MB |
| 160 | 100,000 | 27 MB | 13 MB |
| 160 | 1,000,000 | 266 MB | 131 MB |
| Number of GSM-7 characters | Number of recipients/messages | Size - Uncompressed | Size - Compressed |
|---|---|---|---|
| 1530 (max size) | 10,000 | 16 MB | 11 MB |
| 1530 | 100,000 | 157 MB | 114 MB |
| 1530 | 1,000,000 | 1500 MB | 1100 MB |
Note on request size: Requests larger than 32MB will be rejected. For large batches with unique messages, consider splitting into multiple smaller batches, or using message templates with personalization fields.
Note on SMS length: A single SMS can contain maximum 160 characters, or maximum 70 characters if it contains emojis or any other character that is not part of the GSM-7 character set. When sending longer messages, up to 10 SMS will be automatically concatenated to carry the message content. The maximum limit is imposed by mobile networks. When concatenating SMS, some overhead is used for the concatenation, so the actual number of characters in each SMS will be reduced to 153 characters for GSM-7 and 67 characters for Unicode. Individual messages that exceeds the 10 SMS limit will be rejected and marked as failed in the batch.
The batch SMS API will dynamically adjust the rate according to the capacity of the underlying SMS API and aims to get as close as possible to the max configured rate limit of the account.
There are two ways to get batch status updates:
Use one of the following endpoints to get the status of the batch
| Endpoint | Description |
|---|---|
/v1/batches/{batch_id}/poll |
Poll batch status, summary only |
/v1/batches/{batch_id}/poll_with_delta |
Poll batch status, summary + message delta information |
notification_settings of the create batch request. (See details below)To receive asynchronous batch event notifications, set the following fields in the batch request:
batch_event_callback_url: The URL to which the event notifications will be sent.batch_event_callback_token: An optional token to be included in the callback URL.If a token is provided in the request by the client, It is used by the server when doing the callbacks. A token can have a max length of 64 characters.
Token provided in batch request:
{
...
"notification_settings": {
"batch_event_callback_url": "https://client.com/batchsmsnotifications"
"batch_event_callback_token": "0fb45e50-86bd-4935-a1e3-6c1ded88d58b",
}
}
Token used in callback:
POST https://client.com/batchsmsnotifications?token=0fb45e50-86bd-4935-a1e3-6c1ded88d58b
{
"event_type": "batch.created",
"timestamp": "2025-03-21T11:15:36Z",
"batch_status_summary": {
... // Complete batch status summary information
}
}
{
"event_type": "batch.scheduled",
"timestamp": "2025-03-21T11:15:36Z",
"batch_status_summary": {
... // Complete batch status summary information
}
}
{
"event_type": "batch.processing_started",
"timestamp": "2025-03-21T10:09:59Z",
"batch_status_summary": {
... // Complete batch status summary information
}
}
{
"event_type": "batch.submission_completed",
"timestamp": "2025-03-21T10:09:59Z",
"batch_status_summary": {
... // Complete batch status summary information
}
}
{
"event_type": "batch.submission_progress_update",
"timestamp": "2025-03-21T10:09:59Z",
"submission_progress_percentage": 95,
"batch_status_summary": {
... // Complete batch status summary information
},
"submitted_messages_delta": [
{
"id": "c58b5ebb-076d-4058-b3d9-a3a01f230bb2",
"external_message_id": "1",
"transaction_id": "02df77cc-b1ce-46b6-89bd-3183a969f855",
"phone_number": "+34693363516",
"message": "Hello World!",
"submission_status": "SUBMITTED",
"submission_time": "2025-03-21T08:29:00Z",
},
{
"id": "166269f1-6147-4154-afe3-49c8ad616235",
"external_message_id": "2",
"transaction_id": "e9f63cfd-1e20-4784-b3a7-d131384f4d32",
"phone_number": "+34604224206",
"message": "Hello World!",
"submission_status": "SUBMITTED",
"submission_time": "2025-03-21T08:30:00Z",
}
]
}
{
"event_type": "batch.canceled",
"timestamp": "2025-03-21T14:47:57Z",
"batch_status_summary": {
... // Complete batch status summary information
}
}
{
"event_type": "batch.failed",
"timestamp": "2025-03-21T14:47:57Z",
"batch_status_summary": {
... // Complete batch status summary information
}
}
OAuth2 token endpoint implementing the client credentials flow.
This endpoint validates client credentials (SMS API account and key) and issues a JWT token if the credentials are valid.
The client_id is the SMS API account, and the client_secret is the SMS API key.
Args: json_data: OAuth2 JSON payload containing client_id and client_secret auth_service: AuthService for credential validation and token creation
Returns: Token object containing the JWT access token and metadata
Raises: HTTPException: If client authentication fails
| client_id required | string (Client Id) SMS API account name |
| client_secret required | string (Client Secret) SMS API key |
| grant_type | string (Grant Type) Default: "client_credentials" OAuth2 grant type |
{- "grant_type": "client_credentials",
- "client_id": "string",
- "client_secret": "string"
}{- "access_token": "string",
- "token_type": "bearer",
- "expires_in": 0
}Create a new batch of SMS messages.
This endpoint allows you to create a batch of SMS messages to be sent to multiple recipients. The batch will be processed asynchronously, and you'll receive a batch ID to track its status.
Detailed field descriptions are available in the API schema documentation.
Key capabilities:
schedule_at parameterThis endpoint requires the request to be compressed with gzip due to potential large payload sizes. Set the 'Content-Encoding: gzip' header and compress the request body.
An account can run one batch at a time. While a batch of yours is being assembled, processing, pausing or paused, another immediate batch on the same account returns 409 Conflict with the id of the batch that is holding it. A scheduled batch is accepted regardless, and starts once the account is free.
| content-encoding required | string (Content-Encoding) Must be set to 'gzip' for compressed requests |
required | object (Batch) Batch configuration | ||||||||||
| |||||||||||
{- "batch": {
- "external_batch_id": "string",
- "schedule_at": "2019-08-24T14:15:22Z",
- "sms_config": {
- "sender_id": {
- "type": "international",
- "value": "string"
}, - "message_template": "string",
- "type": "text",
- "validity_period": 4320,
- "client_reference": "string",
- "dry_run": false
}, - "recipients": [
- {
- "phone_number": "string",
- "external_message_id": "string",
- "message_fields": {
- "property1": "string",
- "property2": "string"
}, - "message": "string"
}
], - "notification_settings": {
- "batch_event_callback_url": null,
- "batch_event_callback_token": null,
- "batch_event_include_messages_delta": null,
- "sms_dlr_callback_url": null
}
}
}{- "id": "string"
}Get comprehensive status and configuration of a batch by its ID.
This endpoint returns complete batch information including:
Don't use this endpoint for polling status.
| batch_id required | string (Batch Id) |
{- "batch_status_summary": {
- "id": "string",
- "external_batch_id": "string",
- "account": "string",
- "status": "CREATED",
- "total_messages": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "scheduled_at": "2019-08-24T14:15:22Z",
- "processing_started_at": "2019-08-24T14:15:22Z",
- "submission_completed_at": "2019-08-24T14:15:22Z",
- "canceled_at": "2019-08-24T14:15:22Z",
- "failed_at": "2019-08-24T14:15:22Z",
- "messages_submission_status": {
- "pending": 0,
- "submitted": 0,
- "failed": 0,
- "unknown": 0
}
}, - "sms_config": {
- "sender_id": {
- "type": "international",
- "value": "string"
}, - "message_template": "string",
- "type": "text",
- "validity_period": 4320,
- "client_reference": "string",
- "dry_run": false
}, - "notification_settings": {
- "batch_event_callback_url": null,
- "batch_event_callback_token": null,
- "batch_event_include_messages_delta": null,
- "sms_dlr_callback_url": null
}
}Get batch status summary.
This endpoint efficiently supports polling for status changes by only returning:
It's designed for clients to repeatedly call to monitor batch progress.
| batch_id required | string (Batch Id) |
{- "timestamp": "2019-08-24T14:15:22Z",
- "batch_status_summary": {
- "id": "string",
- "external_batch_id": "string",
- "account": "string",
- "status": "CREATED",
- "total_messages": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "scheduled_at": "2019-08-24T14:15:22Z",
- "processing_started_at": "2019-08-24T14:15:22Z",
- "submission_completed_at": "2019-08-24T14:15:22Z",
- "canceled_at": "2019-08-24T14:15:22Z",
- "failed_at": "2019-08-24T14:15:22Z",
- "messages_submission_status": {
- "pending": 0,
- "submitted": 0,
- "failed": 0,
- "unknown": 0
}
}
}Get batch status and message changes since a specific sequence point.
This endpoint efficiently supports polling for status changes by only returning:
It's designed for clients to repeatedly call to monitor batch progress.
| batch_id required | string (Batch Id) |
| last_sequence_id | integer (Last Sequence Id) >= 0 Default: 0 |
| max_delta_size | integer (Max Delta Size) [ 1 .. 2000 ] Default: 500 |
{- "timestamp": "2019-08-24T14:15:22Z",
- "batch_status_summary": {
- "id": "string",
- "external_batch_id": "string",
- "account": "string",
- "status": "CREATED",
- "total_messages": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "scheduled_at": "2019-08-24T14:15:22Z",
- "processing_started_at": "2019-08-24T14:15:22Z",
- "submission_completed_at": "2019-08-24T14:15:22Z",
- "canceled_at": "2019-08-24T14:15:22Z",
- "failed_at": "2019-08-24T14:15:22Z",
- "messages_submission_status": {
- "pending": 0,
- "submitted": 0,
- "failed": 0,
- "unknown": 0
}
}, - "next_sequence": 0,
- "has_more": true,
- "submitted_messages_delta": [
- {
- "id": "string",
- "external_message_id": "string",
- "transaction_id": "",
- "phone_number": "string",
- "message": "string",
- "submission_status": "PENDING",
- "submitted_at": "2019-08-24T14:15:22Z",
- "failed_at": "2019-08-24T14:15:22Z",
- "error_message": "string"
}
]
}Cancel a batch.
A batch can be canceled while it is scheduled, processing, pausing or paused.
The batch is canceled immediately and the response reports it as CANCELED.
Note that submissions already in flight when the cancel arrives may still reach the SMS network; those messages are counted truthfully in the batch's final statistics, so the submitted count can keep rising briefly after the cancel returns.
A batch that has already completed or been canceled returns 409 Conflict.
| batch_id required | string (Batch Id) |
{- "batch_status_summary": {
- "id": "string",
- "external_batch_id": "string",
- "account": "string",
- "status": "CREATED",
- "total_messages": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "scheduled_at": "2019-08-24T14:15:22Z",
- "processing_started_at": "2019-08-24T14:15:22Z",
- "submission_completed_at": "2019-08-24T14:15:22Z",
- "canceled_at": "2019-08-24T14:15:22Z",
- "failed_at": "2019-08-24T14:15:22Z",
- "messages_submission_status": {
- "pending": 0,
- "submitted": 0,
- "failed": 0,
- "unknown": 0
}
}
}Pause a batch that is processing or scheduled.
Pausing a processing batch happens in two phases. The response is immediate
and reports the batch as PAUSING: submission stops within about ten
seconds, and once the batch has stopped sending and every confirmed result
is recorded, it settles in PAUSED. Poll the batch, or subscribe to the
batch.paused event, to learn when it has settled. Messages already handed
to the SMS network before the pause took effect are sent normally.
A batch with nothing left to stop - a scheduled one that has not started, or
one that has already come to a halt - reports PAUSED right away. A paused
scheduled batch will not start at its scheduled time until it is resumed.
Pausing a batch that is already pausing or paused changes nothing and succeeds. A batch that has completed, failed or been canceled returns 409 Conflict.
Pause and resume may not be issued in rapid succession on the same batch; a request inside the minimum interval returns 409 Conflict.
| batch_id required | string (Batch Id) |
{- "batch_status_summary": {
- "id": "string",
- "external_batch_id": "string",
- "account": "string",
- "status": "CREATED",
- "total_messages": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "scheduled_at": "2019-08-24T14:15:22Z",
- "processing_started_at": "2019-08-24T14:15:22Z",
- "submission_completed_at": "2019-08-24T14:15:22Z",
- "canceled_at": "2019-08-24T14:15:22Z",
- "failed_at": "2019-08-24T14:15:22Z",
- "messages_submission_status": {
- "pending": 0,
- "submitted": 0,
- "failed": 0,
- "unknown": 0
}
}
}Resume a paused batch.
Submission continues with exactly the messages that were not dispatched
before the pause; no message is ever sent twice. A batch that was paused
before its scheduled time returns to SCHEDULED and starts at that time;
every other paused batch reports PROCESSING and continues immediately.
The account is re-checked before the batch leaves PAUSED, so an account
that became inactive while the batch was paused returns 403 Forbidden and
the batch stays paused.
Only a PAUSED batch can be resumed; any other state returns 409 Conflict,
as does a resume issued inside the minimum pause/resume interval.
| batch_id required | string (Batch Id) |
{- "batch_status_summary": {
- "id": "string",
- "external_batch_id": "string",
- "account": "string",
- "status": "CREATED",
- "total_messages": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "scheduled_at": "2019-08-24T14:15:22Z",
- "processing_started_at": "2019-08-24T14:15:22Z",
- "submission_completed_at": "2019-08-24T14:15:22Z",
- "canceled_at": "2019-08-24T14:15:22Z",
- "failed_at": "2019-08-24T14:15:22Z",
- "messages_submission_status": {
- "pending": 0,
- "submitted": 0,
- "failed": 0,
- "unknown": 0
}
}
}Simple health check endpoint that verifies the API is operational.
Returns a JSON response with "status": "OK" when the API is functioning correctly. This endpoint can be used by monitoring systems to verify API availability.
Returns: HealthResponse: Status information indicating the API is healthy
{- "status": "OK"
}