إرسال
SMS

SMS

Send single, bulk, template, and group SMS messages

The SMS endpoints let you send messages in four ways:

EndpointUse case
Send MessageSingle recipient
Send BulkAn explicit list of recipients
Send TemplatePre-defined message templates with variables
Send to Contact GroupAll contacts in a saved group
List MessagesView sent message history
Get MessageCheck delivery status of a specific message

payment_type

All send endpoints require a payment_type field:

ValueDescription
walletDeducted from your company's wallet balance
subscriptionDeducted from your project's active subscription quota

Either way, running out returns 400 with { "message": "Insufficient balance" }.

Sending is asynchronous

A 2xx from a send endpoint means the request was accepted and your balance reserved — the message has not yet reached the network. Delivery is processed in the background.

This has three consequences worth designing around:

  • The returned message_id may not appear in List Messages immediately. Fetch it directly with Get Message, which also serves still-queued requests.
  • Per-recipient delivery status arrives later. Poll Get Message rather than treating the send response as confirmation.
  • If ingest fails after acceptance, the reserved balance is refunded and Get Message reports status: "failed".

Message validity

Every accepted message carries a deadline. A recipient not delivered by then is marked expired and refunded — wallet sends get the money back, subscription sends get the quota back. Poll Get Message to see it; the refund lands shortly after the deadline passes.

The default is 24 hours. Pass expires_after to shorten or extend it:

TypeInteger — seconds from acceptance
Range60 to 604800 (1 minute to 7 days). Outside that returns 422
Default24 hours
Supported onSend Message, Send Bulk, Send Template
{
  "message": "Your verification code is 481920.",
  "sender": "MyApp",
  "payment_type": "wallet",
  "receiver": "00218912345678",
  "expires_after": 300
}

Set this when sending verification codes. On the 24-hour default, a delayed code can arrive the next day. 300 is typical.

Send to Contact Group does not accept expires_after — those sends always use the 24-hour default, and the field is ignored if you pass it.

Sender IDs and provider matching

A sender ID is registered against specific network operators. A recipient whose number belongs to an operator your sender ID is not registered on is rejected — for single and template sends with 400 The receiver is not from the same provider, and for bulk and group sends by being silently dropped from the batch.

Compare details.sent against details.total on bulk and group sends to detect dropped recipients.

Temporarily unreachable operators

An operator your sender ID is registered on can still be temporarily unreachable. Sends to that operator are refused immediately and never charged.

EndpointBehaviour
Send Message, Send Template503 The provider for this receiver is temporarily unavailable
Send Bulk, Send to Contact GroupAffected recipients are dropped and counted in details.skipped_unavailable; if that leaves nothing to send, 503 The provider for these receivers is temporarily unavailable

The status code is what separates this from a permanent mismatch: 400 will never succeed, 503 will succeed once the operator is reachable again. Sends to other operators carry on normally throughout.

Numbers on an unreachable operator are still valid. Keep them in your contact lists — only sending to them fails, and it starts working again on its own.

On this page