{
  "page": "docs/errors",
  "title": "Error codes",
  "error_codes": {
    "invalid_input": {
      "status": 400,
      "retryable": false,
      "meaning": "The request body or a field is missing or malformed.",
      "fix": "Read `message`, fix the field it names and send again."
    },
    "unauthenticated": {
      "status": 401,
      "retryable": false,
      "meaning": "No valid key or session was sent, or the key was revoked.",
      "fix": "Send `Authorization: Bearer <key>` with an active key."
    },
    "forbidden": {
      "status": 403,
      "retryable": false,
      "meaning": "You're signed in but your role can't do this.",
      "fix": "Ask an org owner."
    },
    "not_found": {
      "status": 404,
      "retryable": false,
      "meaning": "The thing you asked for doesn't exist or isn't yours.",
      "fix": "Check the ID."
    },
    "rate_limited": {
      "status": 429,
      "retryable": true,
      "meaning": "Too many requests in a short time.",
      "fix": "Wait and retry. Limits are in the `RateLimit-*` headers."
    },
    "invalid_token": {
      "status": 401,
      "retryable": false,
      "meaning": "A sign-in link or invite is invalid, used or expired.",
      "fix": "Request a new link."
    },
    "invalid_code": {
      "status": 400,
      "retryable": false,
      "meaning": "The phone verification code is wrong or expired.",
      "fix": "Request a new code."
    },
    "phone_in_use": {
      "status": 409,
      "retryable": false,
      "meaning": "This phone number is already verified on another account.",
      "fix": "Use a different number or sign in to the other account."
    },
    "email_unverified": {
      "status": 403,
      "retryable": false,
      "meaning": "The email address isn't verified yet.",
      "fix": "Open the sign-in link we emailed."
    },
    "phone_unverified": {
      "status": 403,
      "retryable": false,
      "meaning": "An org needs a verified phone number first.",
      "fix": "Verify your phone, then create the org."
    },
    "ip_not_allowed": {
      "status": 403,
      "retryable": false,
      "meaning": "The agent key has an IP allowlist and this request came from elsewhere.",
      "fix": "Call from an allowed IP or update the allowlist."
    },
    "unknown_tool": {
      "status": 404,
      "retryable": false,
      "meaning": "No tool with that ID or slug.",
      "fix": "List tools with `GET /v1/tools`."
    },
    "unknown_task_type": {
      "status": 400,
      "retryable": false,
      "meaning": "Not one of the seven task types.",
      "fix": "List them with `GET /v1/task-types`."
    },
    "live_execute_unavailable": {
      "status": 501,
      "retryable": false,
      "meaning": "Live purchases aren't open yet.",
      "fix": "Use a test key (`sk_test_…`) until launch."
    },
    "credits_frozen": {
      "status": 403,
      "retryable": false,
      "meaning": "Arettic has frozen this org's credits while we look into something on the account.",
      "fix": "Email support. Reads still work; purchases resume once the freeze is lifted."
    },
    "insufficient_credits": {
      "status": 402,
      "retryable": false,
      "meaning": "The org's credit balance can't cover this purchase.",
      "fix": "Top up credits or lower `max_price`."
    },
    "over_budget": {
      "status": 402,
      "retryable": false,
      "meaning": "The agent's monthly budget can't cover this purchase.",
      "fix": "Raise the budget or wait for the next UTC month."
    },
    "approval_required": {
      "status": 202,
      "retryable": false,
      "meaning": "The purchase is over the agent's approval threshold or budget.",
      "fix": "Retry with `approval_id` after an owner approves. Approvals expire in 24 hours."
    },
    "approval_expired": {
      "status": 409,
      "retryable": false,
      "meaning": "The approval is older than 24 hours.",
      "fix": "Request a new approval."
    },
    "approval_rejected": {
      "status": 403,
      "retryable": false,
      "meaning": "An owner declined this purchase.",
      "fix": "Don't retry it; ask the owner, or change the request."
    },
    "trial_limit": {
      "status": 429,
      "retryable": true,
      "meaning": "Orgs that haven't topped up yet can spend up to 50 trial credits an hour.",
      "fix": "Wait for the hour to pass, or top up to remove the limit."
    },
    "approval_mismatch": {
      "status": 409,
      "retryable": false,
      "meaning": "The tool, input or amount differs from what was approved.",
      "fix": "Send exactly the approved request, or request a new approval."
    },
    "plan_limit": {
      "status": 402,
      "retryable": false,
      "meaning": "Your plan's limit on agents, seats or lookups is reached.",
      "fix": "Upgrade the plan or wait for the daily reset."
    },
    "not_purchasable": {
      "status": 409,
      "retryable": false,
      "meaning": "The tool is listed for information only, or isn't live yet, so it can't be bought.",
      "fix": "Pick a purchasable tool from POST /v1/recommend (purchasable: true)."
    },
    "price_above_max": {
      "status": 402,
      "retryable": false,
      "meaning": "The price for this request (price × inputs) is above your max_price.",
      "fix": "Raise max_price, send fewer inputs, or pick a cheaper tool."
    },
    "tool_paused": {
      "status": 409,
      "retryable": false,
      "meaning": "The tool is paused (outage, loss-making price or provider issue).",
      "fix": "Use `fallback: true` or pick another tool from `recommend`."
    },
    "provider_error": {
      "status": 502,
      "retryable": true,
      "meaning": "The provider failed after one retry. Nothing was charged.",
      "fix": "Retry later or use `fallback: true`."
    },
    "check_failed": {
      "status": 200,
      "retryable": false,
      "meaning": "The result didn't pass the published check. Nothing was charged.",
      "fix": "Read `reason`; try another tool or fix the input."
    },
    "request_in_progress": {
      "status": 409,
      "retryable": true,
      "meaning": "A request with this idempotency_key is still running.",
      "fix": "Retry in a few seconds with the same key to get its receipt."
    },
    "provider_quota": {
      "status": 429,
      "retryable": true,
      "meaning": "Your org reached today's call limit for this provider.",
      "fix": "Use another tool for the task, or wait for 00:00 UTC."
    },
    "aup_limit": {
      "status": 429,
      "retryable": false,
      "meaning": "The request looks like bulk collection of personal data, which provider terms forbid.",
      "fix": "Contact support if this is legitimate research."
    },
    "idempotency_conflict": {
      "status": 409,
      "retryable": false,
      "meaning": "The idempotency key was reused with a different request.",
      "fix": "Use a new key for a new request."
    },
    "reason_required": {
      "status": 400,
      "retryable": false,
      "meaning": "This action needs a written reason (it goes in the audit log).",
      "fix": "Send `reason`."
    },
    "conflict": {
      "status": 409,
      "retryable": false,
      "meaning": "Something with that slug or email already exists.",
      "fix": "Use a different value."
    },
    "unverified_email": {
      "status": 401,
      "retryable": false,
      "meaning": "Google hasn't verified this email address.",
      "fix": "Sign in with an email link instead."
    },
    "invalid_state": {
      "status": 400,
      "retryable": false,
      "meaning": "The Google sign-in took too long or was opened in another browser.",
      "fix": "Start Google sign-in again."
    },
    "google_failed": {
      "status": 401,
      "retryable": true,
      "meaning": "Google didn't complete the sign-in.",
      "fix": "Try again, or use an email link."
    },
    "not_configured": {
      "status": 503,
      "retryable": false,
      "meaning": "This feature isn't switched on in this environment.",
      "fix": "Use another sign-in method."
    },
    "invalid_amount": {
      "status": 400,
      "retryable": false,
      "meaning": "A credit amount is zero, negative or otherwise invalid.",
      "fix": "Send a positive whole number of credits."
    },
    "capture_exceeds_hold": {
      "status": 409,
      "retryable": false,
      "meaning": "Internal: a charge was larger than the credits held for it. It was blocked.",
      "fix": "Nothing to do on your side; it's logged for us."
    },
    "not_a_hold": {
      "status": 409,
      "retryable": false,
      "meaning": "Internal: a settlement pointed at something that isn't a hold. It was blocked.",
      "fix": "Nothing to do on your side; it's logged for us."
    },
    "already_settled": {
      "status": 409,
      "retryable": false,
      "meaning": "This purchase was already charged or refunded.",
      "fix": "Fetch the receipt instead of retrying."
    },
    "invalid_credentials": {
      "status": 401,
      "retryable": false,
      "meaning": "Admin sign-in failed: email, password or code is wrong.",
      "fix": "Check all three. Five failures lock the account for 15 minutes."
    },
    "locked": {
      "status": 429,
      "retryable": true,
      "meaning": "Admin account locked after too many failed sign-ins.",
      "fix": "Wait 15 minutes."
    },
    "weak_password": {
      "status": 400,
      "retryable": false,
      "meaning": "Admin passwords need at least 14 characters.",
      "fix": "Use a longer password."
    },
    "resale_rights_missing": {
      "status": 409,
      "retryable": false,
      "meaning": "Admin: a tool can't be sold until its provider's resale rights are signed.",
      "fix": "Record the signed agreement on the provider, or list the tool as info-only."
    },
    "price_missing": {
      "status": 409,
      "retryable": false,
      "meaning": "Admin: a tool needs a price per success before it can be sold.",
      "fix": "Set `price_per_success_credits`."
    },
    "tool_unavailable": {
      "status": 409,
      "retryable": false,
      "meaning": "The tool can't be used for this right now: it's paused, has no price yet, or has no working provider connection.",
      "fix": "Pick another tool, or try again later."
    },
    "adapter_not_ready": {
      "status": 409,
      "retryable": false,
      "meaning": "Admin: the tool has no working provider connection (no adapter, or its API key isn't set).",
      "fix": "Add the provider key to .env, then run npm run providers:check."
    },
    "benchmark_missing": {
      "status": 409,
      "retryable": false,
      "meaning": "Admin: a tool must be benchmarked in the last 35 days before it can be sold.",
      "fix": "Run a benchmark for the tool."
    },
    "below_accuracy_floor": {
      "status": 409,
      "retryable": false,
      "meaning": "Admin: the tool's latest benchmark accuracy is under the 60% floor.",
      "fix": "Keep it info-only, or re-run after the provider improves."
    },
    "not_disputable": {
      "status": 409,
      "retryable": false,
      "meaning": "The item wasn't charged, so there's nothing to dispute.",
      "fix": "Only charged (passed or partial) items can be disputed."
    },
    "dispute_window_closed": {
      "status": 409,
      "retryable": false,
      "meaning": "Disputes must be opened within 7 days of the purchase.",
      "fix": "Contact support if you think this item was charged in error."
    },
    "topup_cap": {
      "status": 402,
      "retryable": false,
      "meaning": "New accounts can add up to $200 of credits in their first 14 days.",
      "fix": "Top up a smaller amount, or wait until the account is 14 days old."
    },
    "confirmation_required": {
      "status": 409,
      "retryable": false,
      "meaning": "Admin: a large manual adjustment needs its amount confirmed.",
      "fix": "Send the same amount again in `confirm_credits`."
    },
    "offer_unavailable": {
      "status": 409,
      "retryable": false,
      "meaning": "The founding price is used up, has ended, or this org already used it.",
      "fix": "Subscribe at the list price, or check GET /v1/pricing for the offer's status."
    },
    "no_saved_card": {
      "status": 409,
      "retryable": false,
      "meaning": "Auto-reload needs a saved card, and this org has none.",
      "fix": "Top up once with `save_card: true`, then turn auto-reload on."
    },
    "payment_unavailable": {
      "status": 502,
      "retryable": true,
      "meaning": "The payment provider didn't respond as expected.",
      "fix": "Try again in a minute."
    },
    "invalid_signature": {
      "status": 400,
      "retryable": false,
      "meaning": "A webhook's signature didn't verify, so it was ignored.",
      "fix": "Check the webhook signing secret."
    },
    "method_not_allowed": {
      "status": 405,
      "retryable": false,
      "meaning": "That HTTP method isn't supported here (the MCP endpoint takes POST only).",
      "fix": "Use the method in the `Allow` header."
    },
    "fx_unavailable": {
      "status": 503,
      "retryable": true,
      "meaning": "No USD→INR exchange rate is available, so INR top-ups are paused.",
      "fix": "Pay in USD, or try again later."
    },
    "last_owner": {
      "status": 409,
      "retryable": false,
      "meaning": "An org must keep at least one owner.",
      "fix": "Make someone else an owner first."
    },
    "payload_too_large": {
      "status": 413,
      "retryable": false,
      "meaning": "The request body is over 1 MB.",
      "fix": "Send large batches as async jobs of up to 1,000 items."
    },
    "internal_error": {
      "status": 500,
      "retryable": true,
      "meaning": "Something went wrong on our side.",
      "fix": "Retry. If it keeps happening, check the status page."
    },
    "network_error": {
      "status": 0,
      "retryable": true,
      "meaning": "SDK: the request never got a response (DNS, connection reset, offline).",
      "fix": "Retry with backoff; the SDKs do this for reads and for `execute`, whose idempotency key makes a retry safe."
    },
    "timeout": {
      "status": 0,
      "retryable": true,
      "meaning": "SDK: the request hit the client's timeout before a response arrived.",
      "fix": "Retry, or raise the client's timeout for long batches (or use jobs for over 25 items)."
    },
    "connection_failed": {
      "status": 0,
      "retryable": true,
      "meaning": "MCP package: the local server couldn't reach the hosted MCP endpoint.",
      "fix": "Check ARETTIC_API_URL and your network; the call is retried once if it certainly never left."
    },
    "aborted": {
      "status": 0,
      "retryable": false,
      "meaning": "SDK: your own AbortSignal cancelled the request.",
      "fix": "Nothing to fix; send the request again when you want it."
    },
    "http_error": {
      "status": 0,
      "retryable": false,
      "meaning": "SDK: an HTTP error came back without the API's error body (a proxy, firewall or load balancer answered). The HTTP status is on the error.",
      "fix": "Check ARETTIC_API_URL and anything between you and the API. A 429 or 5xx from a proxy is reported as `rate_limited` or `internal_error` and retried."
    },
    "unexpected_redirect": {
      "status": 0,
      "retryable": false,
      "meaning": "SDK: the server answered with a redirect, which the SDKs never follow (it could leak your key).",
      "fix": "Check ARETTIC_API_URL: it should be https://api.arettic.com with no path."
    }
  }
}