Cette page est publiée en anglais et en ukrainien ; la version anglaise figure ci-dessous.
API errors and limits
For developers, in code: every status and error code the two APIs return, the burst limits and the monthly quota, what the soft block looks like, and the per-plan caps.
Runtime statuses
| Status | Where | Meaning |
|---|---|---|
400 |
/tts, /conversation |
/tts: conversation mode is off on the widget; /conversation: an invalid or expired token |
401 |
header-authenticated endpoints | no key, or no such key |
403 |
the same, and /conversation |
inactive key, or the origin is not on the key’s list; a switched-off widget on /message; a handoff token of another key |
404 |
/message, /widget/config, /tts, /conversation |
unknown agent, widget code or conversation; on /widget/config and /tts also a switched-off widget |
409 |
/message, /conversation |
the widget has no agent assigned; a handoff token already used |
422 |
everywhere | body validation (detail is pydantic’s list); on /handoff, "unrecognised_contact"; on /tts, no voice for the language |
429 |
/message, /tts, /handoff |
a burst limit; no credit is spent |
502 |
/tts |
the speech provider failed |
503 |
/message |
the model failed; try again |
204 |
/followed, /handoff/opened |
always — a beacon reveals nothing |
Socket error codes are on WebSocket and Speech and recognition.
Management statuses
| Status | Meaning |
|---|---|
403 {"detail": …} |
any authentication failure (there are no 401s), a plan gate, or a plan cap — the detail says which |
404 |
another owner’s row — it does not exist for you |
400 |
validation; the body names the field |
409 |
deleting an agent a widget still uses |
202 |
an asynchronous job was queued (import, provisioning, batch processing) |
Burst limits
Fixed windows per minute, counted for the whole account and, where the table says so, for each
visitor too — a visitor is one address on one site. Over the limit: 429, or a rate_limited
error frame on a socket; the credit is not spent and the turn is not run.
| Bucket | Per minute |
|---|---|
chat (/message, /ws messages) |
30 before a plan · 60 Starter · 180 Growth · 360 Pro · 900 Business; 20 per visitor |
speech (/tts) |
120; 60 per visitor |
recognition streams (/ws/stt) |
60; 20 per visitor |
handoff (/handoff, /handoff/opened) |
30 |
| followed beacon | 120 |
| voice timing frames | 120 |
| tool test (the panel) | 30 |
| onboarding analysis (the panel) | 20 |
A visitor also has a day: 300 chat turns, 300 recognition streams and 30,000 characters of speech.
Past it a chat turn gets 429 or rate_limited like any burst, and /tts answers 429 with
Speech limit reached for today.
Speech and recognition spend no credit themselves, so an account earns them by its answers: each
answered turn adds 2,500 characters of speech and 6 recognition streams to that day’s budget, on
top of 20,000 characters and 200 streams a day for what no answer pays for — a spoken greeting,
Shukai.speak, a dictation never sent. Past it /tts answers 429 with
Speech limit reached for today and /ws/stt sends rate_limited. A sentence replayed from the
audio cache costs nothing and is never refused.
The monthly quota and the soft block
Each answered turn costs credits by model, plus the voice surcharge when spoken (Credits and models). The allowance refills on the subscription day; purchased top-ups carry over and are spent after it. At the cap:
- a
/messagecall still returns200, with the localized limit message asanswerand empty lists; - a socket turn gets
limit_reachedafterstartinstead of an answer; GET /widget/configservesactive: falsefrom the next load, so the widget mounts nothing;- the owner is emailed at 80 % and 100 %.
Before a plan is active the account has an allowance of its own: 50 credits a day and 300 a month, 20,000 characters of speech and 100 recognition streams a day. Past it a turn is answered as at the monthly cap, with a message that the trial allowance is used up, and no email is sent.
A custom front end should treat limit_reached and active: false as «the assistant is away»,
not as an error.
Per-plan caps
| Starter | Growth | Pro | Business | |
|---|---|---|---|---|
| credits / month | 3,000 | 7,000 | 18,000 | 52,000 |
| sites (one before a plan) | 1 | 3 | 10 | 25 |
| pages (sources), across all your sites | 500 | 2,000 | 5,000 | 10,000 |
| conversation history | 30 days | 90 | 180 | 365 |
| chat burst / min | 20 | 60 | 120 | 300 |
| custom tools, events, page actions, proactive, delivery | — | ✓ | ✓ | ✓ |
| global tools / events | 0 | 6 | 8 | 11 |
| screen-scoped tools / events | 0 | 50 | 150 | 500 |
A site create past the plan’s site count and a source create over the page cap are each a 403
whose detail names the cap; a tool or event create over its cap is
400 on scope; both are judged on the resulting count, so nothing already saved is lost on a
downgrade — it is marked «not on your plan» and stops being served.
Per-turn caps
| Cap | Value |
|---|---|
| custom tool calls per turn | 3 |
| custom tool timeout · response · concurrency · cache | 10 s · 256 KB · 8 · 600 s |
| tools and events bound per turn | 12 tools and 12 events among those bound on the screen, by name; the rest dropped with only a server log |
| page-action round trips · steps per call · bridge timeout · prefetch | 40 · 40 · 5 s · 1.5 s |
| knowledge-base searches per message | 3 |
| spoken answer | 1,200 tokens of output at most; 1,200 characters per /tts sentence |
| conversation handoff token | 90 s, single use |