Guide
Errors
Every REST failure has the same shape and a stable code. Match on the code, not the message.
{
"error": {
"code": "insufficient_credits",
"message": "Not enough credits. Balance is 2. Buy more at https://trypitch.co/pricing.",
"balance": 2
}
}code and message are always present. Some codes add a field, like balance above. Messages are written for people and may change. Codes will not.
#Codes
| Status | Code | What happened | What to do |
|---|---|---|---|
| 400 | invalid_request | A field is missing, the wrong type, or out of range. The message names the field. | Fix the body. Retrying will not help. |
| 401 | unauthorized | The key is missing, unknown, or revoked. | Check the header and the keys page. |
| 402 | insufficient_credits | The balance cannot cover the project. Nothing was created or charged. | Top up, then retry the same request. |
| 404 | not_found | No project with that id, or it belongs to someone else. | Check the id. We do not distinguish the two cases. |
| 409 | busy | You sent a prompt while the agent was still on the previous one. | Poll until status is no longer working, then send it again. |
| 413 | payload_too_large | The decoded file is over the limit. | Compress or trim the file. |
| 415 | unsupported_media_type | The extension is not accepted. | Convert it first. |
| 500 | internal_error | Something broke on our side. | Retry with backoff. If it persists, email support. |
#What is safe to retry
There are no idempotency keys yet, so a retried create can make a second project. Retry creates only when you never got a response at all, and check the project list first. Retrying a prompt can queue the same metered edit twice.
| Case | Retry? |
|---|---|
GET | Yes, always safe |
| 400, 401, 402, 404, 413, 415 | No, fix the cause first |
| 409 on a prompt | Yes, after the current turn ends |
| 500 on a read | Yes, with backoff |
| 500 on a create | Check GET /v1/projects first. The project may exist. |
| No response, timeout | Same. List projects before firing again. |
#Project failure is not an HTTP error
A project whose agent fails still returns 200. The failure is in the body.
{
"id": "cm4x8k2p90001abcd",
"status": "failed",
"error": "The agent finished without producing anything",
"outputs": []
}Common causes: the URL is behind a login, blocked our browser, or was down. Sites that need a sign-in cannot be demoed from a public URL alone. Send a follow-up prompt to have the agent try again in the same project.
#Errors over MCP
MCP has no status codes. A failed tool call returns a normal result with isError: true and the message as text, so the agent can read it and react. An insufficient-credits error carries the balance in the same string.
{
"isError": true,
"content": [
{
"type": "text",
"text": "Insufficient credits: your current balance is 35. Buy more at https://trypitch.co/pricing, then retry."
}
]
}A bad key is the exception. That fails before MCP is reached, so the client sees a plain 401 and usually reports the server as unreachable.