Error Reference

Errors & Rate Limits

Complete reference for error codes, HTTP status mapping, rate limit policies, and retry strategies.

HTTP Status Codes

Modern REST API uses standard HTTP status codes. The response body includes a structured error object.

CodeStatusMeaning
400Bad RequestRequest validation failed (missing or invalid parameters)
401UnauthorizedAuthentication required or invalid API key
402Payment RequiredInsufficient wallet balance to complete the action
403ForbiddenAuthenticated, but not authorized for this resource
404Not FoundResource not found (e.g. activation ID does not exist)
409ConflictRequest conflicts with current state (e.g. activation already completed)
422Unprocessable EntityRequest is well-formed but semantically invalid
429Too Many RequestsRate limit exceeded — see Retry-After header
500Internal Server ErrorUnexpected server error — retry with exponential backoff
503Service UnavailableUpstream provider unavailable — retry later

Error response shape (JSON)

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 27937
X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 2026-05-10T00:00:00.000Z

{
  "error": "rate_limit_exceeded",
  "message": "Daily API limit reached. Contact support for higher tier.",
  "retryAfter": 27937,
  "limit": 10000,
  "usage": 10000
}

SMS-Activate Text Codes

SMS-Activate compatible endpoint returns plain text codes. Each code maps to an HTTP status for tooling that needs both.

Text CodeHTTPMeaning
BAD_KEY401Invalid or missing API key
BAD_ACTION400Action parameter missing or malformed
BAD_SERVICE400Service code not recognized
BAD_COUNTRY400Country parameter not recognized
BAD_STATUS400Invalid status value for setStatus
WRONG_ACTION400Action name not supported
NO_BALANCE402Insufficient wallet balance
NO_NUMBERS404No numbers available for this service+country combination
NO_ACTIVATION404Activation ID not found or not yours
RATE_LIMITED429Rate limit exceeded — slow down or wait for reset
ERROR_SQL500Internal server error — retry later

Rate Limits

Per-API-key throttle. Multiple servers using one key share a single bucket.

Burst limits

Three concurrent throttle tiers protect against bursts and sustained abuse. Hitting any tier returns 429.

short
5
per 1 second
medium
30
per 10 seconds
long
100
per 60 seconds

Daily Quota

Default 10,000 requests per API key per day. Resets at UTC midnight.

  • Public catalog endpoints (services, countries) are exempt from daily quota
  • Quota counter increments on every authenticated request, regardless of response status
  • Pro tier with higher limits available — contact support

Response Headers

Every authenticated API response includes rate limit headers so clients can self-throttle proactively.

X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 9543
X-RateLimit-Reset: 2026-05-10T00:00:00.000Z
Retry-After: 27937

Retry Strategy

How to handle transient failures without flooding the API or losing data.

Do

  • Honor Retry-After header on 429 responses
  • Use exponential backoff for 5xx errors (1s, 2s, 4s, 8s)
  • Retry up to 5 times, then surface error to the user

Don’t

  • Retry 4xx errors except 429 — they are deterministic
  • Hammer the API after 429 — wait the full Retry-After period
  • Retry POST /activations without checking idempotency

Recommended retry pattern

# Pseudocode — exponential backoff with Retry-After
attempt = 0
while attempt < 5:
    response = call_api()

    if response.status == 200:
        break  # success

    if response.status == 429:
        wait = response.headers.get('Retry-After', 2 ** attempt)
        sleep(wait)
        attempt += 1
        continue

    if response.status >= 500:
        sleep(2 ** attempt)  # exponential
        attempt += 1
        continue

    raise APIError(response)  # 4xx other than 429

Idempotency

Some operations charge your wallet — retrying naively can cause double charges.

POST /activations is not idempotent

If you retry a successful POST /activations, you will create a second activation and be charged twice. On any timeout or unclear response, list activations with GET /activations to verify state before retrying.

Need more details?

The interactive API reference shows error responses for every endpoint.