Skip to content
SMSRay

Errors

Errors use conventional HTTP status codes and one JSON shape, with a stable machine-readable code you can branch on.

Error shape

Every error response has a JSON body with a human-readable error and a stable code. Validation errors also include details.

400 application/json
{
  "error": "Invalid request",
  "code": "invalid_request",
  "details": [
    { "path": ["to"], "message": "Required", "code": "invalid_type" }
  ]
}

The error text may change. Write your logic against code and the HTTP status.

Error codes

All v1 API error codes
HTTPcodeWhen
400invalid_requestValidation failed (details lists each problem), bad JSON, a non-Nepal number, or text over 6 segments.
401unauthorizedx-api-key missing or invalid.
402insufficient_balanceWorkspace balance is lower than the message cost.
403client_disabledThe API client that owns the key is disabled.
403workspace_pendingPOST before Lacspace has activated your workspace.
403workspace_suspendedPOST while the workspace is suspended.
403forbiddenThe message type is not allowed for your workspace.
404not_foundUnknown id, or a message that belongs to another API client.
409idempotency_conflictIdempotency-Key reused with a different body, or the first request is still running.
429rate_limitedA rate or OTP limit was hit. Wait for Retry-After seconds.
500server_errorUnexpected error on our side. Retry with backoff and the same Idempotency-Key.
503unavailableNo sending route is available right now. Nothing was charged.
503sms_disabledThe SMS service is temporarily switched off. Retry later.

Answers that are not errors

A wrong OTP is a normal answer from POST /sms/otp/verify, returned with HTTP 200:

200 application/json
{ "success": true, "verified": false, "reason": "invalid_code" }
OTP verify reasons
reasonMeaning
invalid_codeThe code does not match. The attempt is counted.
too_many_attempts5 wrong attempts were made. Send a new code.
no_active_otpNo code was sent for this number and purpose, it expired, or it was already used.

Likewise, a message that ends as undelivered or failed is reported through its status, not as an API error.

Handling errors

How to handle each class of error
StatusRetry?What to do
400, 403, 404NoFix the request, the key or the workspace setup.
401NoCheck the key; it may have been rotated.
402After top-upAdd balance, then retry with the same Idempotency-Key.
409Yes, carefullyIf the first request is still running, wait 1 s and retry. Otherwise use a new key for a new message.
429YesWait Retry-After seconds.
500, 503YesExponential backoff with jitter, same Idempotency-Key.