Rate limits & errors

Rate limits & errors Pro

Rate limits

The API is a Pro feature. Requests are rate limited per workspace (all of a workspace's tokens share one quota - minting more doesn't raise it), and MCP tool calls count against the same quota:

WindowLimit
Reads (GET)600 / min
Writes (POST · PATCH · DELETE)120 / min
Burst (read + write)30 / sec
Daily total10,000 / day

The per-minute and burst limits cap how fast you can call; the daily total caps overall volume and resets daily at 00:00 UTC - the same instant for every workspace. Hitting the daily cap returns 429 with "Daily request quota exceeded." and a Retry-After counting down to midnight UTC. Running into these ceilings at scale? Talk to support and we'll raise them.

Every response carries the current limit state in its headers, so you can back off before you're throttled:

HeaderExampleMeaning
RateLimit-Limit600Requests allowed in the current window
RateLimit-Remaining588Requests left before you're throttled
RateLimit-Reset41Seconds until the window resets
Retry-After41Seconds to wait - only sent on a 429

When you exceed the limit the API responds with 429 Too Many Requests and a JSON body describing when to retry:

{
  "error": "rate_limited",
  "message": "Rate limit exceeded. Retry after 41s.",
  "retryAfter": 41
}

Honor the Retry-After header with exponential backoff and jitter rather than retrying immediately - tight retry loops just burn your remaining budget. Batch writes where you can.

You can watch today's usage (REST API vs MCP, split out) and the daily history in Dashboard → Settings → Workspace → API.

Abuse protection & auto-disable

A 429 is not a penalty - it just means "slow down." A well-behaved client that honors Retry-After is never punished. But a client that keeps hammering through its own 429s at a high sustained rate (ignoring Retry-After) is treated as abuse, and the token is automatically disabled.

  • Detection is rate-based: it only trips on a sustained flood of requests sent while already rate-limited (on the order of tens per second). Normal usage, and even an occasional retry after a limit, never trigger it.
  • A disabled token stops authenticating immediately (401 invalid_token), exactly like a revoked one.
  • There is no re-enable. The token shows as Disabled in Settings → Workspace → API with the reason; the fix is to delete it and create a new one. (Rotating is also the right move if a token has leaked - the disable usually means someone is misusing it.)

Honor the Retry-After header with exponential backoff and jitter. Tight retry loops don't just burn your budget - sustained ones will get the token disabled.

Log retention

Each request (REST and MCP) is recorded to a per-workspace activity log, surfaced as Recent requests on the API page. Logs are retained for 30 days, then automatically deleted - we also keep only the most recent 500 entries per workspace. The log is for observability only; it's never used for billing.

Errors

Every error shares the same JSON envelope - a machine-readable error code, a human message, and sometimes extra fields (fields, limit, retryAfter). Always branch on the HTTP status and the error code, never on message text.

Statuserror codeWhen
400invalid_requestMalformed body, missing required field, or unknown export format.
401unauthorizedNo bearer token supplied.
401invalid_tokenToken unknown, expired, or revoked.
403node_limitMap exceeds your plan's node cap.
403forbiddenFeature gated behind a higher plan.
404not_foundThe map doesn't exist in your workspace.
429rate_limitedToo many requests - back off per Retry-After.
500server_errorSomething failed on our side; safe to retry.
{
  "error": "invalid_token",
  "message": "The API token is invalid, expired, or revoked."
}

A 500 carries an X-Request-Id header - include it when you contact support so we can trace the failure. These are transient; retry with backoff.

to paste into any AI.

Ask ChatGPT about this page.

Ask Claude about this page.

Need help? Sign in to chat with support

Have ideas?

General inquiry? Email support.