---
title: "Errors and Rate Limits"
description: "Chatvox API status codes, error responses, and request limits."
---

## Errors

Errors return a JSON body with a readable `error` message and a machine-readable `code`:

```json
{ "error": "Invalid API key.", "code": "invalid_api_key" }
```

| Status | `code` | Meaning | What to do |
| --- | --- | --- | --- |
| `401` | `invalid_api_key` | The key is missing, mistyped, or revoked. | Check the `Authorization` header. |
| `402` | `billing_suspended` | The team's billing is suspended. | Update the payment method in **Plans & billing**. |
| `402` | `billing_unavailable` | The team is out of credits. The message may already be saved. | Add credits or wait for the monthly reset. Before resending, [check the conversation](/docs/developers/conversations#get-a-conversation). |
| `402` | `agent_credits_limit` | The agent reached the credit limit set in its settings. The message may already be saved. | Raise or remove the agent's limit. Before resending, [check the conversation](/docs/developers/conversations#get-a-conversation). |
| `403` | `plan_not_allowed` | The team's plan doesn't include the API. | Upgrade to Standard or above. |
| `403` | `model_not_allowed` | The agent's AI model isn't included in the team's plan. | Choose another model or upgrade. |
| `404` | `not_found` | The item doesn't exist, belongs to another team, or the key can't reach that agent. | Check the IDs and the key's access. |
| `409` | `agent_inactive` | The agent is inactive because your team has more agents than your plan allows. | Upgrade your plan or remove another agent. |
| `409` | `idempotency_in_progress` | A request with the same `Idempotency-Key` is still running. | Wait a few seconds, then retry with the same key. |
| `409` | `conversation_busy` | The agent is still answering a previous message in this conversation. The new message isn't saved. | Wait for the reply, then send the message again. |
| `422` | `idempotency_key_reused` | The `Idempotency-Key` was already used for a different request. | Use a new key for each new message. |
| `422` | `validation_failed` | The request is invalid. Details are in `errors`. | Fix the fields listed in `errors`. |
| `422` | `input_too_large` | The conversation is too long for the agent to process. | Start a new conversation. |
| `422` | `history_preparing` | The conversation's history is still being prepared. | Retry in a few seconds. |
| `422` | `rate_limited` | The AI provider is busy. | Retry in a few seconds. |
| `422` | `model_unavailable` | The agent's AI model isn't available right now. | Retry later, or choose another model. |
| `422` | `request_limit` | The agent couldn't process this message. | Retry, or start a new conversation. |
| `429` | `too_many_failed_attempts` | Too many requests with invalid keys from your IP address. | Fix the key, then wait for `Retry-After`. |
| `429` | — | You reached a rate limit. | Wait for the time in the `Retry-After` header. |
| `500` | `processing_failed` | Something went wrong on our side. The body includes a `request_id`. | Retry once. If it keeps failing, contact support with the `request_id`. |

Validation errors list each problem by field:

```json
{
  "error": "The message field is required.",
  "code": "validation_failed",
  "errors": { "message": ["The message field is required."] }
}
```

Every response includes an `X-Request-Id` header. Include it when you contact support about a request.

## Rate limits

| Limit | Applies per |
| --- | --- |
| 120 requests per minute | API key |
| 20 new knowledge sources per minute | API key |
| 20 failed API key attempts per minute | IP address |

Limits are counted per key, not per IP address, so integrations that share IP addresses, such as Zapier, Make, and n8n Cloud, don't affect each other.

When you reach a limit, the API returns `429` with a `Retry-After` header in seconds. Wait that long before retrying.

## Retrying safely

- `GET` and `DELETE` requests are safe to retry.
- **Sending a message** is safe to retry when you send an `Idempotency-Key` header and reuse it for the retry. Without one, a timed-out request may still have been answered and used credits, so [get the conversation](/docs/developers/conversations#get-a-conversation) before resending. See [Retry safely with an idempotency key](/docs/developers/agents-and-chat#retry-safely-with-an-idempotency-key).
