Skip to content

Search for a complete word or an exact phrase.

Schedule an SMS

Use POST /api/sms/v2/messages/ with send_at. The key needs sms.schedule; delivery.read then allows message lookups. The presence of send_at determines the required permission, even if the key already has sms.send.

Prepare one stable idempotency key for the operation and credits covering the text’s segments. Reading the balance and recording a reservation in your application is not sufficient: only API admission reserves credits.

send_at must be a future RFC 3339 timestamp with seconds and an explicit timezone: Z or an offset such as +03:00. Local timestamps without a timezone, null and past timestamps are rejected.

The example assumes BEFIANA_SMS_API_KEY is set as in the quickstart. Replace the timestamp with a future time that suits your workflow and the number with an authorized recipient.

Terminal window
curl --include --request POST 'https://api.befiana.cloud/api/sms/v2/messages/' \
--header "Authorization: Bearer $BEFIANA_SMS_API_KEY" \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: appointment-0001-reminder' \
--data '{"to":"+261340000000","text":"Your appointment is tomorrow.","send_at":"2030-01-15T09:00:00+03:00"}'

Successful admission returns HTTP 202. Illustrative response:

HTTP/1.1 202 Accepted
Content-Type: application/json
Location: /api/sms/v2/messages/8607cac9-cfda-437f-99f3-ec88824e49f8/
{
"id": "8607cac9-cfda-437f-99f3-ec88824e49f8",
"to": "+261340000000",
"sender_name": "BEFIANA",
"segments": 1,
"status": "scheduled",
"send_at": "2030-01-15T06:00:00Z",
"delivery_time": null
}

The response expresses the same instant as 09:00:00+03:00 in UTC. Compare instants, not timestamp strings. send_at preserves the requested schedule after dispatch. The name BEFIANA assumes the corresponding sender selection.

The id is available for lookup immediately after creation. Credits are reserved and scheduled means the message is waiting for its send time. The requested time is the desired start of processing; it does not guarantee delivery at an exact second.

Retrieve GET /api/sms/v2/messages/{message_id}/ using a key with delivery.read. Processing can then become processing, accepted or another status. An unknown outcome does not justify a new submission.

If the response is lost, retry the exact request with the same idempotency key. Replaying an admitted schedule returns the original response even if processing has advanced. If the completed message’s personal data is later subject to targeted erasure, the replay returns 410 personal_data_erased: stop retries and retain the key without resending. See idempotency.

The v2 contract has no public operation for changing or cancelling a scheduled message. Do not create a second message to “replace” the first without handling the duplicate-send risk.

For multiple recipients sharing the same time and text, use a batch. Without scheduling, use immediate sending.