When to Use MDRs
Delivery Tracking
Check if a message was delivered, failed, or is still in progress.
Debugging
Investigate delivery issues by examining message status and error codes.
Cost Verification
Confirm message costs after delivery for billing reconciliation.
Audit Trail
Retrieve message history for compliance and record-keeping.
Retrieve an MDR
Fetch a message record using its UUID. The UUID is returned when you send a message and is also included in webhook events.Example Response
MDR Schema
| Field | Type | Description |
|---|---|---|
id | UUID | Unique identifier for the message request |
direction | string | inbound or outbound |
type | string | Message type: SMS, MMS, or RCS |
messaging_profile_id | UUID | The messaging profile used to send/receive |
from | object | Sender details including phone_number, carrier, line_type |
to | array | Recipients with phone_number, status, updated_at |
text | string | Message body content |
media_urls | array | Media attachment URLs (MMS only) |
encoding | string | Character encoding: GSM-7 or UCS-2 |
parts | integer | Number of message segments |
cost | object | amount and currency (may be null until finalized) |
errors | array | Error details if delivery failed |
webhook_url | string | URL for delivery status webhooks |
webhook_failover_url | string | Backup webhook URL |
use_profile_webhooks | boolean | Whether to use profile-level webhooks |
created_at | ISO 8601 | When the message was submitted |
updated_at | ISO 8601 | Last status update time |
valid_until | ISO 8601 | Expiration time for pending messages |
Cost may be null: When retrieved immediately after sending,
cost may be null because pricing is calculated asynchronously. The final cost appears in the message.finalized webhook event.Message Status
Thestatus field in the to array indicates where the message is in its lifecycle.
Outbound Status Flow
Outbound Statuses
| Status | Description | Final? |
|---|---|---|
queued | Message accepted and queued for sending | No |
sent | Delivered to carrier gateway | No |
delivered | Carrier confirmed delivery to handset | ✓ Yes |
failed | Delivery failed (see errors array) | ✓ Yes |
gw_timeout | No response from gateway | ✓ Yes |
dlr_timeout | No delivery receipt from carrier | ✓ Yes |
Track delivery with webhooks: Rather than polling for status, configure a webhook URL to receive real-time status updates as
message.sent, message.delivered, or message.finalized events.Inbound Statuses
| Status | Description |
|---|---|
received | Message received by Telnyx |
delivered | Message delivered to your webhook |
Common Error Codes
When a message fails, theerrors array contains details:
| Error Code | Description | Resolution |
|---|---|---|
40300 | Invalid destination | Verify the phone number format |
40301 | Destination blocked | Recipient has opted out—remove from list |
40310 | Carrier rejected | Message content may have triggered spam filters |
40311 | Undeliverable | Number is unreachable (landline, disconnected) |
40400 | Sender not registered | Register for 10DLC or toll-free verification |
40500 | Rate limit exceeded | Slow down sending or request higher limits |
Best Practices
Use webhooks instead of polling
Use webhooks instead of polling
Polling the MDR endpoint is inefficient and can hit rate limits. Instead, configure webhooks on your Messaging Profile to receive real-time updates:
message.sent— Message accepted by carriermessage.delivered— Confirmed deliverymessage.finalized— Final status with cost
Store message IDs for tracking
Store message IDs for tracking
Save the
id returned when you send a message. This UUID is required to retrieve the MDR later:Handle cost being null
Handle cost being null
The
cost field is populated asynchronously. For accurate billing:- Wait for the
message.finalizedwebhook, OR - Retrieve the MDR after a few seconds
Troubleshooting
MDR not found (404)
MDR not found (404)
Possible causes:
- Invalid message ID format
- Message ID from a different account
- Message was never created (request was rejected at validation)
201 status. Rejected requests don’t create MDRs.Status stuck on 'queued'
Status stuck on 'queued'
Possible causes:
- Message is rate-limited and waiting in queue
- Gateway connection issue
valid_until will fail.Cost shows null
Cost shows null
Cause: Cost is calculated asynchronously after the message is sent.Solution: Either wait for the
message.finalized webhook, or retrieve the MDR again after 5-10 seconds.