# Status callbacks and delivery receipts

DIDWW reports the result of each outbound message to the **Callback URL** of
your HTTP OUT trunk. A status callback reports how DIDWW processed the
message. A delivery receipt (DLR) event reports the final delivery status
from the carrier.

## Processing status and delivery status

A message passes through three stages, and each stage has its own result:

| Stage | Reported by | Result |
| --- | --- | --- |
| Submission | The API response | `201 Created` with the message ID. DIDWW accepted the message for processing. |
| Processing | The message status callback | `Success`, `Routing error`, or `Failed`, with a `code_id` when processing fails. |
| Delivery | The DLR event callback | The final carrier status, for example `DELIVERED`, `FAILED`, or `EXPIRED`. |

A `Success` processing status means that DIDWW sent the message to the
carrier. It does not confirm that the recipient received it. To receive the
final delivery status, enable DLR events.

```
        %%{init: {
  "theme": "base",
  "themeVariables": {
    "fontSize": "14px",
    "actorBkg": "#e0f2fe",
    "actorBorder": "#38bdf8",
    "actorTextColor": "#1f2d3d",
    "actorLineColor": "#38bdf8",
    "signalColor": "#0f766e",
    "signalTextColor": "#1f2d3d",
    "labelBoxBkgColor": "#ccfbf1",
    "labelBoxBorderColor": "#14b8a6",
    "labelTextColor": "#1f2d3d",
    "noteBkgColor": "#fef3c7",
    "noteBorderColor": "#f59e0b",
    "noteTextColor": "#1f2d3d",
    "sequenceNumberColor": "#ffffff"
  }
}}%%

sequenceDiagram
   autonumber
   participant app as Your application
   participant didww as DIDWW
   participant carrier as Carrier
   participant callback as Your Callback URL

   app->>didww: POST /outbound_messages
   didww-->>app: 201 Created with message ID
   didww->>carrier: Route the message
   didww->>callback: Message status callback
   carrier-->>didww: Delivery receipt
   didww->>callback: DLR event callback, when enabled
```

## Callback configuration

