Skip to content

Errors

Authevo uses standard HTTP status codes. Successful responses are wrapped in a data object; failures return an error object with a machine-readable code and a human-readable message. The tables below cover every code the public send/verify/TOTP endpoints can return — always branch on the HTTP status and error.code, not the message, since messages may change.

400 Bad Request
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "body/phone must match pattern \"^\\+[1-9]\\d{6,14}$\""
  }
}

General & authentication

StatusCodeMeaning
400VALIDATION_ERRORThe request body was malformed, missing a required field, or the phone number isn't a valid E.164 number.
401INVALID_API_KEYThe Authorization header is missing or the secret key is invalid.
404NOT_FOUNDThe requested resource (e.g. an OTP request id) doesn't exist or doesn't belong to your account.
429RATE_LIMIT_EXCEEDEDToo many requests. Slow down and retry after a short delay.
500INTERNAL_ERRORSomething failed on Authevo's side. Safe to retry — these are logged and monitored.

Sending & verification

StatusCodeMeaning
400INVALID_PHONEThe phone number is not a valid, reachable number for this endpoint.
400OTP_NOT_FOUNDThe code has expired, was already used, or was never sent for this phone number.
409IDEMPOTENCY_KEY_IN_PROGRESSA request with this Idempotency-Key is still being processed — wait for it to finish instead of sending a third attempt.
409TEMPLATE_NOT_READYThe WhatsApp message template isn't approved yet on the sending number. Falls back to Telegram automatically if the recipient has linked it.
409CHANNEL_NOT_LINKEDWhatsApp delivery failed and this recipient hasn't linked Telegram yet — nothing was delivered. Call the Telegram-link endpoint for this phone first.
429TOO_MANY_ATTEMPTSToo many failed verification attempts for this phone number. Wait before trying again.
500DELIVERY_FAILEDThe message could not be delivered on any channel. Safe to retry.
503TELEGRAM_UNAVAILABLETelegram fallback isn't available right now.

Two-Factor (TOTP)

StatusCodeMeaning
400TOTP_NOT_ENROLLEDThis phone number has no active TOTP enrollment to verify or disable.
409ALREADY_ENROLLEDThis phone number already has a confirmed TOTP enrollment. Pass replace: true to reissue one.
429TOO_MANY_ATTEMPTSToo many failed verification attempts for this phone number. Wait before trying again.
503TOTP_NOT_CONFIGUREDTOTP is temporarily unavailable on Authevo's side.

Billing & credit

StatusCodeMeaning
402INSUFFICIENT_CREDITSYour account balance is below the amount required to send — add prepaid credit to continue (a $2 minimum balance applies).
402DEPOSIT_REQUIREDYour account has never had a deposit — add prepaid credit before your first send.
402FREE_TRIAL_EXHAUSTEDYou've used all of your free verifications. Add credit to keep sending.
429SPEND_CAP_EXCEEDEDYour hourly spend cap was reached. It resets automatically; raise it from your dashboard if you're hitting it often.
500BILLING_ERRORThe verification itself succeeded, but billing it failed — Authevo's side, not yours. Logged and reconciled automatically; the verified result stands.
503FREE_TRIAL_PAUSEDThe free trial is temporarily paused platform-wide. Retry shortly, or add credit to send immediately.
Always branch on the HTTP status and the error.code, not the message — messages may change.

Rate limits

Requests are rate limited per phone number and per source IP. When you exceed a limit, the API responds with 429 RATE_LIMIT_EXCEEDED — back off and retry after a short delay. These are the real, current numbers, not illustrative ones.

ScopeLimitWindow
Same recipient phone number (send)3 requests10 minutes
Same source IP address10 requests1 hour
Failed verify attempts, same phone number5 attempts15-minute block

Safety Floor

Beyond the limits above, the Safety Floor watches your account's real-world success rate: three consecutive days with a 24-hour verification success rate under 55% moves your account from pay-per-success back to the per-message tier until it recovers. It's a guardrail against sustained abuse or a broken integration silently running up your bill — automatic, nothing to configure.

Idempotency

Send an Idempotency-Key header on POST /v1/otp/send to make network retries safe — a retry with the same key replays the original response instead of sending (and charging for) a second message.

Idempotency-Key: 5b6b4c9e-6e0a-4b7a-9b7a-2f2b6a7c9e10

Generate a fresh key per logical send attempt (a UUID works well) and reuse it only when retrying that exact same attempt. Keys are scoped to your account and remembered for 24 hours — a retry with the same key while the original request is still in flight gets back a 409 IDEMPOTENCY_KEY_IN_PROGRESS immediately, rather than racing it.

The header is entirely optional — requests without one behave exactly as before. It's worth adding wherever your client-side retry logic could plausibly re-send the same request after a timeout.