Delivery Reports
Overview
FutureSMS pushes status callbacks to the merchant-provided dlr_address when an SMS order gains its first durable message status and whenever that status later changes. This page documents the callback contract for merchant implementers.
Endpoint
POST {merchant dlr_address}
This is a documentation-only contract template. It is not a FutureSMS inbound runtime route.
Before You Begin
Provide a public HTTPS callback URL either through your account setup or through the order-level dlr_address on Send SMS.
FutureSMS chooses the callback target in this order:
- The order-level
dlr_address, when the send request provides one. - The merchant-level DLR address configured for the account.
- No callback is pushed when no DLR address is available.
Callback URLs must be public callback URLs. Private or local network targets are rejected by request validation or skipped by callback safety checks.
Request fields
| Field | Type | Required | Meaning |
|---|---|---|---|
order_id | string | Yes | FutureSMS order identifier. |
client_order_id | string or null | No | Merchant-side reference, when provided on the order. |
message_status | enum | Yes | Normalized delivery status. |
phone_number | string | Yes | Destination phone number. |
sender_value | string | Yes | Sender display value used for the message. |
reported_at | date-time | Yes | Time the delivery report was reported. |
Response fields
Return 200 with a small JSON body after accepting the callback.
{
"status": "ok"
}
Callback lifecycle
The order is created in pending without a callback. Callback delivery begins when FutureSMS persists the first message_status, including outcomes such as ACCEPTD, REJECTD, or UNKNOWN. Each later effective status transition produces another callback. A typical successful sequence is:
pending (no callback) -> ACCEPTD -> ENROUTE -> DELIVRD
This means one order can produce several callback requests. Use order_id as the stable key and overwrite the stored current status with each newer callback. reported_at identifies when that callback status was recorded. Duplicate events that do not change the canonical status do not create a new transition callback, and obsolete retries are suppressed so an older transition does not replace a newer one.
Status callbacks are not limited to successful delivery. Effective failure, rejection, expiry, deletion, undeliverable, read, and other normalized transitions are pushed in the same way.
Treat callback transport as at-least-once delivery because a network retry can repeat the same transition. Store order_id, client_order_id, and reported_at so your receiver can process repeated requests safely.
Later provider reports must match the original order before they can change its canonical status. An unmatched provider report cannot produce a merchant callback.
Attempts and retry policy
The initial callback push counts as attempt 1. By default, FutureSMS makes up to 3 total attempts for the same delivery report callback.
FutureSMS schedules a retry only when the merchant endpoint returns 503 Service Unavailable, or when the callback attempt fails because of a network error or timeout. The default retry delay uses exponential backoff: about 60 seconds before the second attempt, about 120 seconds before the third attempt, capped at 900 seconds for deployments that use more attempts.
200 stops the retry cycle as accepted. 4xx responses and non-503 5xx responses are treated as terminal callback failures and are not automatically retried.
Retry timing is approximate. The actual callback push may run slightly later than the scheduled delay.
Status codes
| Merchant response | Meaning |
|---|---|
200 | Callback accepted by the merchant receiver. |
4xx | Callback was not accepted. Treat 4xx responses as an integration issue to investigate. FutureSMS does not automatically retry them. |
503 | Temporary merchant receiver unavailability. FutureSMS retries it according to the callback retry policy. |
Other 5xx | Callback failed, but FutureSMS does not automatically retry it unless the platform policy is changed. |
| Timeout or network error | No durable acknowledgement was received. FutureSMS retries it according to the callback retry policy. |
Examples
{
"order_id": "SDPS260405180908FE6GZZC",
"client_order_id": "client-ord-20260405-0001",
"message_status": "ENROUTE",
"phone_number": "+639171234567",
"sender_value": "FutureSMS",
"reported_at": "2026-04-05T18:10:00Z"
}
{
"status": "error"
}