Delivery receipts for outbound SMS
Delivery Receipts (DR) are webhooks for delivery statuses: POST requests sent by 8x8 platform in JSON format to the delivery reports callback URL configured for your account.
Whenever a message has a new delivery status associated with the delivery stage it is in, 8x8 sends out a POST request with the new status to the callback URL.
๐
You can configure your callback using Webhooks Configuration API
You can also overwrite the default callback URL on a per-message / per-batch-of-message basis by specifying a different dlrCallbackUrl value in your API requests when sending a message or a batch of messages (see Send API)
Retry logicโ
In case of connection error/timeout or HTTP response code 4XX or 5XX, there will be multiple retry attempts with progressive intervals: 1, 10, 30, 90 sec.
Delivery Receipt - Validity Periodโ
If we do not receive a delivery receipt from the SMS carrier promptly, our platform will continue checking for up to 48 hours for a delivery receipt. If the delivery receipt is received after this 48-hour period, there will be no delivery receipt webhook sent.
Webhook formatโ
Request body description
| Parameter name | Parameter type | Description |
|---|---|---|
| namespace | string | A generic namespace for incoming webhook. Equal to SMS for delivery receipts. |
| eventType | string | Webhook type. Equals to outbound_message_status_changed for delivery receipts. |
| description | string | Human-readable description of the incoming event |
| payload | object | Delivery receipt information, see below. |
Payload object description
| Parameter name | Parameter type | Description |
|---|---|---|
| umid | uuid | A unique identifier generated by 8x8 for the message |
| batchId | uuid | A unique identifier generated by 8x8 for the message if sent using Batch API |
| clientMessageId | string | Your custom identifier for the message |
| clientBatchId | string | Client managed id for this batch of messages : your own unique reference |
| subAccountId | string | The sub-account id used to deliver the message |
| source | string | The source (i.e: sender) used to deliver the message |
| destination | string | Destination phone number where the SMS was sent (E.164 format) |
| status | object | Current status of the message, please see Message status reference for details. |
| price | object | Price information of the message, this field is optional in the response if there is no charge incurred. Please see Price object reference for details |
| smsCount | integer | Number of SMS segment in the message |
| outboundContent | object | A structured copy of the original outbound message this receipt refers to. Only present on the queued receipt sent when the message is accepted for processing โ other queued receipts (for example, scheduled messages) do not include it. See outboundContent object below. |
๐ง
Please note that the Price object is optional and might not be included in the Delivery Receipts callback. When a message was not sent successfully, you will still receive Delivery Receipts with Failed/Undelivered status without incurring any charges. Hence, the price information is not available for the Delivery Receipts.
โ๏ธ
If the request you receive has a different structure from described in this document, please contact our support to activate the latest format for your account.
outboundContent objectโ
outboundContent is a structured copy of the message you originally sent. It lets you reconcile a delivery receipt with the exact content that was sent without keeping your own copy of the outbound payload.
๐
outboundContentis attached only to thequeuedreceipt sent when the message is accepted for processing, and only when the original message body is still available. Otherqueuedreceipts โ for example, for scheduled messages โ do not include it, and it is omitted from every other status (sent,delivered,undelivered, etc.).
outboundContentalso requires delivery receipt format V7 or later. If your account is on an earlier format, contact support to activate the latest version.
| Parameter name | Parameter type | Description |
|---|---|---|
| channel | string | Channel the content was sent on. Always sms. |
| contentType | string | Kind of content. Always text โ SMS has no media, template, or interactive content types. |
| body | object | Message body text. Omitted when the content is masked (see meta). |
| meta | object | Extra flags such as redaction status. Only present when the content is masked. |
body objectโ
| Parameter name | Parameter type | Description |
|---|---|---|
| text | string | The message body text. |
meta objectโ
| Parameter name | Parameter type | Description |
|---|---|---|
| redacted | boolean | true when the content was masked. |
| redactionReason | string | Why the content was masked, e.g. Content masked for PII compliance (when PII masking is enabled for your sub-account or destination country). |
Sample delivery receipt for outbound SMSโ
{
"namespace": "SMS",
"eventType": "outbound_message_status_changed",
"description": "SMS outbound message delivery receipt",
"payload": {
"umid": "9e09ac86-bd74-5465-851d-1eb5a5fdbb9a",
"batchId": "3e09ac86-bd74-5465-851d-1eb5a5fdbb9b",
"clientMessageId": "1e09ac86-bd74-5465-851d-1eb5a5fdbb9b",
"clientBatchId": "2e09ac86-bd74-5465-851d-1eb5a5fdbb9b",
"subAccountId": "SubAccount-1",
"source": "8x8",
"destination": "+12025550293",
"status": {
"state": "undelivered",
"detail": "rejected_by_operator",
"timestamp": "2016-01-01T00:00:00Z",
"errorCode": 15,
"errorMessage": "Invalid destination"
},
"price": {
"total": 0.0375,
"perSms": 0.0125,
"currency": "USD"
},
"smsCount": 3
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<root>
<namespace>SMS</namespace>
<eventType>outbound_message_status_changed</eventType>
<description>SMS outbound message delivery receipt</description>
<payload>
<umid>9e09ac86-bd74-5465-851d-1eb5a5fdbb9a</umid>
<batchId>3e09ac86-bd74-5465-851d-1eb5a5fdbb9b</batchId>
<clientMessageId>1e09ac86-bd74-5465-851d-1eb5a5fdbb9b</clientMessageId>
<clientBatchId>2e09ac86-bd74-5465-851d-1eb5a5fdbb9b</clientBatchId>
<subAccountId>SubAccount-1</subAccountId>
<source>8x8</source>
<destination>+12025550293</destination>
<status>
<state>undelivered</state>
<detail>rejected_by_operator</detail>
<timestamp>2016-01-01T00:00:00Z</timestamp>
<errorCode>15</errorCode>
<errorMessage>Invalid destination</errorMessage>
</status>
<price>
<total>0.0375</total>
<perSms>0.0125</perSms>
<currency>USD</currency>
</price>
<smsCount>3</smsCount>
</payload>
</root>
Sample delivery receipt with outboundContentโ
This receipt has status.state of queued, so it carries the outboundContent object.
{
"namespace": "SMS",
"eventType": "outbound_message_status_changed",
"description": "SMS outbound message delivery receipt",
"payload": {
"umid": "9e09ac86-bd74-5465-851d-1eb5a5fdbb9a",
"subAccountId": "SubAccount-1",
"source": "8x8",
"destination": "+12025550199",
"status": {
"state": "queued",
"timestamp": "2026-09-17T05:54:55.72Z"
},
"price": {
"total": 0,
"perSms": 0,
"currency": "EUR"
},
"smsCount": 1,
"outboundContent": {
"channel": "sms",
"contentType": "text",
"body": {
"text": "Hello World"
}
}
}
}
Sample delivery receipt with masked outboundContentโ
When PII masking applies to the sub-account or destination country, body is omitted and meta describes the redaction instead.
{
"namespace": "SMS",
"eventType": "outbound_message_status_changed",
"description": "SMS outbound message delivery receipt",
"payload": {
"umid": "9e09ac86-bd74-5465-851d-1eb5a5fdbb9a",
"subAccountId": "SubAccount-1",
"source": "8x8",
"destination": "+12025550199",
"status": {
"state": "queued",
"timestamp": "2026-09-17T05:54:55.72Z"
},
"price": {
"total": 0,
"perSms": 0,
"currency": "EUR"
},
"smsCount": 1,
"outboundContent": {
"channel": "sms",
"contentType": "text",
"meta": {
"redacted": true,
"redactionReason": "Content masked for PII compliance"
}
}
}
}