123eworld Knowledge Hub → SMS API → Page 308
SMS API Message Status Tracking: Queues, Submitted, Delivered and Failed States
A practical developer reference designed to solve real implementation and production problems around sms api message status tracking: queues, submitted, delivered and failed states.
Why state tracking is necessary
Messaging is asynchronous. A robust state machine prevents developers and support teams from treating API acceptance, provider submission and final delivery as the same event.
Accepted
Accepted means the platform validated the request and created a logical message. It does not necessarily mean a provider has received it.
Queued
Queued means work is waiting for processing. Queue age can be an important operational metric.
Submitted
Submitted means a provider accepted the submission or the platform has sufficient evidence of provider acceptance, according to the documented contract.
Delivered
Delivered should be reserved for a receipt or evidence meeting the platform's delivery definition.
Failed
Failed should represent a terminal outcome when no further automatic attempt is expected. Internal diagnostics should identify the reason.
Expired
Expiry is useful when a message remains pending beyond its business relevance or delivery window.
Unknown
Unknown is preferable to inventing certainty. It can represent missing, conflicting or unrecognized evidence.
Transitions
State transitions should be explicit and testable. A late receipt should not arbitrarily move a terminal message backward without defined reconciliation rules.
Current state and history
Maintain an efficient current-state representation plus immutable transition history.
Client synchronization
Expose webhooks and status APIs using the same logical state vocabulary.
Testing
Test provider timeout, duplicate submission evidence, late delivery, failover and worker crashes.
Practical implementation guidance
Design the public API around a stable logical message ID and keep provider-specific complexity behind internal adapters. Every asynchronous step should be durable, observable and safe to retry.
Security and privacy
Treat phone numbers, message content, credentials and delivery evidence as sensitive. Apply tenant authorization before data access and avoid unnecessary values in logs, traces and reports.
Developer-first principle
A useful reference page should tell developers not only what a feature is, but how to implement it safely, how to troubleshoot it and what failure cases to expect.
Related 123eworld guides
Explore the 123eworld SMS & WhatsApp Knowledge Hub for related API, routing, reliability and developer guides.
State-machine contract
Write the state machine before implementing workers. For every state, define entry conditions, allowed transitions, terminal conditions and customer-facing meaning. This prevents different services from inventing their own interpretation.
Queue state versus delivery state
Queue state describes where work is in the platform; delivery state describes the messaging outcome. A message can leave the queue while still being pending at the provider. Keep these dimensions separate internally.
Retry state
A message may have an active retry attempt while its logical status remains pending. Record retry count and next-attempt time separately from the customer-facing delivery status.
Failover state
Failover should create a new provider attempt without creating a new logical message. This distinction is essential for reporting and duplicate analysis.
Late evidence
When a receipt arrives after a timeout, reconcile it against the existing attempt. Do not assume the timeout proved that the provider did not receive the message.
Status API
The status endpoint should return current state, timestamps, message ID and safe diagnostic information. It should not expose internal queue mechanics unless those are part of the public contract.
Webhook consistency
Webhook events and status API responses should use the same canonical status values. If they differ, developers are forced to maintain two state machines.
Terminal-state protection
Terminal states should have controlled transitions. An unexpected backward transition should generate an internal anomaly rather than silently changing the customer-facing state.
Historical state
Store transitions with event timestamps and source. This allows support to reconstruct how the final state was reached.
Testing
Test every allowed transition and explicitly test every forbidden transition. State-machine tests are especially valuable when several workers update the same message.
Concurrency control
State updates can come from API workers, provider callbacks, polling jobs and reconciliation processes. Use version checks or atomic transition rules so two updates do not overwrite each other silently.
Business state versus evidence
A message state is an interpretation of evidence. Keep the evidence separate so a future correction to a provider mapping can recompute or explain the interpretation.
Terminal state policy
Define what happens when a terminal state receives new evidence. For example, a late failure after delivery may indicate conflicting provider data and should be investigated rather than automatically reversing a delivered business outcome.
State metrics
Track how long messages spend in accepted, queued and submitted states. Long dwell time at one state often identifies the exact layer that needs capacity or routing work.
Client expectations
Document each public status precisely. For example, accepted should not be presented as delivered. This small wording decision prevents business applications from triggering downstream actions too early.
Polling versus webhooks
Webhooks are efficient for event-driven applications, while polling can be useful for simple integrations or recovery. Both should return the same logical status vocabulary.
Status freshness
A status response can include last-updated time so customers know how fresh the information is. This is especially useful when provider receipts are delayed.
Reconciliation state
An internal 'reconciliation required' condition can help isolate uncertain outcomes without exposing unnecessary internal complexity in the public API.
Status API troubleshooting
If customers report that status is stuck, compare the current state with the latest event timestamp, queue state, provider attempt and webhook delivery state. This quickly separates a genuine delivery delay from a reporting or webhook problem.
Reference principle
A status API should answer 'what is the current known state?' while event history answers 'why do we believe it?' Both are necessary for a trustworthy messaging platform.
Advanced production guidance
A mature status system should expose enough timestamps to diagnose delay: message creation time, queue admission time, provider submission time, latest evidence time and last state-change time where appropriate. These timestamps should have clear definitions. For example, 'submitted' should not be timestamped when a worker merely starts an HTTP request; it should reflect the documented evidence that the provider accepted the request. Similarly, 'delivered' should be based on the delivery evidence received by the platform. Clear timestamp semantics make SLA calculations and customer support much more reliable. They also allow engineers to identify whether a delay occurred before provider submission, inside the provider route or during receipt processing.
Reference architecture detail
For application developers, the status lifecycle should be simple even if the internal implementation is complex. They should not need to understand queue partitions, provider attempts or reconciliation workers to know whether a message is accepted, pending, delivered or failed. The platform can expose a concise public state model while retaining detailed internal evidence. Documentation should show examples of each state and explain which state transitions can take time. This is particularly important for OTP, banking and transactional applications where developers may otherwise incorrectly trigger a second notification while the first message is still pending.
Final production checklist
A status-state implementation should be documented as a contract between services. API workers, queue processors, receipt handlers and reconciliation jobs should all use the same transition rules. Centralizing these rules prevents a late callback from being interpreted differently depending on which worker processed it.
Advanced reference note
For a production integration, the most useful status documentation includes a small state-transition table and concrete examples. Show what the API returns immediately after acceptance, what a webhook looks like after submission and what the final response looks like after delivery. Also explain that state changes are asynchronous and that clients should not assume a fixed delay. This prevents polling loops that are too aggressive and prevents business applications from treating an intermediate state as a terminal result. The status API should remain the authoritative current-state view, while webhook events provide efficient change notifications.
Final reference guidance
Keep status terminology consistent across the API, dashboard, webhook payloads and documentation. Small wording differences such as 'complete', 'delivered' and 'successful' can lead developers to implement different business assumptions. A canonical vocabulary is therefore a reliability feature, not just a documentation preference.