SBS TELECOM — 20 years of Tier-1 SMS termination and enterprise messaging excellence.Explore Solutions
S
SBS TELECOMEnterprise Telecom
Error Codes

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.

Client Errors

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.

HTTPStatusError CodeDescriptionRetry
400Bad RequestBAD_REQUESTThe request could not be understood or was missing required parameters. Check your JSON structure.No
401UnauthorizedUNAUTHORIZEDAPI key is missing, invalid, or expired. Check the Authorization header and your API key validity.No
403ForbiddenFORBIDDENYour API key does not have permission to perform this action. Check key scopes in the portal.No
404Not FoundNOT_FOUNDThe requested resource (e.g., message ID) does not exist or is not accessible to your account.No
422UnprocessableVALIDATION_ERRORRequest structure is valid but contains invalid values. See the errors array for field-level detail.No
429Rate LimitedRATE_LIMITEDToo many requests. Apply exponential backoff and check the Retry-After header for guidance.Yes
Server Errors

5xx 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.

HTTPStatusError CodeDescriptionRetry
500Server ErrorINTERNAL_ERRORUnexpected platform error. Retry with exponential backoff. If persistent, contact support with the requestId.Yes
502Bad GatewayBAD_GATEWAYUpstream carrier or routing error. Retry after a brief delay. Typically transient.Yes
503Service UnavailableSERVICE_UNAVAILABLEPlatform temporarily unavailable due to maintenance or overload. Check the status page and retry.Yes
504Gateway TimeoutGATEWAY_TIMEOUTRequest timed out. Retry after exponential backoff. The message may or may not have been submitted.Yes
Delivery Statuses

SMS 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.

DELIVERED

The message was successfully delivered to the recipient's handset. This is a final, positive status — no further action needed.

Recommended action: No action required. Log for reporting.
FAILED

The message could not be delivered due to a carrier or network error. Common causes include the number being unreachable, invalid, or barred.

Recommended action: Check errorCode for detail. Optionally trigger alternative channel (e.g., voice fallback).
EXPIRED

The 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.

Recommended action: For time-sensitive use cases, consider shorter validity and retry logic.
UNDELIVERABLE

The number is permanently undeliverable — invalid number, non-existent, or blocked. Distinct from FAILED in that retrying will not succeed.

Recommended action: Remove the number from your contact list. Do not retry.
PENDING

The message has been queued or is in transit. This is an intermediate status — it will resolve to DELIVERED, FAILED, EXPIRED, or UNDELIVERABLE.

Recommended action: Await final status via webhook. Do not resend.
QUEUED

The message has been accepted by the platform and is queued for submission to a carrier. Typically transitions to PENDING within seconds.

Recommended action: Await further status updates via webhook.
Validation

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.

FieldError CodeDescription
toINVALID_NUMBERNot a valid E.164 phone number format
toINVALID_COUNTRYCountry not supported or blocked
fromINVALID_SENDER_IDSender ID not permitted or malformed
textMESSAGE_TOO_LONGMessage exceeds maximum length for type
textEMPTY_MESSAGEMessage body is empty or whitespace only
typeINVALID_TYPEMessage type not one of: sms, otp, flash
Best Practices

Error 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 requests
    The requestId field in error responses uniquely identifies the request and allows our team to investigate quickly.
  • Distinguish retryable from non-retryable errors
    4xx errors (except 429) indicate a problem with your request — fix before retrying. 5xx and 429 are retryable.
  • Implement exponential backoff with jitter
    On retryable errors, wait progressively longer between attempts. Add random jitter to prevent thundering herd.
  • Log all error responses
    Log HTTP status, errorCode, requestId, and timestamp. This data is essential for diagnosing integration issues.
  • Handle delivery failures in your application
    FAILED and UNDELIVERABLE delivery receipts should trigger application-level logic — fallback channels, user notification, or retry policies.
Retry with exponential backoff (Python)
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.

UK Registered20 Years ExperienceTier-1 Connectivity190+ Countries24/7 Support