Skip to content

Errors

Updated

All errors have the same shape, and none of them costs credits. Each one tells you whether a retry can help.

The error shape

Every failed call returns JSON like this, with the matching HTTP status:

HTTP 402
{
  "error": {
    "code": "insufficient_credits",
    "message": "This call costs up to 2 credits and you have 1.",
    "retryable": false,
    "docsUrl": "https://chatterapi.com/docs/errors#insufficient_credits",
    "topupUrl": "https://chatterapi.com/dashboard/billing",
    "instructionsForAgent": "The user's ChatterAPI balance is too low for this call. Tell them and share the topupUrl. Do not retry."
  },
  "requestId": "req_01JA7Q3V8K2N4P5R6S7T8V"
}
  • code: a stable, machine-readable code. Branch on this rather than on the message.
  • message: a one-sentence description of what went wrong. For invalid_input it names the field.
  • retryable: whether the same request can succeed later.
  • docsUrl: the section of this page for that code.
  • instructionsForAgent: present on 401, 402, 403, 409 and 429. It's written for an LLM and says what to tell the user and whether to retry.
  • requestId: include it when you report a problem to support.

All codes

missing_key

HTTP 401, not retryable. The request has no Authorization: Bearer header.

response body
{
  "error": {
    "code": "missing_key",
    "message": "Add the header Authorization: Bearer <your API key>.",
    "retryable": false,
    "docsUrl": "https://chatterapi.com/docs/errors#missing_key",
    "instructionsForAgent": "Ask the user for their ChatterAPI key (it starts with ca_live_). Do not retry without one."
  },
  "requestId": "req_01JA7Q3V8K2N4P5R6S7T8V"
}

What to do: Send Authorization: Bearer ca_live_... on every request. You can create a key on the Keys page of the dashboard.

What an agent should tell the user: Ask the user for their ChatterAPI key (it starts with ca_live_). Do not retry without one.

invalid_key

HTTP 401, not retryable. The key is malformed, or no key with that value exists.

response body
{
  "error": {
    "code": "invalid_key",
    "message": "Unknown API key.",
    "retryable": false,
    "docsUrl": "https://chatterapi.com/docs/errors#invalid_key",
    "instructionsForAgent": "The API key is wrong. Ask the user to copy it again from the Keys page of their dashboard."
  },
  "requestId": "req_01JA7Q3V8K2N4P5R6S7T8V"
}

What to do: Check that you copied the whole key. Keys are ca_live_ or ca_test_ followed by 40 hex characters. A lost key can't be shown again, so create a new one.

What an agent should tell the user: The API key is wrong. Ask the user to copy it again from the Keys page of their dashboard.

key_revoked

HTTP 401, not retryable. The key was revoked from the dashboard.

response body
{
  "error": {
    "code": "key_revoked",
    "message": "This API key was revoked.",
    "retryable": false,
    "docsUrl": "https://chatterapi.com/docs/errors#key_revoked",
    "instructionsForAgent": "This API key was revoked. Ask the user to create a new key on the Keys page."
  },
  "requestId": "req_01JA7Q3V8K2N4P5R6S7T8V"
}

What to do: Create a new key and update your env var. Revoking is permanent.

What an agent should tell the user: This API key was revoked. Ask the user to create a new key on the Keys page.

account_suspended

HTTP 403, not retryable. The account behind the key is suspended.

response body
{
  "error": {
    "code": "account_suspended",
    "message": "This account is suspended.",
    "retryable": false,
    "docsUrl": "https://chatterapi.com/docs/errors#account_suspended",
    "instructionsForAgent": "This ChatterAPI account is suspended. Tell the user to contact support. Do not retry."
  },
  "requestId": "req_01JA7Q3V8K2N4P5R6S7T8V"
}

What to do: Email support with the requestId. Calls will keep failing until the account is restored.

What an agent should tell the user: This ChatterAPI account is suspended. Tell the user to contact support. Do not retry.

scope_denied

HTTP 403, not retryable. An 18+ tool (or nsfw=true) was called on an account that has not turned on 18+ tools, or a write tool was called with a read-only key.

response body
{
  "error": {
    "code": "scope_denied",
    "message": "18+ content is off for this account. Turn it on in Settings after confirming you are 18 or older.",
    "retryable": false,
    "docsUrl": "https://chatterapi.com/docs/errors#scope_denied",
    "instructionsForAgent": "This key or account isn't allowed to use this tool. Tell the user what setting is needed. Do not retry."
  },
  "requestId": "req_01JA7Q3V8K2N4P5R6S7T8V"
}

What to do: Confirm your age and turn on 18+ tools in Settings, or create a key with write access for X actions.

What an agent should tell the user: This key or account isn't allowed to use this tool. Tell the user what setting is needed. Do not retry.

invalid_input

HTTP 400, not retryable. A parameter failed validation, or the request included an unknown parameter. The message names the field.

response body
{
  "error": {
    "code": "invalid_input",
    "message": "limit: Too big: expected number to be <=100",
    "retryable": false,
    "docsUrl": "https://chatterapi.com/docs/errors#invalid_input"
  },
  "requestId": "req_01JA7Q3V8K2N4P5R6S7T8V"
}

What to do: Fix the named field. Each tool's reference page lists its parameters, types and limits. An expired cursor also returns this error, so restart from the first page.

For agents: do not retry; report the message to the user.

not_found

HTTP 404, not retryable. The user, post, subreddit, tweet or list does not exist, or the path matches no tool.

