V1
API v1•Conventions
Errors & Pagination
Standard error response formatting, HTTP status codes, and cursor-based pagination conventions across API v1.
Error Envelope
Every error response returns a JSON object with a human-readable message string and, on v1 resource endpoints, a machine-readable code (NOT_FOUND, VALIDATION_ERROR, CONFLICT, FORBIDDEN):
Error Response
{"message": "Invalid status: BOGUS. Allowed: NOT_SENT, SENDING, SENT, DELIVERED, FAILED, EXPIRED","code": "VALIDATION_ERROR"}
For definitions of allowed message statuses and lifecycle transitions, see the Message Statuses guide.
HTTP Status Codes
| Status | Code | Meaning |
|---|---|---|
| 400 Bad Request | — | Missing required request fields, unsupported phone number provider, or invalid sendBefore timestamp. |
| 401 Unauthorized | — | Missing, malformed, or expired Bearer JWT token. |
| 402 Payment Required | — | Insufficient active tokens in your billing organization. |
| 403 Forbidden | FORBIDDEN | Attempting to use a template restricted to another app or modify a PUBLIC template. |
| 404 Not Found | NOT_FOUND | Resource does not exist or belongs to another organization/application. |
| 409 Conflict | CONFLICT | Attempting to modify an already APPROVED template slug. |
| 422 Unprocessable Entity | VALIDATION_ERROR | Template parameter validation failure, unapproved template, invalid filter/date query param, or non-HTTPS webhook URL. |
| 429 Too Many Requests | — | Per-number OTP cooldown (60s) or sliding 15-minute cap (5 codes) exceeded. |
| 500 Internal Server Error | — | Unexpected server or upstream queue failure. Safe to retry with an Idempotency-Key. |
Common Error Messages
"Insufficient tokens"(402) — Top up your organization's balance or checkGET /api/v1/balance."Template '...' is not approved (current status: PENDING)"(422) — Wait for template review or use an already approved template."Message does not match any approved template"(422) — When sending rawmessagetext, ensure it matches an approved template's pattern and parameter bounds."Approved templates cannot be modified directly. Please register a new version or slug."(409) — Create a new slug (e.g.otp_login_v2) when changing an approved template.
Cursor Pagination Convention
All list endpoints (GET /messages, GET /batches, GET /batches/:id/messages, GET /ledger, GET /webhooks/:id/deliveries) use deterministic cursor pagination ordered by createdAt desc, id desc:
limit: Number of items per page (default25, min1, max100).cursor: Opaque ID of the last item from the previous page (pagination.nextCursor).from/to: Optional ISO 8601 UTC date or datetime filters (fromis inclusive,tois exclusive).
Paginated Response Envelope
// Response envelope{"data": [ /* ...items... */ ],"pagination": {"limit": 25,"nextCursor": "f47ac10b-58cc-4372-a567-0e02b2c3d479","hasMore": true}}