Skip to content

Statuses and failures ​

A message moves forward through its statuses until it reaches a final one.

text
queued → submitted → sent → delivered → read
             │         │
             │         └──────→ failed / expired
             └──→ rejected
StatusFinalWebhookMeaning
accepted—Accepted by the API. Only seen in the history: the answer of POST /messages is already queued.
queued—Waiting in the ACE SEND queue to go to the provider.
submitted—Handed to the provider.
sentmessage.sentThe provider sent it to the network.
deliveredmessage.deliveredDelivered to the phone. A WhatsApp message can still become read.
readyesmessage.readOpened by the recipient. WhatsApp only: SMS never report reads.
rejectedyesmessage.failedRefused by the provider or the network before it was sent; error says why.
failedyesmessage.failedSent but not delivered; error says why.
expiredyesmessage.failedNot delivered in time (the phone stayed offline).
cancelledyesmessage.failedCampaign messages only: the campaign was stopped before the message went to the provider.

What to rely on ​

  • Final statuses never change: read, rejected, failed, expired, cancelled.
  • delivered is not final for WhatsApp: it becomes read when the recipient opens the message (if they share read receipts — many do not). For SMS delivered is the last status.
  • Steps can be skipped. Some networks report delivered without sent; then no message.sent comes. Treat any later status as including the earlier ones.
  • Statuses never go back. A late failed after delivered is kept in the history but does not change the status.
  • Webhooks can arrive out of order. Compare the order of statuses above, not the order of arrival: a message.sent that comes after message.delivered changes nothing.

The history of a message — every status with its time and error — is in events of GET /v1/messages/{id}.

Failure codes ​

When a message does not reach the recipient, error tells why: a stable code and a text for people in the language of Accept-Language (in English in webhooks).

json
"error": { "code": "no_whatsapp", "text": "The number does not use WhatsApp" }
error.codeerror.text (English)Meaning
no_whatsappThe number does not use WhatsAppThe number has no WhatsApp account. Send an SMS instead.
invalid_numberThe number is invalidThe network does not know the number.
blockedThe recipient blocked the messagesThe recipient or the operator blocked the messages.
template_pausedThe template is paused by WhatsAppWhatsApp paused the template, usually after negative feedback. Use another template.
template_rejectedThe template is rejected by WhatsAppWhatsApp no longer allows the template.
rate_limitedToo many messages to the recipientThe recipient got too many messages recently. Try later.
expiredThe message was not delivered in timeThe phone stayed unreachable.
provider_errorDelivery errorThe provider failed to deliver the message.
not_sentThe message did not go outThe message did not leave ACE SEND.
sender_rejectedThe operator or the provider did not accept the sender nameSMS: the sender name is not registered or not allowed for the operator.
otherNot deliveredAnother reason; text carries the words of the provider.

New codes may appear: treat an unknown one as other.

Message text ​

text is the text as sent. After 90 days it is erased: text becomes null and text_masked is true. The number, template, statuses and price stay.

ACE SEND API v1