KlientBrain AI VisibilityDocs

API errors and limits

What each API error code means, and how the request limits and their headers work.

When a request fails, the API answers with a status and a JSON object. For the addresses and keys, see API reference.

The error object

{
  "type": "/help/api-errors#rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "error": "rate_limited",
  "message": "Too many requests this minute. Try again in 12 seconds.",
  "requestId": "0b6f0d2e-7a41-4d6c-9f1c-2f6a1d3c8a55"
}

The object follows the standard problem details format (RFC 9457) and is sent as application/problem+json. It keeps the error and message fields the API has always sent, so a script that reads those keeps working.

  • code and error are the same short code. Test for this, not the message.
  • message says what is wrong and what to do.
  • type points at this page, at the row for the code, and title is the HTTP status in words.
  • requestId is also sent as the X-Request-Id header. Quote it if you contact support.

Codes

StatusCodeWhat it means
400bad_requestA query value is not valid, such as a date that is not YYYY-MM-DD, an unknown engine or a limit out of range
400bad_cursorThe cursor is not one the API gave you. Leave cursor out to start again
401unauthenticatedNo key was sent. Send Authorization: Bearer YOUR_KEY
401invalid_keyThe key is not shaped like one of ours, is unknown, or has been revoked
401key_expiredThe key's expiry date has passed. Generate a new key
403workspace_suspendedThe key's workspace is suspended
403no_workspaceThe key's workspace was not found
404not_foundNo such address, or no project or response with that id that this key can read
405method_not_allowedThe API only reads. Use GET
429rate_limitedA request limit is used up. Wait for Retry-After seconds
503api_not_availableThe API is not available right now
503database_not_configuredThe API is not available right now

A 401 or a 405 that is sent before the key is read has error and message only.

Codes for changes

These come only from the addresses that make changes. See Change projects through the API. A refused change changes nothing. When the app itself refuses the change (too_many, too_many_facts, domain_overlap, bad_brand, bad_competitor, bad_prompt, project_limit, prompt_limit, duplicate_prompt, not_paused, demo_project, pitch_frozen, and some conflict and bad_request answers), the answer also has "applied": false; the other refusals have no applied field.

StatusCodeWhat it means
400too_manyThe project tracks as many competitors as it can. Delete one first
400too_many_factsThe project holds as many brand facts as it can. Delete one first. Nothing was added
400bad_brandThe project's name or brand is too long or not valid. The message says which and how long it may be
400bad_competitorA competitor's name, website or other names are too long or not valid. The message says which and how long it may be
400bad_promptA prompt's text, topic or tags are too long or not valid. The message says which and how long it may be
400domain_overlapThe website is already one of another brand's other websites in this project
403insufficient_scopeThe key is read only. Make a key with the Read and write permission
403key_tied_to_projectA key tied to one project cannot create projects. Use a key for the whole workspace
403role_read_onlyThe person who made the key is no longer an Admin or Member of the workspace, so the key cannot make changes
403project_limitThe workspace has as many projects as its plan allows. Delete one, or choose a bigger plan
403prompt_limitThe project has as many active prompts as it can. Pause one first. The answer also has limit, active and room
409conflictThat brand is already tracked in this project
409own_brandThe project's own brand cannot be deleted. Change it with PATCH instead
409duplicate_promptThat prompt is already in the list: the same words in the same market
409not_pausedOnly a paused prompt can be deleted. Pause it first
409demo_projectThe demo project shows sample data and cannot be changed
409pitch_frozenThe pitch project has ended, so its markets and prompts cannot be changed

A change the app itself refuses for another reason answers bad_request, with the reason in message.

Request limits

Each workspace has an hourly quota that depends on its plan, plus a per-minute limit, shared by every key in the workspace.

HeaderMeaning
RateLimit-LimitThe requests allowed in the hourly window
RateLimit-RemainingRequests left in the window
RateLimit-ResetSeconds until the window ends
RateLimit-PolicyThe windows that apply, for example 1000;w=3600, 60;w=60: a quota and its window in seconds
Retry-AfterOn a 429, the seconds to wait

The older X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers are still sent. X-RateLimit-Reset is a time in seconds since 1 Jan 1970 (UTC), where RateLimit-Reset is a number of seconds from now.

When you get a 429, wait for Retry-After seconds and try again. Do not retry at once.

Need help?

Email support@klientbrain.com and tell us what you were doing.