Set the **Callback URL** in the [General
settings](../sms-trunks/http-out/http-out-trunk-settings-reference.html#user-panel-sms-http-out-general-settings) of
your HTTP OUT trunk. DIDWW
posts the status callbacks for every message sent through the trunk to this
URL.

DIDWW sends each callback as an HTTP `POST` request with the
`Content-Type: application/vnd.api+json` and `User-Agent: DIDWW` headers.
The body is a [JSON:API](https://jsonapi.org/format/) document.

Configure your firewall to allow requests from the DIDWW callback IP
ranges:

- **IPv4:** `46.19.208.0/21`, `185.238.173.74/32`
- **IPv6:** `2a01:ad00::/32`

## Callback and delivery receipt payloads

### Message status callback

Sent as soon as DIDWW finishes processing an outbound message, whether the
message was sent to the carrier or failed.

**Payload example:**

```
 1{
 2  "data": {
 3    "type": "outbound_message_callbacks",
 4    "id": "550e8400-e29b-41d4-a716-446655440000",
 5    "attributes": {
 6      "time_start": "2025-08-12T12:24:30.45Z",
 7      "end_time": "2025-08-12T12:24:31.15Z",
 8      "source": "12125551234",
 9      "destination": "15551234567",
10      "status": "Success",
11      "code_id": null,
12      "fragments_sent": 1,
13      "price": 0.0075
14    }
15  }
16}
```

**Attributes:**

| Attribute | Description |
| --- | --- |
| `id` | The ID of the outbound message. It matches the `id` returned when the message was submitted. |
| `time_start` | The time message routing started ([ISO 8601](https://tools.ietf.org/html/rfc3339#section-5.6)). |
| `end_time` | The time message processing finished ([ISO 8601](https://tools.ietf.org/html/rfc3339#section-5.6)). |
| `source` | The sender of the message. `null` when the request did not include `source` and DIDWW did not select a Sender ID. |
| `destination` | The recipient's number. |
| `status` | The processing status: `Success`, `Routing error`, or `Failed`. |
| `fragments_sent` | The number of fragments sent. `0` when the message was not sent. See [Fragment billing](../sms-trunks/technical-data/sms-encoding-reference.html#sms-encoding-billing). |
| `price` | The charge for the message, for all fragments sent. `0.0` when the message was not sent. |
| `code_id` | The error code if the status is not `Success`. `null` when the message was processed successfully. See [Callback error codes](outbound-sms-errors-and-status-codes.html#callback-error-codes-http). |

### DLR event callback

Sent with the final delivery status from the carrier, for example
`DELIVERED`, `FAILED`, or `EXPIRED`.

Note

To enable DLR event notifications, contact [support@didww.com](mailto:support%40didww.com).

**Payload example:**

```
 1{
 2  "data": {
 3    "type": "dlr_event",
 4    "id": "550e8400-e29b-41d4-a716-446655440000",
 5    "attributes": {
 6      "status": "DELIVERED",
 7      "time_start": "2025-08-12T12:24:32.00Z"
 8    }
 9  }
10}
```

**Attributes:**

| Attribute | Description |
| --- | --- |
| `id` | The ID of the related outbound message. It matches the `id` of the corresponding `outbound_message_callbacks`. |
| `status` | The final carrier status, for example `DELIVERED`, `FAILED`, or `EXPIRED`. See [Delivery receipt status values](outbound-sms-errors-and-status-codes.html#outbound-sms-dlr-status-values). |
| `time_start` | The time the DLR event was generated ([ISO 8601](https://tools.ietf.org/html/rfc3339#section-5.6)). |

### Callback examples

*Single SMS callback*

If you configure callbacks for your endpoint, the following attributes
are returned for each outbound SMS. In some cases, a [DLR event
callback](#callback-dlr-event) may also be sent with additional status
information.

| Unique ID | Time Start | Time End | Source | Destination | Status | Fragments Sent | Price |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 83950010-3954-43a6-8419-c1417807672f | 2023-04-11 09:07:35 | 2023-04-11 09:07:35 | 12125551234 | 15551234567 | Success | 5 | 0.0375 |


*Bulk SMS callback*

When sending bulk SMS, you receive a callback for every destination
number with a unique ID. A [DLR event callback](#callback-dlr-event) may also be sent with final delivery details.

| Unique ID | Time Start | Time End | Source | Destination | Status | Fragments Sent | Price |
| --- | --- | --- | --- | --- | --- | --- | --- |
| dc38aa6b-c454-438f-9761-e3bdea13bee0 | 2023-04-11 09:14:30 | 2023-04-11 09:14:31 | 12125551234 | 15551234568 | Success | 1 | 0.0075 |
| 8075cec0-9fb9-41b6-8580-dabbbb41f0e9 | 2023-04-11 09:14:30 | 2023-04-11 09:14:31 | 12125551234 | 15551234567 | Success | 1 | 0.0075 |

## Delivery behavior and constraints

If your callback endpoint returns a non-`2xx` HTTP response or does not
respond within 60 seconds, DIDWW retries the callback up to 9 more times:

| Callback attempt | Wait interval |
| --- | --- |
| 2 | 1 minute |
| 3 | 10 minutes |
| 4 | 30 minutes |
| 5 | 1 hour |
| 6 | 3 hours |
| 7 | 6 hours |
| 8 | 12 hours |
| 9 | 1 day |
| 10 | 2 days |

Use the message `id` to match callbacks to your messages, and make your
callback handler accept repeated callbacks for the same message.

## Related resources

- [Outbound SMS errors and status codes](outbound-sms-errors-and-status-codes.html) - Look up processing error
  codes and delivery receipt statuses.
- [Outbound SMS API reference](outbound-sms-api-reference.html) - Review requests, responses, and limits.
- [HTTP OUT trunk settings reference](../sms-trunks/http-out/http-out-trunk-settings-reference.html) - Review
  the Callback URL and other HTTP OUT trunk settings.
- [Outbound SMS logs](../../logs-analytics/sms-logs/outbound-logs.html#outbound-logs) - Review sent messages, their
  status, and their charges.
