Limits
Rate limits, the active-run cap per end-user, daily token budgets.
Four different kinds of limits apply to the public surface. All of them
return a 429 with either code: "rate_limited" or
code: "budget_exceeded" — see Errors for the
full error shape.
Token exchange (POST /v2/token)
Counted per (publishable key, caller IP), 60 requests/minute by
default. Only applies to exchanging via pk (anonymous or signed) —
exchanging with an API key (server-to-server) has no limit at this
endpoint. Exceeding it returns rate_limited with
scope: "token_exchange" and a retry_after (seconds).
Messages from an end-user
Counted per end-user (not per IP), 20 messages/minute by default —
your organization can adjust this within whatever ceiling the operator
allows. Applies to messages sent through the widget or through
POST /v2/conversations/{id}/messages.
scope: "end_user".
Messages from an API key
Counted per API key, 300 requests/minute by default — also adjustable
within an operator ceiling. Applies to
POST /v2/chat. scope: "api_key".
Concurrent active runs
Each end-user (including the service end-user standing in for an API key
that skips end_user_id) can have at most 3 runs in flight at once.
Sending a fourth message while three runs are still going returns
rate_limited with scope: "active_runs" — wait for a run to finish (or
cancel one) and send again. A run
waiting for the user to confirm an action or answer questions still counts as
in flight.
Concurrency and queue (per organization)
Your organization can run a set number of chat runs at once (10 by default) and keep a set number waiting for a free slot (50 by default). The Harnix team sets both for your organization; you see them in Console → Usage & Quotas. When a new message would only join a full queue, it is refused right away instead of waiting indefinitely:
429 queue_fullwithscope: "org", aretry_afterin seconds and aRetry-Afterheader — no message and no run are created. Waitretry_afterseconds and send again.scope: "deployment"means the platform as a whole is at capacity and your organization has no free slot; handle it the same way.- Resending with the same
Idempotency-Keyreturns the original run, neverqueue_full.
Document processing runs in the background and never counts toward these limits.
Daily token budgets
Your organization can set a daily budget (total tokens the model consumes) — for the whole organization, and/or per agent (Console → Usage & Quotas). Once it's used up:
- A request that would start a new run gets
429 budget_exceededwithscope: "org"or"agent"immediately — no run is created. - A run already in progress whose org/agent runs out mid-flight (another
run just used up the rest) stops at the next safe checkpoint, also with
an
errorstarting withbudget_exceeded.
No budget set = no limit. The day is counted in UTC.
The confirmation window (not a rate limit)
When the agent wants to call a connector tool that needs confirmation, the
run pauses and waits for the user's answer for up to 5 minutes (the
Harnix default, the same for every organization; expires_at on the
approval frame gives the exact moment). Past that, the action counts as
declined: the tool doesn't run, the assistant tells the user the action was
not carried out, and the run ends normally — no 429 is involved. See
Idempotency & cancel and
Connectors.
The question waiting window (not a rate limit)
When the agent calls ask_user, the run pauses and waits for the user's
answer for up to 10 minutes (the Harnix default, the same for every
organization, deployment setting ASK_USER_TIMEOUT_SECONDS; expires_at on
the question frame gives the exact moment). Past that, the model is
notified that the question expired and proceeds with the available context —
the run ends successfully (succeeded), and no 429 is involved. See
Idempotency & cancel and
Tools.
Trace retention (not a rate limit)
Your organization has a separate setting for how many days it keeps trace
content (Console → Usage & quotas) — unrelated
to the four kinds of limits above, never returns a 429, and doesn't affect
the conversations or messages you read back through the API. See
Runs & traces.
Next
- Errors — the
{code, message, scope?, retry_after?}shape. - Production checklist — handling
429s correctly before you ship.