Error codes
Identify request, dataset, and payment errors and decide when to retry.
The dataset and agent HTTP APIs return application errors in this JSON format.
Use error.code to handle them in client code:
{
"error": {
"code": "QUERY_TOO_LONG",
"message": "'query' too long (max 2000 chars)",
"details": { "field": "query", "max": 2000 }
}
}Payment responses from x402 can use a different body format. For a 402
payment challenge, read the PAYMENT-REQUIRED header. A subscription-related
402 instead uses error.code, such as SUBSCRIPTION_REQUIRED or QUOTA_EXHAUSTED,
and does not ask for a wallet signature.
Public dataset queries
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | INVALID_JSON | Body cannot be parsed as a JSON object | Send a JSON object |
| 400 | MISSING_QUERY | query is absent, not a string, or empty | Provide a non-empty query |
| 400 | QUERY_TOO_LONG | query exceeds 2000 characters | Shorten the query |
| 400 | INVALID_TOP_K | top_k is not a number in the range 1–20 | Use an integer between 1 and 20 |
| 402 | — | Payment is required or could not be completed | Read the payment requirements and check the authorization; see Paying with x402 |
| 402 | SUBSCRIPTION_REQUIRED | This dataset has disabled x402 | Use the authenticated agent endpoint with a subscription; read the links in error.details |
| 404 | NOT_FOUND | No published dataset at this username and slug | Find a dataset through Explore or MCP |
| 409 | PAYOUT_NOT_CONFIGURED | Creator's payout wallet is missing or invalid | The creator must resolve this; use another dataset meanwhile |
| 409 | DATASET_EMPTY | Dataset has no indexed content | Retry later or choose another dataset |
| 409 | PAYMENT_IN_FLIGHT | The signed payment is locked, usually by a request still in progress | Wait for the active request's result before deciding whether to retry |
| 429 | RATE_LIMITED | Requests are temporarily limited | Wait for the number of seconds in Retry-After |
| 500 | SEARCH_FAILED | Search could not complete | Retry with increasing delays between attempts |
| 500 | PAYMENT_FAILED | Payment infrastructure failed; settlement may be uncertain | Check the payment outcome before retrying; an in-flight authorization may remain temporarily locked |
Subscription and agent APIs
These statuses apply to HTTP routes under /api/agent. With MCP, a billing
failure inside a tool call sets isError: true and includes the error object in
its text content; the HTTP response alone does not indicate tool success.
| Status | Code | What to do |
|---|---|---|
| 400 | VALIDATION_ERROR | Check the tool schema or HTTP query fields |
| 401 | UNAUTHORIZED | Connect or reconnect through OAuth using the account that owns the subscription; ordinary login tokens are not accepted |
| 402 | SUBSCRIPTION_REQUIRED | Check access and complete payment for an available offer; pending Checkout is not paid access |
| 402 | QUOTA_EXHAUSTED | Wait for the next paid period or explicitly choose the x402 alternative, if offered |
| 404 | NOT_FOUND | Check the dataset reference and account; a retiring dataset is available only while the account has paid access |
| 409 | DATASET_EMPTY | The dataset has no indexed content; the creator must resolve this |
| 409 | REQUEST_IN_FLIGHT | Wait, then retry the identical query with the same request ID |
| 409 | IDEMPOTENCY_CONFLICT | Use the original parameters for a retry, or a new ID for a new query |
| 409 | RESERVATION_EXPIRED | Retry the identical query with the same request ID |
| 409 | BILLING_IN_FLIGHT | A billing operation is running; retry after a delay |
| 409 | CHECKOUT_RECONCILING | Stripe payment status is being checked; wait and retry the subscription request |
| 409 | OFFER_UNAVAILABLE | Fetch the offer again; it may have changed or the dataset may be retiring |
| 409 | SELLER_UNAVAILABLE | The creator cannot accept subscription payments yet |
| 410 | RESULT_EXPIRED | The saved response expired; a new query needs a new ID and consumes quota |
| 429 | RATE_LIMITED | Respect HTTP Retry-After, or error.details.retry_after for a quota-query tool error |
| 500 | SEARCH_FAILED | Search failed and its reservation was released; retry with the same ID |
| 500 | BILLING_FAILED | The operation's outcome may be uncertain; recheck access or retry a query with the same ID |
| 503 | BILLING_UNAVAILABLE | Subscription payments or agent access are not configured in this environment |
For SUBSCRIPTION_REQUIRED and QUOTA_EXHAUSTED from a subscription query,
error.details includes the access quote and available payment options. No
additional payment is made automatically. A 401 agent HTTP response includes
an OAuth challenge in WWW-Authenticate.
Creator subscription settings
| Status | Code | What to do |
|---|---|---|
| 409 | STRIPE_ACCOUNT_NOT_READY | Complete Subscriptions → Selling → Stripe setup, then check its status |
| 409 | SUBSCRIPTION_NOT_READY | Configure an active offer and a ready Stripe account before publishing a subscription-only dataset |
| 409 | DATASET_RETIRING | Wait until retirement finishes before changing payment options |
| 409 | PAID_ACCESS_PROTECTED | Retire the dataset and preserve its content until subscriptions close and paid access ends |
See Publish your first dataset for all publication requirements.
Notes for x402 agents
- Validation errors, missing datasets, dataset precondition failures, rate
limits, and
SEARCH_FAILEDresponses do not settle a payment. - Send one request at a time with a given signed payment. Concurrent requests
using it can receive
PAYMENT_IN_FLIGHT. If the active request failed without settlement, its authorization remains unspent and can be retried while it is still valid. A successful payment cannot be reused. - An initial
402is the payment challenge. If a signed request also returns402, check the current requirements, network, USDC balance, and authorization validity. See the FAQ.