API Error Code Reference
Complete reference for HTTP status codes, API error codes, and SMS delivery statuses. Understand every error your integration may encounter and how to handle it correctly.
4xx Client Error Codes
These errors result from issues with the request itself — invalid parameters, missing authentication, or permission problems. They are not retryable without fixing the underlying request.
BAD_REQUESTThe request could not be understood or was missing required parameters. Check your JSON structure.NoUNAUTHORIZEDAPI key is missing, invalid, or expired. Check the Authorization header and your API key validity.NoFORBIDDENYour API key does not have permission to perform this action. Check key scopes in the portal.NoNOT_FOUNDThe requested resource (e.g., message ID) does not exist or is not accessible to your account.NoVALIDATION_ERRORRequest structure is valid but contains invalid values. See the errors array for field-level detail.NoRATE_LIMITEDToo many requests. Apply exponential backoff and check the Retry-After header for guidance.Yes5xx Server Error Codes
These errors indicate a platform-side problem. They are typically transient and retryable with exponential backoff. Include the requestId when contacting support.
INTERNAL_ERRORUnexpected platform error. Retry with exponential backoff. If persistent, contact support with the requestId.YesBAD_GATEWAYUpstream carrier or routing error. Retry after a brief delay. Typically transient.YesSERVICE_UNAVAILABLEPlatform temporarily unavailable due to maintenance or overload. Check the status page and retry.YesGATEWAY_TIMEOUTRequest timed out. Retry after exponential backoff. The message may or may not have been submitted.YesSMS Delivery Status Codes
Delivery status codes are returned in webhook delivery receipts and message status polling responses. Understand each status to build correct application logic.
DELIVEREDThe message was successfully delivered to the recipient's handset. This is a final, positive status — no further action needed.
FAILEDThe message could not be delivered due to a carrier or network error. Common causes include the number being unreachable, invalid, or barred.
EXPIREDThe message was not delivered within the validity period (typically 48 hours). The recipient's phone may have been off or out of coverage for an extended period.
UNDELIVERABLEThe number is permanently undeliverable — invalid number, non-existent, or blocked. Distinct from FAILED in that retrying will not succeed.
PENDINGThe message has been queued or is in transit. This is an intermediate status — it will resolve to DELIVERED, FAILED, EXPIRED, or UNDELIVERABLE.
QUEUEDThe message has been accepted by the platform and is queued for submission to a carrier. Typically transitions to PENDING within seconds.
Common Validation Error Codes
When a 422 Unprocessable response is returned, the errors array contains field-level detail. Here are the most common field-level error codes.
toINVALID_NUMBERNot a valid E.164 phone number formattoINVALID_COUNTRYCountry not supported or blockedfromINVALID_SENDER_IDSender ID not permitted or malformedtextMESSAGE_TOO_LONGMessage exceeds maximum length for typetextEMPTY_MESSAGEMessage body is empty or whitespace onlytypeINVALID_TYPEMessage type not one of: sms, otp, flashError Handling Best Practices
A well-implemented error handling strategy ensures your integration is resilient to transient issues and responds correctly to permanent errors.
- Always include requestId in support requestsThe requestId field in error responses uniquely identifies the request and allows our team to investigate quickly.
- Distinguish retryable from non-retryable errors4xx errors (except 429) indicate a problem with your request — fix before retrying. 5xx and 429 are retryable.
- Implement exponential backoff with jitterOn retryable errors, wait progressively longer between attempts. Add random jitter to prevent thundering herd.
- Log all error responsesLog HTTP status, errorCode, requestId, and timestamp. This data is essential for diagnosing integration issues.
- Handle delivery failures in your applicationFAILED and UNDELIVERABLE delivery receipts should trigger application-level logic — fallback channels, user notification, or retry policies.
import time
import random
import requests
def send_with_retry(payload, api_key,
max_retries=3):
retryable = {429, 500, 502, 503, 504}
delay = 1.0
for attempt in range(max_retries + 1):
r = requests.post(
'https://api.sbstelecom.co.uk'
'/v1/messages',
headers={
'Authorization': f'Bearer {api_key}'
},
json=payload,
timeout=10
)
if r.status_code < 400:
return r.json()
if r.status_code not in retryable:
# Non-retryable — raise immediately
r.raise_for_status()
if attempt < max_retries:
# Exponential backoff with jitter
jitter = random.uniform(0, delay * 0.2)
time.sleep(delay + jitter)
delay = min(delay * 2, 60)
r.raise_for_status()Questions About a Specific Error?.
Our technical support team can help diagnose any integration issue. Include the requestId from the error response for fastest resolution.