Error format, codes and how to handle them.
Errors use standard HTTP status codes and a JSON body:
{
"error": {
"type": "permission_denied",
"message": "User marja@example.com does not have access to knowledge base kb_01j9…",
"request_id": "req_01j9x…",
"doc_url": "https://www.brewmycode.com/docs/api/errors#permission_denied"
}
}
Include request_id when contacting support.
| Status | type | Meaning |
|---|---|---|
| 400 | invalid_request | Malformed body or parameters; message explains which |
| 401 | unauthenticated | Missing or invalid API key |
| 403 | permission_denied | Key lacks a scope, or as_user lacks access |
| 404 | not_found | Resource doesn't exist or isn't visible to you |
| 409 | conflict | Duplicate name, or version already promoted |
| 422 | unprocessable | Valid syntax but semantically invalid (e.g. approval policy references unknown tool) |
| 429 | rate_limited | See Rate limits; retry after Retry-After seconds |
| 500 | internal_error | Our fault; safe to retry with backoff |
| 503 | unavailable | Temporary; retry with backoff |
POST requests that create resources or trigger runs accept an Idempotency-Key header. Repeating a request with the same key within 24 hours returns the original response instead of creating a duplicate.
SDKs retry 429, 500 and 503 with exponential backoff (up to 3 attempts by default). Do not retry 4xx other than 429.