Errors & limits
HTTP status codes
| Status | Typical cause |
|---|---|
| 401 | Missing, invalid, or expired API key |
| 403 | Wrong organisation, missing permission, source not allowed, widget rejected the request, or conversation does not belong to this visitor |
| 404 | Unknown organisation, source, page, widget, or conversation |
| 402 | No answer credits left (chat and summarize) |
| 422 | Invalid input, identity check failed, or keep limit reached |
| 429 | Too many requests |
Invalid input
When a required field is missing or invalid, the body looks like this:
{
"message": "The content field is required.",
"errors": {
"content": ["The content field is required."]
}
}
message is a human-readable summary. errors maps each field name to one or more messages.
Rate limits
Limits are counted per minute.
Ingestion API
Counted per API key (or IP if there is no key).
| Area | Default |
|---|---|
| Page push and related routes | 120 requests per minute |
Widget API
Each group has a limit for the whole widget and a lower limit for a single visitor (widget + IP), so one visitor cannot use up the entire budget.
| Group | Endpoints | Defaults (widget / visitor) |
|---|---|---|
| Search | search | 60 / 20 |
| AI | chat, summarize | 20 / 6 |
| Events | events | 120 / 30 |
| Config | config, conversations | 300 / 60 |
Exceeding a limit returns 429.
Answers and billing
- Search and page ingestion do not use answer credits.
- Chat and summarize use your plan's monthly answers.
- When answers are used up, those endpoints return 402. The official embed falls back to search for chat.
Tips for reliable page sync
- Always send a stable
external_idso retries update the same page instead of creating duplicates. - Re-pushing identical content for an already indexed page is skipped.
- Batch requests accept at most 50 pages at a time.