123eworld Knowledge Hub → Transactional SMS → Page 178
Transactional SMS API Error Handling: HTTP Status Codes, Error Codes, Retryable Failures and Debugging
Developer reference for designing consistent SMS API errors, HTTP status codes, retryable failures, validation errors, provider errors and diagnostics.
Why errors need a contract
An API error is part of the developer interface. A generic 500 response forces customers to guess whether they should retry, correct the request or contact support. A good error contract separates HTTP semantics from stable machine-readable business codes.
HTTP status codes
Use 4xx responses for problems attributable to the request or authorization and 5xx responses for server-side or dependency failures. Do not use 200 with an error hidden inside the response simply to avoid handling HTTP errors.
Machine-readable codes
Define stable error codes such as invalid_destination, insufficient_credit, rate_limited or provider_unavailable. Messages can change for clarity, but codes should remain compatible.
Retryable failures
A timeout or temporary provider failure may be retryable, while an invalid phone number is not. The API can expose retry guidance without forcing every client to understand provider-specific codes.
Validation errors
For structured validation failures, return field-level information where safe. The client should know whether the sender, destination, template ID or variable is invalid.
Provider errors
Normalize provider responses into platform-level categories. Retain raw provider evidence internally so support can investigate without exposing unstable provider terminology.
Rate limits
Return a clear rate-limit error and, where appropriate, retry timing information. Clients should not respond to throttling by immediately retrying in a tight loop.
Correlation IDs
Every request should have a correlation or request ID. Return it to the customer and include it in internal logs so support can trace the operation without searching by sensitive message content.
Security
Error messages should not expose credentials, internal hostnames, stack traces or another tenant's data. Detailed diagnostics belong in protected internal telemetry.
Testing
Test malformed JSON, missing fields, invalid authentication, forbidden scopes, rate limiting, provider timeouts and unexpected internal failures.
Operational checklist
Document HTTP codes, error schema, stable codes, retryability, correlation IDs, field errors and security restrictions.
Developer takeaway
Predictable errors reduce integration failures. The error contract should tell developers what happened, what they can fix and whether retrying is appropriate.
Error envelope
A consistent error envelope might contain an error code, human-readable message, request ID and optional field details. The structure should remain stable across endpoints so SDKs can parse errors uniformly. Do not place provider stack traces or database messages in the customer-facing envelope.
Retry guidance
Retryability can be represented by a stable error category or documented table. A 503 commonly indicates temporary service unavailability, while a 400 validation error normally requires correction. Some 4xx responses such as rate limiting are also retryable after an appropriate delay.
Unknown errors
If the server encounters an unexpected condition, return a generic internal error and a request ID. Internal telemetry should capture the real exception and dependency context. This prevents information leakage while still giving support enough evidence to investigate.
Provider timeout
A provider timeout is especially important because the final submission state may be uncertain. The API should not automatically tell the customer that the SMS was definitely not sent. Instead, the logical message can enter a processing or uncertain state while reconciliation determines the outcome.
Field errors
For JSON payloads, return a list of invalid fields where practical. Each item should have a stable field path and code. This allows SDKs and web applications to highlight the exact problem without parsing English text.
Compatibility
Adding an optional error field is normally safer than changing the meaning of an existing field. Error-code documentation should identify whether clients may safely retry, correct input or contact support.
Final reference
A good error contract reduces support load because developers can determine the next action directly from the response.
Error taxonomy
A useful taxonomy separates client validation, authentication, authorization, quota, rate limiting, dependency failure, timeout and internal failure. This taxonomy should be shared by APIs, SDKs and support tooling.
Request IDs
The request ID should be returned even for errors generated before a message ID exists. This gives support a stable reference for authentication and validation failures as well as successful requests.
Provider uncertainty
If a provider times out after accepting a request, classify the outcome as uncertain rather than failed unless evidence exists. This prevents automated clients from immediately sending a duplicate.
Documentation
Each documented error should include what caused it, whether it is retryable, what the client should change and whether support may need the request ID. Avoid documentation that merely lists numeric codes without action.
Alerting
Aggregate errors by stable code and provider route. A sudden increase in one normalized provider-unavailable code can be more useful than monitoring hundreds of raw provider strings.
Final safeguard
The error model should be stable enough for software and descriptive enough for humans. That combination is what makes an API supportable at scale.
Advanced production guidance
Support teams need a practical error-debugging workflow. Start with the request ID, identify the normalized error code, determine whether the failure happened before or after logical message creation, and then inspect provider evidence if applicable. This workflow is much faster than asking a customer to resend the same message repeatedly. Error codes should therefore remain stable across deployments. If an internal implementation changes but the customer-facing condition is still the same, the public code should normally remain unchanged.
Reference architecture note
Error responses should be tested as carefully as successful responses. Contract tests should verify HTTP status, error code, request ID and retry guidance. A backend refactor that accidentally changes a 429 into a 500 can cause thousands of customer applications to behave incorrectly. Treat the error contract as a public API surface and include it in release testing.
Implementation detail
When a provider introduces a new error code, the adapter should map it to a normalized category before it reaches customer applications. Unknown provider errors should be retained as raw evidence and placed into a safe fallback category. This prevents a provider-specific change from forcing every customer to update its integration immediately. The mapping table should be versioned and tested with representative provider responses.
Operational reference
Error-rate dashboards should distinguish customer-correctable errors from platform failures. A spike in invalid destinations may indicate a customer data problem and should not page the platform operations team in the same way as a provider outage. This classification makes incident response more focused and prevents alert fatigue.
Final engineering guidance
A stable error code should have a clear owner and documentation entry. When an error is no longer used, retain historical documentation long enough for customers investigating old incidents to understand it. Support tooling can translate old codes into current categories while preserving the original evidence. This makes incident investigations more reliable after API versions and provider adapters evolve.
Knowledge-base guidance
Support should be able to map a customer request ID to the error, logical message and provider attempt when one exists. This makes the error model operationally useful. A developer can report one request ID instead of sending sensitive message content or screenshots. Correlation should work even when the error occurs before message creation.
Production reference
The API should avoid encouraging clients to retry every 5xx response immediately. Some failures are temporary, but aggressive retries can amplify an outage. Documentation and SDKs should use bounded backoff and preserve idempotency for submission operations. During a major incident, this can be the difference between gradual recovery and a retry storm that keeps dependencies overloaded.
Closing engineering guidance
Error documentation should also explain uncertain outcomes. A timeout is not always equivalent to failure, particularly for provider submission. Customers should be directed to message status or reconciliation rather than told to resend automatically. This distinction is critical for transactional notifications because a duplicate may have greater business impact than a short delay.
Continue through the 123eworld Knowledge Hub
Explore the complete 123eworld Knowledge Hub for practical SMS API, transactional messaging and developer architecture guides.
Visit 123eworld.com for messaging and digital communication services.