Error codes
API returns standard HTTP codes with JSON error body. The retryable field indicates whether the request can be retried.
Error format:
400 — Invalid request (missing required fields, wrong format)
401 — Invalid or missing API key
403 — No access to resource
404 — Subscriber or resource not found
409 — Conflict (e.g., OTP already sent)
422 — Validation error (text too long, invalid URL)
429 — Rate limit exceeded (retryable: true, Retry-After header)
500 — Internal server error (retryable: true)
Limits
Rate limits and field size restrictions.
Rate limit: 300 requests/min per project. Exceeding it returns 429 Too Many Requests.
Message text: up to 4,096 characters.
Buttons: up to 3 rows, up to 3 buttons per row.
Media: up to 20 MB (photo), 50 MB (video/document).
Broadcast: up to 100,000 subscribers per broadcast.
OTP: 5-min TTL, max 5 attempts, 1 active code per subscriber_id.
Tags: up to 20 tags per project, tag length up to 64 characters.
Permissions: up to 20 per project.
Templates: up to 100 per project.
X-RateLimit-* headers are not returned. When the limit is exceeded, the API only returns HTTP 429 with an error body. We recommend implementing exponential backoff on your side.
Error handling & retry
Recommendations for handling API errors and retry strategies.
retryable: true — the error is temporary (429, 500). Use exponential backoff: 1s → 2s → 4s, max 3 attempts.
retryable: false — retrying won't help (400, 401, 403, 404, 409). Fix the request before resending.
Retry-After — on 429, this header specifies how many seconds to wait before the next request. Rate limit: 300 requests per minute per project.
Exponential backoff — increase delay between attempts: 1s, 2s, 4s. Do not automatically retry POST requests (send, broadcast) — use the retryable field to make decisions.