response body
{
  "error": {
    "code": "not_found",
    "message": "Not found",
    "retryable": false,
    "docsUrl": "https://chatterapi.com/docs/errors#not_found"
  },
  "requestId": "req_01JA7Q3V8K2N4P5R6S7T8V"
}

What to do: Check the id or name. Reddit account checks return a state instead of this error, so you can tell a deleted account from a suspended one.

For agents: do not retry; report the message to the user.

insufficient_credits

HTTP 402, not retryable. The balance is below the tool's cost. We check this before any upstream call.

response body
{
  "error": {
    "code": "insufficient_credits",
    "message": "This call costs up to 3 credits and you have 1.",
    "retryable": false,
    "docsUrl": "https://chatterapi.com/docs/errors#insufficient_credits",
    "topupUrl": "https://chatterapi.com/dashboard/billing",
    "instructionsForAgent": "The user's ChatterAPI balance is too low for this call. Tell them and share the topupUrl. Do not retry."
  },
  "requestId": "req_01JA7Q3V8K2N4P5R6S7T8V"
}

What to do: Top up or upgrade at the topupUrl in the error. Nothing was charged.

What an agent should tell the user: The user's ChatterAPI balance is too low for this call. Tell them and share the topupUrl. Do not retry.

rate_limited

HTTP 429, retryable. You sent more requests per second than your plan allows.

response body
{
  "error": {
    "code": "rate_limited",
    "message": "Over 10 requests per second.",
    "retryable": true,
    "docsUrl": "https://chatterapi.com/docs/errors#rate_limited",
    "instructionsForAgent": "Too many requests per second. Wait retryAfter seconds, then retry once.",
    "retryAfter": 1
  },
  "requestId": "req_01JA7Q3V8K2N4P5R6S7T8V"
}

What to do: Wait retryAfter seconds (also in the retry-after header), then retry. Spread your calls out, or upgrade for a higher limit.

What an agent should tell the user: Too many requests per second. Wait retryAfter seconds, then retry once.

upstream_error

HTTP 502, retryable. Every data provider for this tool failed.

response body
{
  "error": {
    "code": "upstream_error",
    "message": "Reddit data is temporarily unavailable. Retry in a few seconds.",
    "retryable": true,
    "docsUrl": "https://chatterapi.com/docs/errors#upstream_error"
  },
  "requestId": "req_01JA7Q3V8K2N4P5R6S7T8V"
}

What to do: Retry with exponential backoff. If a cached copy exists, you get that instead, marked with a stale_data warning.

For agents: retry with backoff, then report the failure with the requestId.

upstream_timeout

HTTP 504, retryable. The provider took longer than 15 seconds.

response body
{
  "error": {
    "code": "upstream_timeout",
    "message": "X timed out. Retry in a minute.",
    "retryable": true,
    "docsUrl": "https://chatterapi.com/docs/errors#upstream_timeout"
  },
  "requestId": "req_01JA7Q3V8K2N4P5R6S7T8V"
}

What to do: Retry with backoff. Smaller limit values return faster.

For agents: retry with backoff, then report the failure with the requestId.

x_account_required

HTTP 409, not retryable. An X write tool was called without accountId.

response body
{
  "error": {
    "code": "x_account_required",
    "message": "This X action needs accountId, the id of an X account connected in the dashboard.",
    "retryable": false,
    "docsUrl": "https://chatterapi.com/docs/errors#x_account_required",
    "instructionsForAgent": "This X action needs a connected X account. Ask the user to connect one on the Accounts page and pass its accountId."
  },
  "requestId": "req_01JA7Q3V8K2N4P5R6S7T8V"
}

What to do: Connect an X account in the dashboard and pass its id as accountId.

What an agent should tell the user: This X action needs a connected X account. Ask the user to connect one on the Accounts page and pass its accountId.

x_account_needs_reconnect

HTTP 409, not retryable. The session for the connected X account expired.

response body
{
  "error": {
    "code": "x_account_needs_reconnect",
    "message": "The connected X account needs to be reconnected.",
    "retryable": false,
    "docsUrl": "https://chatterapi.com/docs/errors#x_account_needs_reconnect",
    "instructionsForAgent": "The connected X account's session expired. Ask the user to reconnect it on the Accounts page."
  },
  "requestId": "req_01JA7Q3V8K2N4P5R6S7T8V"
}

What to do: Reconnect the account on the Accounts page, then retry.

What an agent should tell the user: The connected X account's session expired. Ask the user to reconnect it on the Accounts page.

internal

HTTP 500, retryable. This is a bug on our side. We log it with the request id.

response body
{
  "error": {
    "code": "internal",
    "message": "Something went wrong on our side. It has been logged.",
    "retryable": true,
    "docsUrl": "https://chatterapi.com/docs/errors#internal"
  },
  "requestId": "req_01JA7Q3V8K2N4P5R6S7T8V"
}

What to do: Retry once. If it keeps happening, email support with the requestId.

For agents: retry with backoff, then report the failure with the requestId.

Retry guidance

  • Retry only when retryable is true.
  • On rate_limited, wait the retry-after seconds and then retry.
  • On upstream_error, upstream_timeout and internal, use exponential backoff with jitter: roughly 0.5s, 1s, 2s, each plus a random fraction. Give up after three or four tries.
  • Never retry 400, 401, 402, 403, 404 or 409, because the same request will fail the same way.

Reporting a bug

Email support with the requestId from the response (it's also in the x-request-id header) so we can find the exact call in our logs.