Skip to content

Errors & status codes

Marvel keeps error surfaces narrow and category-only on purpose: you learn what to fix, never an internal detail or whether some other account’s email or key exists.

Returned by the gateway at resi.marvel.sh:9000 during CONNECT.

StatusMeaningFix
407Missing or invalid credentials — no auth, or an unknown/revoked API keyCheck the key is current and sent as the username.
400Bad target stringSee target errors for the exact reason.
402Insufficient balanceTop up a bundle; a zero balance cannot proxy.
503No live capacity for the requested country right nowCheck /v1/availability; retry or pick a live country.
502Gateway errorTransient — retry with backoff. Upstream, dial, and internal faults deliberately look identical here.

A malformed password (target string) is rejected with 400 and one of these fixed, safe reasons. The message names the category of mistake — it never echoes your raw input back.

ReasonCause
missing required target: country-<CC> (ISO 3166-1 alpha-2)No country- field.
invalid country code; expected ISO 3166-1 alpha-2, e.g. country-UScountry wasn’t two letters.
targeting is country-only; ASN/ISP selection is not supportedAn -asn- or -isp- token was present.
unknown target field; supported fields: country, session, min_purityAn unrecognized key.
duplicate target field; country, session, and min_purity may each appear onceA field repeated.
malformed target; each field must be <key>-<value> joined by '-'A dangling key or empty token.
invalid session id; allowed: letters, digits, underscore (1-64 chars)Session id outside [A-Za-z0-9_]{1,64}.
invalid min_purity; expected an integer 0-100min_purity not an integer in range.

Returned by api.marvel.sh/v1/*. The body is always { "error": "<message>" }.

StatusMeaning
401 UnauthorizedMissing/invalid bearer token, or a bad email/password at sign-in.
402 Payment RequiredIssuing a node on an empty balance.
404 Not FoundUnknown resource — e.g. a key id that isn’t yours, or a country with no live capacity.
409 ConflictSign-up with an email that already exists.
422 Unprocessable EntityValidation — bad country, session id, min_purity, email, or a password under 8 chars.
503 Service UnavailableA required subsystem (Reserve/selector) is not available right now.
500 Internal Server ErrorA fault on our side — logged, never detailed on the wire.
  • Every request returns 407. The key is unknown or revoked, or it’s in the wrong field. Confirm it’s a current mk_live_… key sent as the proxy username.
  • 402 even though I just paid. Credit lands when Stripe’s webhook confirms payment, not on the redirect. Check GET /v1/usagebalance_bytes should be non-zero once it settles.
  • 503 for a country I expected. Capacity is live-only and honest. Query GET /v1/availability to see what’s serveable this moment.
  • Sticky session changed IP. Exits expire (see expires_at) or get dropped; the next request re-pins a fresh vetted exit. That’s self-healing, by design.
  • A whole country looks lower-grade than usual. dominant_grade and mean_purity from GET /v1/availability/{country} reflect the current pool — grade availability moves with the Reserve.