Status codes
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Body was malformed JSON or exceeded the 4 KB cap. |
| 401 | missing_api_key | Authorization header absent or not a vv_live_… Bearer token. |
| 401 | invalid_api_key | Key not found, revoked, or disabled. |
| 402 | insufficient_balance | Wallet is empty and autopay is not active. Top up or enable autopay. |
| 403 | scope_denied | Key exists but is not authorized for this surface. |
| 429 | rate_limited | Per-key budget exceeded. See X-RateLimit-* headers. |
| 500 | server_error | We failed. Retry with exponential backoff. |
| 502 | upstream_error | Upstream backend (LiveKit / meeting-agent) failed. Retry. |
Error envelope
Every non-2xx response is JSON with at least an error string. Some errors carry a second hint field:
Optional fields
| Field | Type | Notes |
|---|---|---|
setup_url | string | Returned with 402 — points at the billing page where you can top up or enable autopay. |
room_url | string | Returned with 502 from meeting-agent if Vikash dispatch fails after the room was already created. |
# All errors are JSON with an "error" field. 4xx responses
# have NO retry value beyond Retry-After on 429.
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{ "error": "Invalid API key" }
HTTP/1.1 402 Payment Required
Content-Type: application/json
{ "error": "insufficient_balance", "setup_url": "https://vaanilabs.in/settings#billing" }
HTTP/1.1 403 Forbidden
Content-Type: application/json
{ "error": "Key not authorized for surface 'meeting-agent'" }# All errors are JSON with an "error" field. 4xx responses
# have NO retry value beyond Retry-After on 429.
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{ "error": "Invalid API key" }
HTTP/1.1 402 Payment Required
Content-Type: application/json
{ "error": "insufficient_balance", "setup_url": "https://vaanilabs.in/settings#billing" }
HTTP/1.1 403 Forbidden
Content-Type: application/json
{ "error": "Key not authorized for surface 'meeting-agent'" }# All errors are JSON with an "error" field. 4xx responses
# have NO retry value beyond Retry-After on 429.
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{ "error": "Invalid API key" }
HTTP/1.1 402 Payment Required
Content-Type: application/json
{ "error": "insufficient_balance", "setup_url": "https://vaanilabs.in/settings#billing" }
HTTP/1.1 403 Forbidden
Content-Type: application/json
{ "error": "Key not authorized for surface 'meeting-agent'" }What we don't return
We do not currently return 409 conflicts, idempotency keys, or pagination cursors — there are no list endpoints on the public API. If a future surface needs them, they'll arrive in a versioned v2.