What arrives
APOST with Content-Type: application/json:
id is the messageId your send returned. That is how you correlate — there is nothing else.
Field names follow Jasmin’s, so a receiver written for Jasmin reads this unchanged. Null fields are
omitted rather than sent as nulls, so a receipt for a message that never reached a vendor does not
arrive full of empty keys.
Every call carries User-Agent: FireFlo/<version>.
level decides whether you are finished
Choose with
dlr_level on the send: 1 progress only, 2 the outcome (default), 3 both.
Over SMPP the same choice is the registered_delivery octet — bits 1–0 pick none / all /
failure-only / success-only, and bit 4 (0x10) adds the intermediate notification. 0x11 is the
SMPP spelling of dlr_level: 3.
stat is the raw state, not a success flag
DELIVRD, UNDELIV, EXPIRED, DELETED, ACCEPTD, UNKNOWN, REJECTD, FAILED, BUFFRED,
SEEN.
EXPIRED, REJECTD and UNDELIV all bill as failures but mean different things and are worth
telling apart — expiry is a handset that was off for a day, rejection is usually a refusal you can
act on.
err says why it failed
Sent alongside stat when something reported a failure code, and omitted when nothing did — so
a delivered message usually carries no err at all, and its absence means “we were not told” rather
than “no error”.
It is the same value the SMPP err: field carries for the same failure, so receipts over a webhook
and receipts over SMPP agree.
err was added after this payload was first published, so receipts you have on file from earlier
will not carry it.
The vendor field is absent unless your provider enables it
It names which supplier carries your traffic. Providers withhold that from customers by construction
elsewhere, so it is off by default and enabled per deployment.
operator_msg_id is not the same disclosure and is always sent: it is the carrier’s own handle
for the message, which is what you quote when raising a delivery query. It identifies the message,
not the supplier.
Delivery, retries and what counts as success
Three segments, three receipts
By default you get one receipt persubmit_sm you sent, each quoting the id you were given. Your
provider can collapse that to one with first or last.
Every receipt reports the same outcome whichever they choose, because the outbound segments are
aggregated before any receipt is built.
Related
Callbacks not arriving
The success range, the retry budget, and the placeholder trap.
Handling errors
Building for the receipt rather than the response.