Errors
tools402 returns errors as JSON with an error field (machine-readable code)
and an optional message or per-error fields. The HTTP status code tracks
the standard HTTP semantics. Below is the full canonical list.
#Buyer-side errors (calling /v1/<seller-slug>/<path>)
| HTTP | error code | Meaning | Action |
|------|-------------------------------|--------------------------------------------------------------------|---------------------------------------------------------------------------------------|
| 402 | X-PAYMENT header is required| Normal first response : the call requires payment | Pay then retry with X-Payment header |
| 402 | payment_unconfirmed | Tx hash not yet visible on-chain | Wait one block (~1.2 s Base, ~2 s Polygon, sub-second Solana), retry same X-Payment |
| 402 | amount_mismatch | Paid less than maxAmountRequired | Pay the correct amount, rebuild X-Payment, retry |
| 402 | wrong_recipient | Tx sent to wrong payTo address | Re-pay to the correct address from the quote |
| 402 | wrong_asset | Tx used wrong USDC contract (e.g. USDC.e instead of native) | Pay using the asset field from the quote |
| 402 | quote_expired | Quote maxTimeoutSeconds elapsed since 402 was issued | Re-quote from step 1. Previous USDC is lost (no off-chain refund) |
| 404 | endpoint_not_found | Path doesn't exist in the marketplace catalog | Check /v1/_meta for live endpoints |
| 409 | tx_already_consumed | This tx hash was already used to authorise a call | Replay-once is enforced. Pay again, build new receipt |
| 410 | endpoint_suspended | Seller's endpoint flipped to suspended after 5xx threshold | Try later, or pick a different endpoint |
| 502 | upstream_5xx | Seller's upstream returned 5xx after settlement (proxy mode) | Not refundable. Tx hash returned in X-Tools402-Tx header for on-chain audit |
| 504 | upstream_timeout | Seller's upstream took > 30 s (proxy mode) | Not refundable. Same audit path |
| 413 | body_too_large | Request body > 50 MB (proxy mode) | Use paywall mode (seller-side) or chunk the request |
#Seller-side errors (calling /v1/_seller/*)
| HTTP | error code | Meaning | Action |
|------|-------------------------------|--------------------------------------------------------------------|---------------------------------------------------------------------------------------|
| 400 | invalid_json | Body wasn't parseable JSON | Check Content-Type: application/json, valid JSON syntax |
| 400 | invalid_input | Body missed a required field or had wrong types (Zod schema fail) | Check issues[] in response. Common cause : atomic_price as string, must be number |
| 400 | invalid_slug_format | Slug doesn't match ^[a-z0-9-]{3,32}$ | Use lowercase letters, digits, dashes only ; 3-32 chars |
| 400 | invalid_wallet | Wallet address not 0x + 40 hex chars (EVM) or not base58 (Solana) | Re-check the wallet param in the URL |
| 400 | invalid_id | Endpoint ID in DELETE wasn't a positive integer | Fetch your endpoint id from /v1/_meta |
| 400 | invalid_timestamp | Anti-replay window violated (timestamp > 300 s old or 60 s ahead) | Re-sign with fresh timestamp = floor(Date.now() / 1000) |
| 400 | seller_not_found | add_endpoint called before register | Register the slug first |
| 400 | seller_suspended | Your seller status is suspended | POST /v1/_seller/<wallet>/resume after fixing the underlying outage |
| 401 | invalid_signature | EIP-712 recovered address ≠ claimed wallet | Re-sign with the correct private key |
| 401 | missing_signature_headers | DELETE missing X-Signature or X-Timestamp headers | Include both headers |
| 401 | missing_sig_or_ts | Stats call missing sig or ts query params | Include both |
| 401 | wallet_mismatch | DELETE called with wrong wallet for the endpoint id | DELETE only your own endpoints |
| 404 | endpoint_not_found | Endpoint id doesn't exist or already deleted | Check /v1/_meta first |
| 404 | seller_not_found | Stats called for an unregistered wallet | Register first via POST /v1/_seller/register |
| 409 | slug_taken | Slug already owned by another wallet | Pick a different slug |
| 409 | wallet_already_registered | This wallet already owns a slug | One wallet = one slug. Use a different wallet for a second slug |
| 409 | path_taken | This path is already published | Use a different path_suffix |
| 413 | body_too_large | Body > 4 KB on seller register/add_endpoint | Shrink desc (max 200 chars) |
#Observability
Every error is logged server-side. For your own seller endpoints, your errors are queryable via your stats endpoint :
curl 'https://api.tools402.dev/v1/_seller/<your-wallet>/errors?sig=…&ts=…'
# → [{ "ts": …, "code": "upstream_5xx", "count": 3 }, …]For marketplace-side incidents (facilitator outage, suspended chain), check tools402.dev/status.