The statuses and what they claim
A message created through the API starts as queued, or accepted when a messaging service is used, then moves through sending to sent, meaning the upstream carrier took it. The end states are delivered, undelivered and failed. Delivered means Twilio received confirmation from the carrier and, where available, the handset; undelivered means a delivery receipt reported non-arrival. The phrase where available is the honest limit: some routes confirm less than others.
- Failed: Twilio could not send it, for example because of a suspended account.
- Undelivered: a receipt said it did not arrive, for example carrier filtering or an unreachable handset.
- Read and received exist for other channels and inbound messages and are outside a plain outbound text.
Why the latest arrival is the wrong rule
Twilio tells developers that callbacks may arrive out of order because of network latency and quick successive transitions. A handler that overwrites the stored status with each arrival will sometimes show sent after delivered. Give each status a rank, accept a new status only if its rank is higher than the stored one, and treat the three end states as final. If a failed callback arrives after a sent one, move forward; if a sent arrives after delivered, ignore it.
- Store the message SID, current status, error code and the time of each accepted change.
- Do not discard rejected arrivals silently; log that they were ignored.
- Use the stored history in your admin view, not only the current status.
Error codes are information, not rules
Twilio warns that the error code and message values for a given cause may change as it refines them, and that you should not use them programmatically. An unreachable handset, for example, is reported with a carrier-level code whose cause is often temporary. Show the code to your team and keep it in the record, but do not build a rule that deletes a customer's number because one code appeared once. Decide separately how many failures make a number worth reviewing.
- Retry rules should come from the final status and a count, not from one code.
- Keep a plain-language label for the few codes your team sees often.
- Review repeated failures by hand before removing anyone.
A safe first investigation
Take one real message in your Twilio console and read its status history and any error code, without copying the recipient's number into any ticket. Compare it with what your app stored. If the app stored sent while Twilio shows delivered, either callbacks are not arriving, are being rejected, or are being applied in the wrong order. Check the callback address, the response code your handler returns and its signature check in that order.
How the paid outcome is accepted
The Twilio outcome for one notification type is accepted when a live send to your own test phone stores a message record, replaying an older callback after the final one leaves the final state, and an unsigned callback changes nothing. The fixed £345 price is untested and payment follows your sign-off. Sender registration and consent rules stay with you.
Sources and limits
- Twilio: track outbound message status Checked 2026-10-11.
- Callbacks can arrive out of order and Twilio gives no guarantee of the order of arrival.
- The endpoint should return HTTP 200 and tolerate new parameters.
- Twilio: Message resource Checked 2026-10-11.
- Status values include queued, sending, sent, delivered, undelivered and failed, with delivered reflecting handset confirmation only where available.
- Error codes may change and should not be used programmatically.
- Twilio error 30003 Checked 2026-10-11.
- 30003 is a carrier-level error whose cause is often temporary, such as a phone that is off or out of coverage.