SMS

What is a delivery receipt (DLR), and how reliable is it?

A delivery receipt (DLR) reports a text message's network delivery outcome, but does not establish that anyone read it.

Your send request can succeed before the recipient's phone receives anything. A later carrier report supplies another result, which your application must handle separately from request acceptance.

What does a delivery receipt tell me?

A receipt reports delivery success or a delivery problem from the network's perspective.

An SMS delivery result can arrive while the phone sits unread in a drawer. It does not prove that the recipient saw the sender identity. It also does not establish that they read the complete text.

The network sends receipts separately from its response to a send request. It can also suppress some reports. The SMPP receipt reference documents these controls for carrier connections.

Which carrier receipts does Bird expose?

You receive public events for recognized delivery outcomes. Buffered receipts remain internal.

A buffered receipt says the carrier is holding the message. Bird records it in its internal event log without changing the public message status. You see no update in the public timeline or your webhooks.

Carrier receipt statusBird event
deliveredsms.delivered
expiredsms.expired
rejectedsms.rejected
delivery_failed with a recoverable reasonsms.undelivered
delivery_failed with a permanent or unmapped reasonsms.failed
bufferedNo public event

An unrecognized carrier status produces no event. A missing public update therefore does not establish that the carrier sent no receipt.

Why does one failure status produce different events?

Bird uses the carrier's failure reason to decide whether the underlying problem may clear.

Carrier reasonBird error codeClassification
unavailable_subscriberunreachableRecoverable
received_network_errorprovider_unavailableRecoverable
capacity_limit_reachedprovider_unavailableRecoverable
unknown_subscriberinvalid_destinationPermanent
opted_outrecipient_opted_outPermanent
carrier_rejectedcontent_rejectedPermanent

A recoverable failure produces sms.undelivered. The message is still final: Bird does not retry it automatically. Reaching the recipient requires another send after the underlying problem clears.

A permanent failure produces sms.failed. An unmapped reason also produces that event with the error code unknown. That result means Bird could not classify the carrier's reason. It does not independently prove that the destination is permanently unreachable.

Can I set when the carrier stops trying?

You cannot set the carrier's delivery deadline through Bird's send endpoint.

Bird rejects any supplied validity_period with HTTP 422 SMSUnsupportedFeature. That field would control how long the carrier keeps trying to deliver the text.

The corresponding response field is not returned. Bird produces sms.expired when a carrier reports expiry. Your application cannot infer the carrier's waiting period from an absent field.

How should I handle receipts in my application?

You should track delivery outcomes separately from request acceptance and from any action the recipient takes.

Treat a message without a final delivery result as pending. Read the error code with a failure event so you can investigate its cause. Preserve unfamiliar codes in your logs because the error-code set is extensible.

Use delivered events for a delivery metric. For a passcode or confirmation flow, record success when the recipient completes the action. A delivery receipt alone cannot supply that measurement.

SMS events documents the public event payloads and message timeline.

In short

  1. Delivery does not establish reading.

    A receipt reports the network's delivery outcome without confirming that a person saw the text.

  2. Some receipts have no public event.

    Bird records buffered receipts internally without changing the public status, timeline or webhook stream.

  3. The reason determines the failure event.

    Recoverable carrier reasons produce sms.undelivered; permanent or unmapped reasons produce sms.failed.

  4. A recoverable reason does not trigger another send.

    An undelivered message is final, so another attempt requires a separate send.

Put it into practice.

Continue with the documentation, guides and examples for this topic. Resources are in English.

Get an implementation brief

Build on the same network.

A test API key is yours immediately. Production unlocks when you add a payment method and verify a sender.

Your next idea.
Ready to connect.