Subscribe) or polling (Pull) — and remove each receipt with Ack. Both read the same
queue.
It is the alternative to running a webhook endpoint: nothing to expose
to the internet, nothing for the gateway to retry against, and receipts kept until you have them.
Which receipts land in the feed
A receipt is queued for your login when all of these hold:- the message was sent by your HTTP login — over gRPC or over REST;
- it asked for receipts —
dlr: trueon gRPC,"dlr": "yes"on REST — and this receipt is one it asked for (dlr_level:1progress,2the outcome,3both); - it carries no
dlr_url.
dlr_url has its receipts sent to that URL and never to
the feed. Messages sent over SMPP never appear in it — they get their receipts on the bind.
REST sends can use the feed too. On a platform with gRPC and the feed switched on, REST accepts
"dlr": "yes" with no dlr_url, and those receipts land here. Where gRPC is off, that REST request is
still refused 400, because the receipts would have nowhere to go. See
POST /secure/send.UNKNOWN receipt in the feed, as a webhook would.
The Receipt message
The webhook’s JSON body, one field per key, plus two delivery fields at the end:
Optional fields are absent, not empty, when there is nothing to say. Everything the
delivery receipts guide says about
level, stat and err
applies unchanged.
Delivery is at least once
1
A receipt leaves the queue only when you Ack it
Or when retention removes it — see Limits and retention.
2
A delivered receipt is leased to you for 120 seconds
Not acknowledged by then, it is delivered again — to whichever
Subscribe or Pull of your login
asks next — with delivery_count up by one.3
A stream that ends gives its receipts back at once
When a
Subscribe stream ends — you cancel, the connection drops, the gateway restarts — the
receipts it had delivered and you had not acknowledged are released immediately, not after the
lease.Ack
already_gone is not an error. An Ack repeated after a timeout is safe, which is exactly when you
will repeat one. More than 1000 tokens in one call is INVALID_ARGUMENT.
A token works on any gateway node and across restarts, but only for the login it was delivered to.
Batch your acknowledgements: one Ack of 500 tokens is far cheaper than 500 of one.
Pull: polling
max receipts (at most 1000), oldest first.
- With none waiting and
wait_secondsabove 0, it waits up to that long — 20 seconds at most — and returns as soon as one arrives. That is a long poll, and it is how you avoid a busy loop. - With
wait_seconds: 0it returns at once, possibly empty.
Pull suits a batch job, a worker that wakes on a timer, or a language whose streaming support you
would rather not depend on.
Subscribe: streaming
window bounds how many delivered-but-unacknowledged receipts the stream holds. At the window the
stream pauses until you Ack — on any channel. Unset, or above the gateway’s maximum (1000 by
default), the maximum is used.
Several readers share the queue
SeveralSubscribe streams — and Pulls — of one login share the queue: each receipt goes to
exactly one of them at a time. Use that to spread receipt handling over several workers. To give
separate applications separate feeds, give them separate HTTP logins.
Ordering
Best effort, by arrival. There is no ordering guarantee across gateway nodes, and a redelivered receipt arrives after newer ones. An outcome can arrive before a progress receipt for the same message. Order bylevel — 2 is final — and by done_date, never by arrival. Once you hold a level: 2
receipt for a message, ignore any level: 1 that comes after it.
Limits and retention
Your provider can change each of these.
Related
Examples
Subscribe, Pull and Ack loops in Python, Java and Go.
The delivery receipt webhook
The same fields, POSTed to your URL instead.