Skip to content
XICBOT

Settings

Deutsch
Documentation · API reference

API limits: plan gates and throttles

Which API endpoints depend on plan features and count limits, which named throttles apply with which values, and what the 402, 429 and 503 responses look like.

In plain language

The API sets limits on requests. The plan you booked decides whether an endpoint is open. It also sets how many assistants and sources you can create. Counters limit how often you can call an endpoint in a period of time. This page lists every limit. It says which answer comes when a request is refused. And it shows how to deal with it.

Last updated

All documentation topics

The API limits requests in two ways: through the booked plan and through counters. The plan decides whether an endpoint is open at all and which count limits for assistants, knowledge sources, documents, chunks and seats are checked on creation. Counters limit how often an endpoint may be called within a time window. This page lists every gate with its endpoint, value and response. For an overview of plans and quota, see Plans and quotas.

Plan gate and plan limits

Endpoints bound to a plan feature, a yes/no limit of the plan or a count limit check the account's plan before doing anything. The rejection carries status 402, which sets it apart from a missing role (403): someone in the account can grant a role, whereas a missing feature or a higher limit only comes with another plan. A count limit is reached as soon as the stock equals the limit, so with a limit of 1 the second assistant fails.

StatuserrorOther fieldsMeaning
402plan_feature_missingfeature, plan, plan_name and available_inThe plan lacks the feature the endpoint needs, or a yes/no limit of the plan is set to no; feature then names that limit.
402plan_limit_reachedlimit, allowed, used, plan and plan_nameThe count limit is reached; nothing is created.
503plan_limit_unmeasuredlimit and reasonThe stock could not be counted; nothing is created.
500plan_gate_misconfiguredkind, feature or limitThe endpoint is bound to the plan incorrectly. This is an error on our side.
403no_tenant-The request belongs to no account.

limit and feature name the limit or feature by the key used in the tables below. plan is the plan key (for example start, pro or custom) and plan_name its display name (Start, Pro and, for the Custom plan, Individuell). available_in lists the keys of the plans that include the feature. allowed is the limit and used the current stock. These responses carry no message field, not even from status 500 upward; what counts is error.

antwort-402.json json

{
  "error": "plan_limit_reached",
  "limit": "assistants",
  "allowed": 1,
  "used": 1,
  "plan": "start",
  "plan_name": "Start"
}

In the app, plan_feature_missing shows “Your Start plan does not include this feature. See Billing for the overview.”, plan_limit_reached shows “The Start plan limit is reached: 1 of 1. See Billing for the overview.” and any other 402 shows “Your plan does not cover this. See Billing for the overview.” Your plan and your figures take the place of “Start” and the numbers. A 503 appears as “The service reported an error. Please try again later.”

Features by endpoint

