Error codes
Errors are JSON: { "error": "<code>", "message": "…" }. Only 2xx responses are ever settled.
| Status | error | Charged | Meaning / what to do |
|---|---|---|---|
400 | invalid_request | No | Body or query failed validation. details lists each issue. Fix and retry. |
400/404/422 | invalid_request | No | TinyFish rejected the input. Details are in upstream. |
402 | Payment required | No | No payment attached. Read PAYMENT-REQUIRED, sign, retry. x402 clients do this automatically. |
402 | invalid_exact_evm_insufficient_balance | No | Your USDT balance is below the price. |
402 | invalid_exact_evm_* | No | Bad signature, wrong domain, expired or reused authorization. Check extra and chain ID 1874. |
429 | rate_limited | No | More than RATE_LIMIT_PER_MIN requests per IP. Honor Retry-After. |
502 | upstream_failed | No | TinyFish failed, or an agent run ended FAILED (see error.category). Safe to retry once. |
502 | all_failed | No | Fetch: every URL failed. Per-URL errors are in errors. |
503 | service_unavailable | No | The upstream provider isn't available on this deployment. reason says why: operator_key_missing, operator_key_rejected or operator_out_of_credits (the operator has to fix these), or upstream_busy (retry later). |
504 | upstream_timeout | No | Upstream didn't answer in time. |
5xx | settlement error | No | The facilitator couldn't settle. The response is withheld and nothing is transferred. |
Client-side errors
These are thrown by @x402/fetch before anything is sent:
| Message contains | Cause |
|---|---|
spend control / no allowed payment requirements | The server asked for an asset, network or amount outside your spendControls. |
Failed to create payment payload | Signing failed, or the user rejected the request in their wallet. |
Payment already attempted | You passed a request that already had PAYMENT-SIGNATURE. |
Background jobs
Research and Datasets settle when the job is accepted. If the job later ends FAILED, CANCELLED or TIMED_OUT, the poll endpoint reports it, but the payment is not reversed automatically.
SSE
/api/v1/agent/run-sse returns 402 and 400 as normal JSON responses before the stream opens. After it opens, failures arrive as:
text
event: error
data: {"error":"run_failed","message":"…","charged":false}