Documentation menu

Errors, limits, and conventions

Error format, limits per plan, idempotency, pagination, versioning, and usage.

Error format

Every error returns an HTTP status code and a body in this format:

json
{
  "error": {
    "type": "invalid_request",
    "code": "missing_param",
    "message": "The 'agent_id' field is required.",
    "param": "agent_id",
    "request_id": "req_8q1m2z"
  }
}

Send the request_id to support when you need help. It's also returned in the Nevox-Request-Id header of every response.

HTTPtypeWhen
400invalid_requestMissing parameter, wrong format, or invalid value
401authentication_errorKey missing, invalid, or revoked
403permission_errorMissing scope, plan doesn't include the API, or domain not allowed
404not_foundThe resource doesn't exist or belongs to another account
409conflictState conflict (e.g. sending a message in a closed conversation) or an idempotency key reused with a different body
413invalid_requestBody or file too large
422invalid_requestData is well-formed but rejected by a rule (e.g. a private action URL)
429rate_limit_errorRequest limit or monthly quota reached
500, 502, 503api_errorA problem on our side. Retry with exponential backoff.

Most common codes

codeMeaning
missing_param, invalid_paramA problem with a field, indicated in param
invalid_api_key, revoked_api_keyInvalid or revoked key
insufficient_scopeThe key doesn't have the required scope
plan_requiredThe API requires the Pro - 3 Agents or Ultimate - 5 Agents plan, with an active subscription
feature_not_in_planFeature available only on Ultimate - 5 Agents (e.g. export)
origin_not_allowedPublishable key used on a domain that isn't on the list
session_token_expiredThe widget session token has expired
conversation_closedThe conversation has already been closed
idempotency_key_reusedThe same idempotency key with a different body
rate_limitedToo many requests per minute
monthly_quota_exceededMonthly quota reached (conversations, /ask, or events)

Rate limits

Pro - 3 AgentsUltimate - 5 AgentsTest keys
Requests per minute, per account6030020
Messages per minute, per conversation202020
Browser tracking eventsNo practical limitNo practical limit—

Every response includes:

texto
RateLimit-Limit: 60
RateLimit-Remaining: 57
RateLimit-Reset: 41

RateLimit-Reset is the number of seconds until the limit resets. When you get a 429, wait for the time given in the Retry-After header.

Monthly quotas

Conversations through the API and the widget count toward the plan's same conversation quota (Pro - 3 Agents: 900; Ultimate - 5 Agents: 1,600). /ask and server events have their own quotas. See the plans table.

You get an email when you reach 80% and 100% of any quota.

Usage

GET /v1/usage (any valid key)

json
{
  "plan": "pro",
  "period": { "start": "2026-11-01", "end": "2026-11-30" },
  "conversations": { "used": 812, "limit": 2000 },
  "ask": { "used": 112, "limit": 1000 },
  "server_events": { "used": 2310, "limit": 10000 },
  "api_keys": { "used": 2, "limit": 3 },
  "webhook_endpoints": { "used": 1, "limit": 3 }
}

Idempotency

To safely retry a POST (e.g. after a timeout), send the Idempotency-Key header with a unique value, such as a UUID:

texto
Idempotency-Key: 6c1f0e2a-1b8e-4f0e-9d0a-1d2c3b4a5e6f

For 24 hours, the same key returns the same response without repeating the operation. Using the same key with a different body returns 409 idempotency_key_reused.

Pagination

Lists use a cursor:

bash
curl "https://api.nevox.ai/v1/conversations?limit=50&cursor=eyJpZCI6..." \
  -H "Authorization: Bearer $NEVOX_API_KEY"
json
{
  "data": [ ... ],
  "has_more": true,
  "next_cursor": "eyJpZCI6ImNvbnZfN..."
}

limit ranges from 1 to 100 (default 20). When has_more is false, you've reached the end.

Versioning

The major version is in the path (/v1). Changes that could break integrations only ship in a new major version, with at least 6 months' notice.

Within /v1 we may, without notice: add endpoints, add fields to responses, add new values to list fields (such as new event types), and add optional parameters. Build your integration to ignore fields it doesn't recognize.

All changes are listed in the changelog.

IDs

PrefixResource
agt_Agent
conv_Conversation
msg_Message
ctc_Contact
kn_Knowledge item
svc_Service
act_ / inv_Action / action invocation
whk_ / evt_Webhook / webhook event
fb_ / sug_Feedback / learning suggestion
vis_ / ses_Visitor / session
exp_Export
req_Request