Skip to main content
The Tanvik API uses conventional HTTP status codes and a consistent JSON error body so failures are easy to handle programmatically.

Error response shape

{
  "error": {
    "code": "invalid_request",
    "message": "to is required",
    "status": 400
  }
}

HTTP status codes

StatusMeaning
200Request succeeded
400Malformed request — check required fields and formats
401Missing, invalid, or revoked API key
403Key is valid but the account’s plan doesn’t include this feature
404Resource (message, template, webhook) not found
422Request understood but rejected downstream (WhatsApp, OTP logic)
429Rate limit exceeded — 120 requests/minute per key
500Something went wrong on our end

Error codes

CodeStatusCause
missing_api_key401No Authorization header sent
invalid_api_key401Key is malformed, doesn’t match any account, or was revoked
feature_not_enabled403Your plan doesn’t include API access
rate_limited429More than 120 requests/minute on this key — see Retry-After header
invalid_request400A required field is missing or malformed
no_default_otp_template422No approved authentication-category template exists; create one or pass template explicitly
otp_send_failedvariesWhatsApp/OTP send failed downstream — message has the underlying reason
otp_expired422The OTP code has passed its validity window
otp_max_attempts422Too many incorrect verification attempts for this otp_id
otp_not_found404No pending OTP matches the given otp_id
otp_verify_failedvariesUnexpected failure verifying the code
template_create_failedvariesTemplate submission was rejected — message includes the reason
template_not_found404No template with that id on this account
send_failedvariesMessage send failed — check message for the specific reason (e.g. closed session window, insufficient wallet balance)
too_many_recipients400More than 100 recipients in one /v1/messages call
message_not_found404No message with that id on this account
webhook_not_found404No webhook with that id on this account
not_found404No matching route for this method/path
internal_error500Unexpected server-side failure

Handling 429s

Rate-limited responses include a Retry-After header (seconds). Back off and retry rather than looping immediately.
otp_send_failed, template_create_failed, and send_failed wrap the real downstream error text in message — read it, since the specific reason (e.g. “Session window closed. Use a template.”) is usually more actionable than the generic code.