Reading a delivery receipt
A receipt is a sequence of states, not a verdict. Treating an intermediate one as final is the most common way a sending dashboard ends up lying to you.
Read the guide →Two providers describe the same outcome with two different words, and neither word means what the reader assumes. Normalising receipts into one status is what makes a receipt usable in code rather than as a screenshot.
Receipt collection and normalisation ship on the SMS channel: whichever provider carried the message, your system reads one normalised status instead of a provider-specific word it has to translate itself. That is what makes a receipt usable in code.
A delivery receipt says the destination network accepted the message. It does not say a human read it, and it does not say the handset displayed it. Treating a receipt as proof of reading is the most common misreading of the data.
Receipts are recorded against the message log and can be pushed to an endpoint you configure, so a system that needs to react does not have to poll. Callback delivery has its own reliability characteristics, which the guides cover explicitly rather than glossing over.
A receipt is a sequence of states, not a verdict. Treating an intermediate one as final is the most common way a sending dashboard ends up lying to you.
Read the guide →Terminal outcomes are pushed to a URL you control, with a small bounded retry. Your handler has to tolerate a repeat, and it should not expect a call for every message.
Read the guide →You keep the provider relationship you already have, connect it once, and the platform treats that account as a send path it can route through, pace against and read receipts from.
Open →One provider account is a single point of failure that you cannot see failing until customers tell you. Routing across several accounts turns that into a failover you configure once.
Open →Suppression is the part of messaging that is easy to get almost right and expensive to get wrong: honour it too broadly and confirmations stop arriving; honour it too narrowly and you are ignoring a customer who asked you to stop. Getting it right is the whole feature.
Open →The limit that stops your traffic is not your application’s quota — it is the rate your provider applies per sender number. One number, one limit, and a batch that ignores it fails partway through.
Open →The sender is the first thing a recipient sees and the thing that decides whether a message is trusted. Because that identity sits on your own account, it stays with you however you choose to send.
Open →Product messaging is emitted by code, not typed by a person. The API exists so the service that knows an event happened is the service that sends the message about it.
Open →Polling for status works until the volume makes it wasteful. A callback lets the system that cares about an event be told about it, which also means the record lands in your own database at the same time.
Open →The first question after any messaging incident is “what did we actually send?”. That answer should come from a log with a filter on it, not from a reconstruction.
Open →Isolation is the feature that nobody asks about until it is missing. Holding connections, keys and records per tenant means a shared platform does not become a shared inbox.
Open →Not every message comes from an API. Testing a new sender, resending after a fix, or simply looking up what a customer received — those are console jobs, and they should not require writing code.
Open →