Problem details
Every error from the API is a problem details object (RFC 9457), sent as application/problem+json with the HTTP status:
{
"type": "https://agents.chesly.app/docs/errors#rate_limited",
"title": "Too many requests.",
"status": 429,
"detail": "This API key made more than 600 requests in one minute. Retry in 4 s.",
"code": "rate_limited",
"request_id": "571d003e-ad60-4a08-858a-b7b5353f39db",
"retry_after": 4
}
typelinks to the code's section on this page.titleis fixed for each of the API's codes, anddetailexplains this occurrence.codenever changes: branch on it, never ontitleordetail.request_idis the request'sX-Request-ID. Include it when you write to us.retry_after, in seconds, comes with most 429 and 503 answers, along with aRetry-Afterheader.- A 400
invalid_requestalso lists each problem inerrors, with a JSON Pointer to it.
The MCP server refuses a tool call with the same codes, as a tool error whose text starts with the code: chat_not_found: …. The CLI prints the API's problem as it came, and exits with the code each section names. Its own errors come in the same shape; they're under CLI errors.
400 Bad request
idempotency_key_invalid
400 · The Idempotency-Key header is not valid. · CLI exit code 1
Use 1 to 255 characters from A-Za-z0-9._:-, such as a UUID. The quoted form "…" works too.
invalid_cursor
400 · The cursor is not valid. · CLI exit code 1
Pass next_cursor from the page before, exactly as it came, with the same filters. A cursor of GET /v1/messages?since= expires 15 minutes after its first page: start again without one.
invalid_reply_to
400 · reply_to must be a message in this chat. · CLI exit code 1
reply_to must be the ID of a message in the same chat. Leave it out to send a plain message.
invalid_request
400 · The request is not valid. · CLI exit code 2
A parameter or the body is missing, unknown or out of range. detail names the first problem, and errors lists each one with a JSON Pointer to it. Sending the same request again fails the same way.
invalid_webhook_url
400 · This webhook URL can't be used. · CLI exit code 1
A webhook URL must be a public https:// address of at most 2,048 characters, with no user name or password, whose host doesn't resolve to a private, loopback or link-local address.
media_too_large
400 · The media is too large. · CLI exit code 1
The API serves and takes files of up to 50 MB (50,000,000 bytes), one per message, and the CLI refuses a bigger one before uploading it. Open a bigger file in the Chesly app.
not_a_voice_note
400 · This message is not a voice note. · CLI exit code 1
Only voice notes can be transcribed, and a voice note's type is audio.
text_too_long
400 · The text is too long for this network. · CLI exit code 1
Each network takes text up to its own length, in UTF-16 code units: Instagram 1,000, Discord 2,000, Telegram 4,096, email 100,000 and every other network 10,000. Split the text into several messages.
unsupported_chat
400 · Chesly can't send to this chat. · CLI exit code 1
This chat can't take a message from the API, and detail says why. Answer it in the Chesly app instead.
webhook_limit_reached
400 · This account has the most webhooks allowed. · CLI exit code 1
Your plan's webhooks are used: 25 on Personal, 100 on Pro. Delete one you don't use, send several event types to one URL, or switch to Pro.
401 Unauthorized
invalid_api_key
401 · The API key is missing or not valid. · CLI exit code 3
Send Authorization: Bearer ck_live_… with a key that is still active. A revoked key fails from its next request: make a new one with chesly login or in the dashboard.
402 Payment required
api_plan_required
402 · An API plan is required. · CLI exit code 6
Calls need an API plan. Start the 7-day trial at web.chesly.app/api; GET /v1/me answers without one. The CLI exits with 6.
transcription_limit_reached
402 · This period's transcription minutes are used up. · CLI exit code 6
This month's transcription minutes are used: 600 on Personal, 3,000 on Pro. Transcripts work again when the next month starts, and everything else keeps working. Switch to Pro at web.chesly.app/api for more.
403 Forbidden
forbidden
403 · This request is not allowed. · CLI exit code 1
Something other than the key's scope refused the request, and the same request will be refused again: an API key turning back on a webhook that a leaked key's revoke turned off, say, which only the dashboard can do. Write to us with the request_id if you think it should work.
insufficient_scope
403 · This API key does not allow this request. · CLI exit code 1
A read-only key can only make GET requests. Sending, marking chats read, transcribing and changing webhooks need a full-access key.
signing_key_missing
403 · The account signing key is missing. · CLI exit code 1
Your account's signing key has to be restored before Chesly can read your chats. Open the Chesly app and sign in again, then retry.
404 Not found
account_not_found
404 · Account not found. · CLI exit code 4
None of your connected accounts has this ID. GET /v1/accounts lists them.
chat_not_found
404 · Chat not found. · CLI exit code 4
None of your chats has this ID: chat IDs belong to one user, so take one from GET /v1/chats. The CLI raises it too, when a chat name matches nothing; chesly chats lists the names.
key_not_found
404 · API key not found. · CLI exit code 4
None of your API keys has this ID. GET /v1/keys lists them.
media_not_found
404 · Media not found. · CLI exit code 4
No media has this ID. Use a message's media.id as it came.
message_not_found
404 · Message not found. · CLI exit code 4
No message of yours has this ID. Use message IDs as the API gave them, in answers and events.
not_found
404 · Not found. · CLI exit code 4
No endpoint matches this method and path. IDs go in the path, filters in the query.
webhook_not_found
404 · Webhook not found. · CLI exit code 4
None of your webhooks has this ID. GET /v1/webhooks lists them.
408 Request timeout
upload_timeout
408 · The upload took too long to arrive. · CLI exit code 5
The file didn't arrive in time: an upload has 60 seconds, and must keep up 50 KB a second once its first 10 are over. Your next upload can start in 60 seconds; send it again over a faster connection.
409 Conflict
account_reconnect_required
409 · This account needs to be reconnected. · CLI exit code 1
This account was disconnected on its network. Reconnect it in the Chesly app, then retry.
already_subscribed
409 · You already have an API plan. · CLI exit code 1
You already have an API plan. Manage it at web.chesly.app/api.
idempotency_in_progress
409 · A request with this Idempotency-Key is still running. · CLI exit code 5
The first request with this Idempotency-Key hasn't finished. Wait for Retry-After (1 second), then send the same request with the same key: you get its answer once it's done.
message_request
409 · This chat is a message request. · CLI exit code 1
The API reads message requests but never answers them, because a reply would accept the request on the network. Accept it in the network's own app first.
plan_change_in_progress
409 · A change to your plan is already under way. · CLI exit code 1
Another request is changing your plan right now, such as a second click on Keep plan in the dashboard. Wait a second and look again: the change is usually done.
terms_changed
409 · The API Terms changed. · CLI exit code 1
The API Terms changed since you opened them. Read and accept the current version, then try again.
410 Gone
events_expired
410 · These events are no longer kept. · CLI exit code 1
Events are kept for 7 days on Personal and 30 on Pro, and this after or Last-Event-ID is older. Start again without one, and catch up on what you missed with GET /v1/catch_up. chesly watch does this by itself, with an events_expired warning.
media_expired
410 · The media has expired. · CLI exit code 1
The file is no longer stored, and asking again won't bring it back.
413 Payload too large
payload_too_large
413 · The request body is too large. · CLI exit code 1
The request body is over its limit: 10 MB for a request, 1 MB for an MCP message and 4 KB for chesly login's calls. Send a file to POST /v1/media instead, up to 50 MB (50,000,000 bytes).
422 Unprocessable content
idempotency_key_reused
422 · This Idempotency-Key was used for a different request. · CLI exit code 1
This Idempotency-Key went with another method, path or body in the last 24 hours. Use a new key for a new request; reuse a key only to retry the same request.
transcription_failed
422 · This voice message could not be transcribed. · CLI exit code 1
This voice note's audio can't be transcribed: it may be damaged, or in a format the transcription doesn't read. Asking again gets the same answer.
429 Too many requests
rate_limited
429 · Too many requests. · CLI exit code 5
A key, all of your keys together, an account or the API as a whole went over a limit: the limits list them. Wait Retry-After seconds (also in retry_after), then retry. GET /v1/me shows your limits.
send_limit_reached
429 · This account's send limit is reached. · CLI exit code 5
This connected account reached its send limit: 60 an hour and 250 a day on WhatsApp, 30 an hour and 150 a day on every other network. Wait Retry-After seconds. GET /v1/me shows where each account stands.
too_many_streams
429 · Too many open event streams. · CLI exit code 5
You can keep 10 event streams open at once on Personal and 25 on Pro. Close one, or poll GET /v1/events instead.
500 Internal server error
internal_error
500 · Something went wrong on our side. · CLI exit code 1
Something failed on Chesly's side, logged under the request_id. Retry later, and if it keeps happening, write to us with the request_id. The CLI raises it too, for a failure it didn't expect.
502 Bad gateway
email_send_failed
502 · The email provider refused the message. · CLI exit code 5
Your email provider refused the message. Check the account in the Chesly app, then retry.
503 Service unavailable
api_paused
503 · The Chesly API is paused. · CLI exit code 5
Chesly has paused the API for a moment. Retry after retry_after seconds.
feed_unavailable
503 · The feed is temporarily unavailable. · CLI exit code 5
The since feed can't page right now. Retry in a moment, or ask for a stretch of time that fits one page.
media_unavailable
503 · The media is temporarily unavailable. · CLI exit code 5
The file couldn't be fetched just now. Retry after retry_after seconds when it's there, or in a moment.
network_unavailable
503 · This network is temporarily unavailable. · CLI exit code 5
Chesly has paused sending and marking read on this network to protect your accounts. Reads still work. Retry later, or do it in the network's own app.
plan_unavailable
503 · Your API plan can't be checked just now. · CLI exit code 5
Chesly couldn't read your plan just now, so it makes nothing your plan limits: a new key or a new webhook. Everything else goes on. Retry after retry_after seconds, about 5; chesly login keeps polling by itself.
search_unavailable
503 · Search is temporarily unavailable. · CLI exit code 5
Search can't answer right now. Retry in a moment; reading chats and catching up still work.
transcription_unavailable
503 · Transcription is temporarily unavailable. · CLI exit code 5
Transcription can't answer right now. Retry in a moment.
upstream_unavailable
503 · Your messages are temporarily unavailable. · CLI exit code 5
Chesly couldn't reach your messages just now. Retry after retry_after seconds, about 5.
CLI errors
The CLI raises these itself, in the same shape, with a type on this page and a code that never changes. Its problems carry their message as title, so branch on code; the titles below describe each code. In JSON mode it prints them to standard error as one line, and it exits with one of these codes:
| Exit code | Meaning |
|---|---|
0 |
Done |
1 |
An error |
2 |
A usage error: a missing argument or an unknown option, or a request the API refused as invalid_request (400) |
3 |
Not signed in: no key, a malformed one, or one the API refused (401) |
4 |
Not found (404), or a chat name that fits more than one chat |
5 |
Not final, come back to it: a limit (429), the API or a gateway briefly away (502, 503 or 504), a first attempt still running (409 idempotency_in_progress), or a send the network didn't confirm (delivery_unconfirmed: check the chat before you send it again). retry_after, when there is one, says when. |
6 |
Payment required (402): no API plan, or one of its limits reached |
When something in front of the API answers without problem details, such as the gateway during a Chesly deploy, the CLI names the error after the HTTP status: http_400, http_404, http_413, http_429, http_500, http_502, http_503 or http_504, and http_error for any other status.
access_denied
CLI · The sign-in was denied.
Someone chose Deny on the approval page, so nothing was stored. Run chesly login again.
ambiguous_chat
CLI · The chat name matches more than one chat.
The error lists the chats that match as candidates. Use one of their chat IDs instead of the name.
credentials_file_error
CLI · The credentials file couldn't be read or written.
chesly logout couldn't remove ~/.config/chesly/credentials.json. Check the file's permissions, or delete it yourself.
delivery_failed
CLI · The network did not take the message.
chesly send --wait saw the network refuse the message for certain (delivery.error.certain is true), and the error says why. Fix what it names before you send again. The CLI exits with 1.
delivery_unconfirmed
CLI · The network didn't confirm the message, so it may have been delivered.
chesly send --wait saw the send fail without the network confirming it (certain: false: a timeout, or an unknown error), so the message may have been delivered. Check the chat before you send it again. The CLI exits with 5.
expired_token
CLI · The sign-in code expired.
A sign-in link lasts 10 minutes. Run chesly login again and approve the new link.
file_unreadable
CLI · The file can't be read.
The CLI can't read the file --file names. Check its path and its permissions.
http_400
CLI · HTTP 400 · Bad Request, without details.
Something in front of the API refused the request without details. Check CHESLY_API_URL if you set it, then retry.
http_404
CLI · HTTP 404 · Not Found, without details.
The request reached something other than the API, which answered 404 without details. Check CHESLY_API_URL if you set it.
http_413
CLI · HTTP 413 · Payload Too Large, without details.
Something in front of the API found the request too large. A file can be up to 50 MB (50,000,000 bytes).
http_429
CLI · HTTP 429 · Too Many Requests, without details.
Too many requests, answered without details, as the sign-in's own limit does. Wait a minute, then retry.
http_500
CLI · HTTP 500 · Internal Server Error, without details.
A server error without details. Retry in a moment, and if it keeps happening, write to us.
http_502
CLI · HTTP 502 · Bad Gateway, without details.
The gateway in front of the API got no answer from it, as happens for a few seconds during a Chesly deploy. Retry in a few seconds.
http_503
CLI · HTTP 503 · Service Unavailable, without details.
The gateway in front of the API answered that it is unavailable. Retry in a few seconds.
http_504
CLI · HTTP 504 · Gateway Timeout, without details.
The gateway in front of the API gave up waiting for it. Retry in a few seconds.
http_error
CLI · An HTTP error without details.
An HTTP error without details, with a status the codes above don't name: status says which. Check CHESLY_API_URL if you set it, then retry later.
invalid_api_url
CLI · CHESLY_API_URL is not a usable API URL.
CHESLY_API_URL must be an http:// or https:// URL, such as https://api.chesly.app. Fix it, or unset it to use Chesly's.
invalid_key_format
CLI · The API key is not well formed.
A key is ck_live_ and 48 letters, digits, _ or -. Check CHESLY_API_KEY, the stored key or the key you gave chesly login --key -, or run chesly login again. A malformed CHESLY_API_KEY or stored key exits with 3, and one given to --key - with 2.
invalid_response
CLI · The API's answer is not what the CLI expects.
Something other than the Chesly API answered, such as a proxy or a wrong CHESLY_API_URL. Check the URL, then retry.
keychain_error
CLI · The OS keychain refused.
The OS keychain refused to read or change the key. Unlock it, or set CHESLY_API_KEY instead.
keychain_timeout
CLI · The OS keychain didn't answer in time.
The keychain didn't answer within 10 seconds: it may be locked, or waiting for someone to answer a dialog. Unlock it or answer the dialog, then retry, or set CHESLY_API_KEY.
login_not_started
CLI · No sign-in is waiting to finish.
chesly login --wait found no sign-in waiting to finish. Run chesly login --no-wait first, then chesly login --wait within 10 minutes.
network_error
CLI · The CLI couldn't reach the API.
The request got no answer: no connection, a DNS failure or a timeout. Check your connection, and CHESLY_API_URL if you set it, then retry.
not_signed_in
CLI · Not signed in.
Run chesly login, or set CHESLY_API_KEY. The CLI exits with 3.
usage_error
CLI · The command is not valid.
An argument is missing or an option is unknown. Run the command with --help. The CLI exits with 2.
CLI warnings
The CLI prints a warning on standard error and goes on: a warning never changes the exit code. In JSON mode each is one line, {"warning": "<code>", "message": "…"}.
delivery_wait_failed
Warning · The message was sent, but following its delivery failed.
The message went out, but following its delivery failed: a 401 or a 402 on a check, say. The command still exits with 0, and the warning carries the idempotency_key that asks the API for its answer again.
env_key_set
Warning · CHESLY_API_KEY wins over the key login stored.
CHESLY_API_KEY is set, so the CLI uses it rather than the key chesly login stored. Unset it to use the stored key.
event_too_large
Warning · An event too large to read was skipped.
An event too large to read ended the stream twice in a row, so chesly watch went on after it. The warning names its ID.
events_expired
Warning · The resume point is no longer kept, so watching starts from now.
chesly watch was asked to resume from a point older than your plan keeps events (7 days on Personal, 30 on Pro), so it starts from new events. chesly catchup shows what you missed.
invalid_event
Warning · An event the CLI could not read was skipped.
chesly watch skipped an event it couldn't read, and goes on.
key_details_unavailable
Warning · The new key's details didn't load.
chesly login stored the new key, but its details didn't load, so key is null. chesly whoami shows them.
key_still_active
Warning · A key this CLI no longer uses is still active.
A key this CLI no longer uses still works. The warning names it by its ID, first 12 and last 4 characters: revoke it with chesly keys revoke <key_id>, or in the dashboard.
reconnecting
Warning · The event stream dropped and is reconnecting.
The event stream dropped. chesly watch reconnects by itself, after 3 seconds and then longer, up to 30, and resumes after the last event it had.