Feature (feature)Endpoints under /api/v1Included in
tool_and_api_controlPOST keys, POST webhooks, PUT webhooks/{id} and POST webhooks/{id}/test, every endpoint under integration/, plus tools of type http and of the types for connected systemsCustom
conversation_analyticsanalytics/* except analytics/subscriptionPro, Custom
shop_integrationcatalog/*, including catalog/shop, catalog/shop/test and catalog/shop/syncPro, Custom
appointment_and_leadrecords/appointments and records/carts, plus tools of type appointmentPro, Custom
conversation_exportGET conversations/export and GET conversations/{id}/exportStart, Pro, Custom

For tools, the API checks the tool type on creation, on update and when the tool runs. Without the feature, a tool of that type is neither created nor changed; the response is the same 402 with plan_feature_missing. The types for connected systems are order_status, order_change, inventory_status, price_lookup, calendar_availability, calendar_booking, crm_lead, crm_activities, callback_note and ticket_create. Appointments and baskets check the feature only when a status is changed; without the feature their lists can still be read and single cases deleted. GET records counts every kind, and plan_locked lists the kinds whose status cannot be changed. conversation_export is a yes/no limit of the plan; if it is missing, the API also responds with 402 plan_feature_missing, with feature set to conversation_export. How the app displays locked areas is described under Plans and quotas.

Count limits by endpoint

Endpoint under /api/v1Limits checked (limit)
POST assistantsassistants
POST setup/runs/{id}/acceptassistants
POST knowledge/sourcesknowledge_sources, documents and chunks
POST setup/runsknowledge_sources, documents and chunks
POST knowledge/sources/{id}/refreshdocuments and chunks
POST team/invitationsseats

The limits apply per account. The API checks the existing stock before the endpoint creates anything; once a limit is reached, nothing new is created. Documents and chunks only come into being while a source is read in, so the check compares the stock before reading with the limit. Restoring a source does not check any count limit. For seats, members and open invitations count together. More on seats is in Team and roles.

The value of each limit per plan is listed in Plans and quotas. When a request is turned down, allowed carries your account's limit and used the current count.

Named throttles

Besides the plan, named throttles limit the number of calls. Each name has its own counters, so an exhausted name only blocks the endpoints that carry it. Values are per minute; where an hourly figure is also given, it counts separately, and the request is rejected as soon as either counter is exhausted. Exceeding a throttle returns 429, and the app shows “Too many attempts. Please wait a moment.” General information on status codes is in API basics.

Per user

These throttles count per signed-in user. Without a session, the origin of the request counts instead. Someone who belongs to several accounts uses the same counter in all of them; only dpa counts separately per account and user. password-change is one shared counter for three endpoints.

NamePer minuteEndpoints under /api/v1
knowledge-sources20POST knowledge/sources, refreshing, restoring and embedding a source, POST setup/runs
knowledge-search60Knowledge search
knowledge-ask30Asking the knowledge base
knowledge-probes6Running probe questions
knowledge-tune2Tuning based on the probe questions
assistants30Creating and updating assistants, creating and restoring versions, POST assistants/{id}/key, starting an acceptance run, creating and updating check questions, creating and updating tools; deleting is not throttled
conversations30Creating conversations, exporting all or one, rating, revealing plain text and fetching attachments; GET analytics/report
conversation-send20POST conversations/{id}/send
catalog20Creating, importing and changing products; saving, testing and syncing the shop connection
privacy5Account data export, objection to subprocessors, retention and deletion request
dpa10Data processing agreement endpoint
key10POST keys, POST webhooks and POST webhooks/{id}/test
confirmation3Resending the confirmation email
invitations5POST team/invitations
tenant-switch20Switching accounts
password-change5Changing the password, removing the code method and removing security keys

Per origin

These throttles apply to endpoints without a session and count per origin: per address for IPv4 and per /64 network for IPv6. An IPv4 address written in IPv6 notation (::ffff:) counts as an IPv4 address. Minute and hour counters run separately.

NamePer minutePer hourEndpoints under /api/v1
status30-public/status, public/changelog, fetching a demo with GET public/demo/{id} and public/accessibility
enquiry5-public/enquiry
demo2-POST public/demo
register520POST register
password-forgot-20POST password/forgot
auth-token30-Address confirmation with POST verify and POST password/reset
invitation20-GET invitation/{token} and POST invitation/accept
cart-pickup60-cart/pickup/{token}

Per visitor

The widget endpoints under /api/v1/public/widget/{key} count per visitor, formed from the origin and the widget key together. Visitors with the same origin therefore share a counter only within the same widget key. The widget caps apply in addition.

NamePer minuteEndpoints under /api/v1/public/widget/{key}
widget-send12POST send, confirming a tool call and uploading an attachment
widget60all other endpoints, including fetching the settings

API key caps

The endpoints under /api/v1/integration authenticate with the X-Api-Key header, see API integration. Two caps apply to them, both counted per key, so one runaway integration does not stop the account's other keys.

CapValueWindow
Per minuteRequests per minute field when the key is created, 1 to 6000, 120 if not set60 seconds from the first counted call
Per dayThe account's daily limit, default 2,000; a value of 0 means no daily capCalendar day in UTC; the counter restarts at 00:00 UTC, which is 1 a.m. in Germany, or 2 a.m. during summer time
  • Both caps are checked before either one counts, so a rejected request uses up nothing. Counting happens before the scope check, though: a request that fails only because of a missing scope still counts against both caps.
  • A key reports its per-minute limit through GET /api/v1/integration/status in the limit_per_min field, see Integration endpoints.
  • An existing key cannot be changed. For a different per-minute value, create a new key and revoke the old one.
  • An account can have up to 10 valid keys; revoked and expired keys do not count. One more returns 422 with too_many_keys and limit, and the app shows “The maximum number of simultaneous keys has been reached.”
  • GET /api/v1/keys states the limit in limit_active. The Interfaces page shows the count under API keys, for example as “3 / 10”.

antwort-429.json json

{
  "error": "too_many_requests",
  "scope": "minute",
  "limit": 120,
  "retry_after": 42,
  "limit_per_min": 120,
  "wait": 42
}

scope is minute or day, limit is the cap that was exceeded and limit_per_min is the key's per-minute value. retry_after and wait contain the same wait time in seconds as the Retry-After header. For the daily cap it runs until the end of the day in UTC, but at least 60 seconds.

Widget caps

Besides the named throttles, the widget has two caps of its own whose values belong to the account: one for calls and one for questions. Each cap counts on the visitor and, if the call belongs to a conversation, also on that chat window session. A call belongs to a conversation if the conversation ID is in the path or sent as conversation_id in the body. Either carrier can reject; counting only happens once neither has rejected.

CapEndpointsPer minutePer day
CallsSettings, start, history, rating, revocation, export and deletion, plus confirming, rejecting and reporting a tool callThe account's Requests per minute valueThe account's daily limit, default 2,000
QuestionsPOST sendDefault 10Default 200
  • The per-minute value for calls is the account's Requests per minute value. Switching to a plan sets it to that plan's value: 20 for Start, 60 for Pro, 120 for Custom. If the account is already on Custom, a value stored there stays in place.
  • The daily limit for calls is the same value as the daily cap of the API keys. For questions, an account may have a value other than the default.
  • Uploading and fetching attachments are not subject to these caps; only the named throttles apply there.
  • The windows run from the first counted call: 60 seconds for the minute and 86,400 seconds for the day. The day here is not a calendar day.
  • A cap below 1 counts as switched off.
  • The rejection is 429 with too_many_requests, limit_per_min, limit_per_day and wait, plus the Retry-After header.
  • How the chat window reacts is described under Widget delivery.

Monthly quota

Once the month's quota is used up, the assistant generates no more replies. How this shows depends on the endpoint. The quota itself is described in Plans and quotas.

From 80 % of the quota onwards, the assistant keeps answering in throttled form: a reply is capped at 300 units and runs at most one tool round. Once the quota is used up, the service turns the question down before any reply is generated.

EndpointResponse
POST /api/v1/integration/chat429 with quota_exhausted, scope set to month, month, budget, used and retry_after, plus the Retry-After header. The wait time runs until the month changes, at least 60 seconds.
Widget and the test dialog in the appAn error event with code set to quota_exhausted, scope set to month and retry_after, followed by the assistant's stored fallback reply.
Acceptance run422 with quota_exhausted. The app reports “The quota for this month is used up. A run would book every line as not measurable.” See Test and acceptance.

Other counters

Some endpoints also keep their own counters. Their rejections carry their own error codes.

Endpoint under /api/v1LimitCounted perResponse
POST login5 failed attempts per minute, 20 per hourEmail address and origin429 too_many_attempts with retry_in
POST login30 failed attempts per minute, 300 per hourOrigin429 too_many_attempts with retry_in
POST password/forgot3 requests per hourEmail address and origin429 too_many_attempts with retry_in
POST password/forgot10 emails per hourEmail address200 with {"ok":true}; nothing is sent in that case
POST catalog/shop/test3 tests per minuteAccount429 too_many_tests with retry_after and the Retry-After header
POST catalog/shop/syncone sync per 900 secondsShop connection429 sync_too_soon with retry_after, connection and the Retry-After header
POST public/demo3 existing demos created within 24 hoursIP address429 demo_ip_limit
POST public/demofree capacity for demos-503 demo_capacity
POST public/widget/{key}/send, POST integration/chat and POST conversations/{id}/sendquestions per conversation, set by the operator individually for each account: 0 to 1,000, default 60; 0 means no maximumConversationin the event stream, error with conversation_limit and limit, followed by a notice text and handoff

Only failed attempts count at sign-in. A successful sign-in releases the counter for email address and origin, while the per-origin counter keeps running. retry_in gives the wait time in seconds; sign-in and the password request do not send a Retry-After header. The limit of 10 emails per address does not change the response, and the request ends with 200. If a sync for the account is already waiting or running, POST catalog/shop/sync skips the waiting period and responds with 202, with already_pending set to true.

Handling rejections

  • Distinguish by status: 402 calls for another plan, 403 for another role, 429 for a pause and 503 with plan_limit_unmeasured for a later attempt.
  • If the Retry-After header is present, wait at least that many seconds. Otherwise evaluate retry_after, wait or retry_in.
  • Do not retry a 402 in a loop. It only changes with another plan or a smaller stock, for example after deleting an assistant.
  • Give each integration its own key. The per-minute and per-day caps count per key.
  • A key's daily cap restarts at 00:00 UTC; the widget's daily cap restarts 86,400 seconds after the first counted call.

Frequent questions

Why does the API respond with 402 instead of 403?

402 means the plan does not cover the endpoint or a count limit is reached. 403 stands for a missing role. This tells you whether another plan or another role is needed.

Do several API keys of one account share a counter?

No. The per-minute and per-day caps count per key. The daily value comes from the account and is the same for every key, but each key is counted separately.

When does a key's daily cap restart?

At 00:00 UTC. The counter belongs to the calendar day in UTC and expires when that day ends.

Do the per-user throttles apply across several accounts?

Yes. They count per user, even if that user belongs to several accounts. Only dpa counts separately per account and user.

Does a rejected request count?

Not for the key and widget caps. Both check every counter first and only count when none of them has rejected.

Something still unclear?

Tell us which page and which step you mean. We reply personally.

Enquiry in three steps

  1. 1. Topic
  2. 2. Your case
  3. 3. Contact

What is this about?

One click is enough, everything else is optional.

Tell us briefly about your case

Everything in this step is optional. It helps us reply with something concrete straight away instead of asking back.

Enquiries per month, roughly (optional)
When should it start? (optional)
How can we reach you?

Name and email address are enough. We reply personally.

We use your details to handle your enquiry. More on this in the privacy policy.