Navigation
ELOWEN · Documentation

Last updated: October 27, 2026

Browse documentation · Agent API errors
Skills, MCP and API

Agent API errors

Every refused request answers with a status code and a JSON body that has an error field, so a script can decide what to do next.

The examples use the ELOWEN_URL and ELOWEN_TOKEN variables set up in Send your first agent API request.

Status codes

Status When Body
400 The request body is not valid JSON, a field has the wrong type, or it carries a field the request does not accept. { "error": "…" } describing the field
401 The token is missing, unknown, deleted or expired, or its value was replaced. { "error": "unauthorized" }
402 Your account reached its monthly spend limit. A missing model price alone does not cause this refusal. This is the account's limit, not a token limit. { "error": "spend_limit", "reason": "monthly_limit", "resetsAt": "…" }, where resetsAt is the start of the next UTC month
403 The request needs a signed-in browser session, or your account may not use it. See What a token cannot do. { "error": "forbidden" }
404 conversationId is not one of your conversations. { "error": "unknown conversation" }
409 The conversation is already running a turn. { "error": "conversation_busy" }
409 The requested model was refused. { "error": "…" }, the same message the web app shows
429 A token limit was reached. { "error": "…", "reason": "…" } and a Retry-After header
500 The turn failed, could not start, or the requested model could not be switched to. With "stream": true, a turn that could not start answers with this status instead of a stream. { "error": "…", "conversationId": "…" }
503 The agent is not available on this server. Also returned when the account's usage could not be recorded, which blocks its paid requests until an administrator reconciles usage and Chetty restarts. { "error": "brain unavailable" }, or the usage message

Branch on error, and on reason for a 429, rather than on the message text.

Limit refusals

A 429 always carries Retry-After, the number of seconds to wait, and a reason a script can act on:

error reason Meaning Retry-After
limit_exhausted requests_per_minute Too many requests this minute. Seconds until the minute is over.
limit_exhausted monthly_cost This month's cost limit is reached. Seconds until the next UTC month.
limit_unverifiable monthly_cost_unverifiable A turn this month reported no cost, so the cost limit cannot be checked. Seconds until the next UTC month.
limit_exhausted daily_cost Today's cost limit is reached. Seconds until the next UTC day.
limit_unverifiable daily_cost_unverifiable A turn today reported no cost, so the cost limit cannot be checked. Seconds until the next UTC day.
limit_exhausted concurrent_turns Too many runs are still going. 1

When more than one cost limit is reached at once, the answer names the wider window, the month before the day, so Retry-After is a time the run can actually succeed at.

curl -sS -D - "$ELOWEN_URL/api/v1/agent/runs" \
  -H "Authorization: Bearer $ELOWEN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message":"One more"}'
HTTP/1.1 429 Too Many Requests
Retry-After: 52380
Content-Type: application/json

{"error":"limit_exhausted","reason":"daily_cost"}

What a refused run counts

A run refused by a limit creates nothing: no conversation, no turn, and nothing against the token's turn count.

The same holds for a run refused because the conversation was busy, the conversation or model was unknown, or its turn could not start. A retry after the wait therefore runs as if the refused attempt had never happened.

See Cap what an API token can run to set these limits, and Send your first agent API request for a request that succeeds.