Rate limits and errors
Found this helpful? Share it:
Found this helpful? Share it:
When a request fails, the idapt API tells you exactly why in a predictable shape, so your code can react instead of guessing. This is the error envelope, the types to branch on, and the limits to expect 🚦
Every failed request returns the same JSON shape:
{
"error": {
"type": "rate_limit",
"message": "Too many requests",
"code": "completions_per_minute"
}
}Branch on type, never on the wording of message(which can change). The optional code narrows the reason when one type covers several
cases.
Status | type | What happened |
|---|---|---|
|
| The key is missing, malformed, or revoked. |
|
| The key lacks the scope, or the route is session only. |
|
| No such resource, or you cannot see it. |
|
| The route exists but not this verb (for example creating a computer directly). |
|
| The body failed validation. Read the message for the field. |
|
| You hit a per-surface limit. Back off and retry. |
Every response carries an X-Request-Id header. Log it and
quote it when you contact support, because it points straight at the
failing request.
Surface | Limit |
|---|---|
Compatible-gateway completions | 300 requests per minute |
Notification sends | 100 per 24 hours per principal |
Notifications to one recipient | 500 per hour |
Automation webhook fires | 60 per hour |
Model calls also respect your Credit balance. When it runs out you get a usage wall, not a rate limit. See Plans, credits, and the welcome credit.
A usage wall carries a stable code naming which limit you
hit, so your integration can tell the user the right remedy:
code | What it means |
|---|---|
| The model is not unlocked yet: the welcome credit only covers operations priced at most $1. Add credits to unlock every model. |
| The request costs more than your balance covers. Add credits. |
| Your Credit balance ran out mid-request. Add credits. |
| The per-chat credit spend limit would be exceeded. Raise, remove, or reset that limit in the chat settings. |
| The Team seat cap is reached. A billing admin raises it. |
| The account's own daily, weekly, or monthly spending limit would be exceeded. Raise or turn off that limit in Billing, under Spending limits. |
| The daily spend cap for accounts without two-factor authentication would be exceeded (the cap is fixed, not editable). Enable two-factor authentication in Settings → Security. |
| The daily credit top-up cap for accounts without two-factor authentication was reached (the cap is fixed, not editable). Enable two-factor authentication in Settings → Security. |
Every response carries an X-Request-Id header. Log it and
quote it when you contact support, because it points straight at the
failing request.
Capacity walls are plan ceilings: a quota the plan itself sets. Credits never lift one; the remedy is delete, wait, or upgrade:
code | What it means |
|---|---|
| Drive storage has reached the plan's cap. Delete or move files, or upgrade. |
| The Knowledge Base is at its size cap for the plan. Delete or export notes, or upgrade. |
| The plan's workspace count limit is reached. Delete an unused workspace or upgrade. |
| The plan's provider-endpoint limit is reached. Remove an unused connection or upgrade. |
| The plan's limit of chats with an active run is reached. Wait for a chat to finish or upgrade. |
| The chat is at its plan's limit of active sub-agent workers. Wait for workers to finish or upgrade. |
| The plan's computer count limit is reached. Remove a computer or upgrade. |
| The plan's scheduled-automations limit is reached. Remove an automation or upgrade. |
A Gateway API key's own USD spend cap is a separate condition:
it returns 402 with the code key_limit_exceeded. See
cap what an API key spends.
On a 429, wait and retry with a growing delay rather than
hammering the endpoint. A simple pattern:
async function withRetry(call, tries = 4) {
for (let attempt = 0; attempt < tries; attempt++) {
const res = await call();
if (res.status !== 429) return res;
await new Promise((r) => setTimeout(r, 2 ** attempt * 1000));
}
throw new Error("rate limited after retries");
}The JavaScript SDK throws a typed RateLimitError you can
catch directly. See the SDK quickstart.
Related articles
REST API
Authentication, versioning, response shapes, pagination, and errors for the idapt REST API, plus the full endpoint list.
API keys and scopes
Create a key, choose its scopes, pin it to an API version, rotate it, and cap what it can spend.
Notifications API
Send notifications to workspace members and manage your inbox programmatically.
Automations and webhooks
Run an agent on a schedule, or fire one from an external system with a signed webhook.
Was this helpful?
{
"error": {
"type": "rate_limit",
"message": "Too many requests",
"code": "completions_per_minute"
}
}{
"error": {
"type": "rate_limit",
"message": "Too many requests",
"code": "completions_per_minute"
}
}async function withRetry(call, tries = 4) {
for (let attempt = 0; attempt < tries; attempt++) {
const res = await call();
if (res.status !== 429) return res;
await new Promise((r) => setTimeout(r, 2 ** attempt * 1000));
}
throw new Error("rate limited after retries");
}async function withRetry(call, tries = 4) {
for (let attempt = 0; attempt < tries; attempt++) {
const res = await call();
if (res.status !== 429) return res;
await new Promise((r) => setTimeout(r, 2 ** attempt * 1000));
}
throw new Error("rate limited after retries");
}