API Reference
Error Codes
Error shapes, status codes, and handling behavior.
All errors follow a consistent shape:
{ "error": "ERROR_CODE", "message": "Human readable description" }Error reference
| HTTP | Code | When |
|---|---|---|
400 | VALIDATION_ERROR | Missing/invalid params, unknown model, amount too low, thinking/reasoning_effort not allowed |
401 | UNAUTHORIZED | Missing/invalid API key or SIWE signature |
402 | INSUFFICIENT_BALANCE | Not enough credit for the estimated cost |
404 | NOT_FOUND | Resource not found |
429 | RATE_LIMITED | Per-wallet rate limit exceeded |
500 | INTERNAL_ERROR | Server error |
502 | UPSTREAM_ERROR | LLM provider failed or timed out |
Detailed examples
Insufficient Balance (402)
Returned when balance can't cover the reserved cost estimate.
{
"error": "INSUFFICIENT_BALANCE",
"message": "Insufficient balance. Top up at POST /v1/topup"
}Rate Limited (429)
Returned when per-wallet sliding window limits are exceeded.
{
"error": "RATE_LIMITED",
"message": "Rate limit exceeded"
}Validation Error (400)
{
"error": "VALIDATION_ERROR",
"message": "Thinking/reasoning models are not supported"
}Upstream Error (502)
Returned when the LLM provider fails. The balance lock is released (no charge).
{
"error": "UPSTREAM_ERROR",
"message": "Provider returned an error"
}Error handling behavior
| Scenario | Behavior |
|---|---|
| Insufficient balance | HTTP 402 with top-up instructions and current balance |
| Provider down | Release lock, return 502, no balance deducted |
| Invalid model | Return 400, release lock, no balance deducted |
| Rate limited | Return 429, no balance deducted |
| Invalid API key | Return 401 |
| Expired/invalid SIWE | Return 401 |
| Top-up below minimum | Return 400 before issuing 402 |