BulkSMSRates

Delivery Reports

Track every message in real-time. Our delivery reports give you full visibility into message status from submission to final delivery — with industry-standard SMPP status codes.

How Delivery Reports Work

1

Message submitted ACCEPTD

Your message is accepted via API or SMPP and queued for delivery.

2

Sent to carrier ENROUTE

Message forwarded to the destination mobile network via our direct routes.

3

Delivered to handset DELIVRD

The recipient's phone confirms receipt. DLR sent to your webhook.

4

Or: delivery failed UNDELIV / REJECTD / EXPIRED

The carrier reports a permanent failure, rejection, or timeout.

SMPP Status Codes Explained

DELIVRDDelivered

Message successfully delivered to the handset.

UNDELIVUndeliverable

Permanent failure — number doesn't exist, is disconnected, or the carrier rejected the message.

EXPIREDExpired

Message TTL exceeded. The handset was unreachable for the entire validity period (default 48h).

REJECTDRejected

Message rejected by the carrier — spam filter, invalid sender ID, or blocked content.

ACCEPTDAccepted

Message accepted by the SMSC but not yet delivered. Intermediate status.

UNKNOWNUnknown

No delivery receipt received from the carrier within the timeout window.

DELETEDDeleted

Message was deleted by the carrier before delivery (e.g. cancel request).

ENROUTEEn Route

Message is in transit to the destination network. Will resolve to DELIVRD or UNDELIV.

Webhook Setup

Configure a webhook URL to receive delivery reports as HTTP POST requests. You can set this up via the dashboard or the API:

// Create a webhook
POST /v1/webhooks
{
  "url": "https://yourapp.com/dlr-webhook",
  "events": ["delivered", "failed", "expired", "rejected"],
  "secret": "your_webhook_secret"  // for HMAC signature verification
}
// Webhook payload (POST to your URL)
{
  "event": "delivery_report",
  "message_id": "msg_abc123",
  "to": "+447700900000",
  "from": "MyBrand",
  "status": "DELIVRD",
  "status_code": 0,
  "error_code": null,
  "error_message": null,
  "segments": 1,
  "submitted_at": "2024-01-15T10:29:55Z",
  "delivered_at": "2024-01-15T10:30:00Z",
  "network": "EE",
  "country": "GB"
}

// Signature header for verification:
// X-BSR-Signature: sha256=<HMAC of body using your webhook secret>

Real-time vs Batched Reports

FeatureReal-timeBatched
DeliveryInstant (< 1 second)Every 1/5/15/60 minutes
FormatSingle JSON per eventArray of events
Best forTransactional SMS, OTPsBulk campaigns, reporting
Webhook loadHigher (many small POSTs)Lower (fewer large POSTs)
Retry on failure3 retries with backoff3 retries with backoff
SetupDefault — no config neededSet batch_interval in webhook config

Troubleshooting Common Issues

Not receiving webhooks

Verify your URL is publicly accessible, returns 200 OK, and responds within 10 seconds. Check firewall rules. Test with the dashboard webhook tester.

High UNDELIV rate

Clean your number list — remove invalid, disconnected, and landline numbers. Use our number validation API to verify numbers before sending.

Many EXPIRED messages

Recipients' phones may be off. Consider time-of-day scheduling. Check if you're sending to prepaid numbers that may be out of credit.

UNKNOWN status

Some carriers don't return final DLRs. This is more common on indirect routes. Upgrade to direct routes for better DLR rates.

REJECTD messages

Check your sender ID is registered for the destination country. Verify message content doesn't contain blocked keywords. Review carrier-specific content policies.

Frequently Asked Questions