Schedule an SMS
Prepare the schedule
Section titled “Prepare the schedule”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.
Supply an unambiguous timestamp
Section titled “Supply an unambiguous timestamp”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.
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 AcceptedContent-Type: application/jsonLocation: /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.
What the response confirms
Section titled “What the response confirms”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.
Retry or change the plan
Section titled “Retry or change the plan”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.