# Proxies.sx error table for agents Last verified: 2026-10-28. Three families: gateway codes on a proxy connection (`CODE: message (req: )` body; quote the req id to support), purchase-API JSON errors (`{statusCode, message, code, fix, timestamp, path}`; `code` is stable, `fix` says what to do), and the x402 402 body. Support: maya@proxies.sx, https://t.me/proxies_sx. ## Gateway (gw.proxies.sx:7000 / :7001) | code | HTTP | meaning | exact fix | retryable | |---|---|---|---|---| | `E_AUTH_REQUIRED` | 407 | no `Proxy-Authorization` header | send username + proxy password (or `pak_` key) as proxy auth | yes, with auth | | `E_AUTH_INVALID` | 407 | credentials rejected; the backend reason follows the colon | set a proxy password with `PATCH /v1/account/proxy-password` (the account login password never works); check the username starts with `psx_` | after the fix | | `E_BALANCE_EXHAUSTED` | 407 | password valid, no shared GB left on the account | buy GB in the dashboard (https://client.proxies.sx/purchase) after topping up; not a password problem | after top-up | | `E_CAP_EXCEEDED` | 407 | a `pak_` key reached its GB cap | the key's owner tops it up (`pool_topup_key`, `/v1/reseller/pool-keys/:id/topup`) or an x402 session calls `/v1/x402/manage/pool/topup` | after top-up | | `E_USERNAME_PARSE` | 400 | username missing or longer than 256 chars | rebuild it: `psx_--[-rot-..][-sid-..]`; unknown tokens are dropped silently, never a 400 | with a valid username | | `E_RATE_LIMITED_AUTH` | 429 | too many failed auth attempts from this IP or account | stop retrying the same bad credential; wait 30 s (5 min after repeated bursts) | after the wait | | `E_RATE_LIMITED_CONN` | 429 | over 500 concurrent connections on the account | lower concurrency or close idle connections | yes, later | | `E_SESSION_LIMIT` | 429 | over 250 concurrent sessions (distinct `-sid-`) | reuse `-sid-` values or let sessions expire | yes, later | | `E_NO_STOCK_COUNTRY` | 502 | no online endpoints for that pool/country | read `GET /v1/gateway/pool/stock`; switch country or pool (`mbl` is only US, GB, FR, NL, PL, GE; use `peer-de`, never `mbl-de`) | with another country | | `E_STOCK_DEGRADED` | 502 | the chosen endpoint vanished mid-request | retry the request; a new endpoint is picked | yes | | `E_SSRF_BLOCKED` | 403 | target is private, localhost or cloud metadata | only public targets are allowed | no | | `E_INTERNAL` | 503 | unexpected gateway error | retry once; then open a ticket with the req id | once | `E_ACCOUNT_DISABLED` and `E_UPSTREAM_REFUSED` exist in the code but have no throw-sites; those conditions surface as `E_AUTH_INVALID` with the reason in the message. ## Purchase API (private modems, top-up, keys) | code | HTTP | meaning | exact fix | retryable | |---|---|---|---|---| | `scope_missing` | 403 | the API key lacks the scope (`modems:purchase` or `billing:topup`) | a human creates a key with that scope at https://client.proxies.sx/account (API keys) | with the new key | | `spend_cap_reached` | 403 | today's key top-ups + amount exceed `spendCapUsdPerDay` | wait for 00:00 UTC, or a human raises the cap with `PUT /v1/api-keys/:id {"spendCapUsdPerDay"}` | after reset / raise | | `invalid_amount` | 400 | top-up amount missing, below 1 or not a number | send `amount` in whole USD, at least 1 | with a valid amount | | `expected_price_required` | 400 | buy/renew without `expectedPriceUsd` | read the catalog / renewal-quote and send its `priceUsd` | yes | | `price_changed` | 409 | `expectedPriceUsd` differs from the current price (body carries `priceUsd`) | show the new price, confirm with the user, resend with the new `expectedPriceUsd` and a NEW `Idempotency-Key` | after confirmation | | `no_stock` | 409 | plan or region sold out, or quantity above stock | re-read the catalog and pick another plan | with another plan | | `insufficient_balance` | 400 | balance below the price; the order is recorded as failed and nothing is charged | top up (`POST /v1/stripe/create-balance-checkout`), then order again with a NEW `Idempotency-Key` | after top-up, new key | | `recent_checkout` (`error` field) | 409 | the same items were bought less than 2 minutes ago | if intended, resend with `"confirmAgain": true` | yes, with confirmAgain | | `recent_renewal` (`error` field) | 409 | this modem was renewed less than 2 minutes ago | if intended, resend with `"confirmAgain": true` | yes, with confirmAgain | | `renewal_open` | 409 | a renewal for this modem is in progress | wait, then `GET /v1/private-modems/mine` | yes, later | | `not_renewable` / `expired` / `dead` / `not_live` | 409 | the modem cannot be renewed or used in its state | `dead`: `POST /:id/replace` first; `expired`/`not_live`: rent a new one | no | | `not_supported` | 400 | the modem lacks that capability (OpenVPN, p0f, rotate) | check `capabilities` in `mine`; replace or pick another plan | no | | (401, no code) | 401 | missing or invalid `X-API-Key`, or a route not yet open to keys | check the key; for top-up use the dashboard https://client.proxies.sx/billing | with a valid key | | (429, no code) | 429 | route throttle (orders/renew 10 per minute, receipt 12 per minute) | wait a minute | yes | Same `Idempotency-Key` + same body = the same order back; use that for timeouts and network errors when you do not know the outcome. Use a NEW key after `price_changed` and after `insufficient_balance`. ## x402 (no account) An unpaid `GET /v1/x402/pool?...` or `/v1/x402/proxy?...` answers **402** with: ```json {"x402Version":1,"error":"Payment required","accepts":[ {"scheme":"exact","network":"base","maxAmountRequired":"4000000","resource":"https://api.proxies.sx/v1/x402/pool?tier=peer&country=us&traffic=1", "payTo":"0xF8cD900794245fc36CBE65be9afc23CDF5103042","asset":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","maxTimeoutSeconds":30}, {"scheme":"exact","network":"solana","maxAmountRequired":"4000000","payTo":"6eUdVwsPArTxwVqEARYGCh4S2qwW2zCs7jSEDRpxydnv","asset":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"}]} ``` | situation | HTTP | fix | retryable | |---|---|---|---| | 402 body above | 402 | not an error: pay `maxAmountRequired` micro-USDC (6 decimals; `4000000` = $4 = 1 GB) to `payTo` on that network, then repeat the same request with `Payment-Signature: ` | yes, with payment | | payment rejected (wrong amount, network or recipient, or a reused tx) | 402/400 | the tx hash is not consumed by a validation error: fix the query (`country`, `traffic`, `duration` are required on the paid retry) and resend the same hash; a reused or short payment needs a new transaction | depends | | `X-Session-Token` missing or unknown on `/v1/x402/manage/*` | 401 | send the `x402s_...` token from the purchase response | yes, with token |