ProxyWing LogoProxyWing
Browse endpoints

ProxyWing Developer API

API Reference

The ProxyWing API lets you manage your account and provision proxies programmatically. All requests are made over HTTPS to a single base URL and authenticated with a Bearer API key.

Base URLhttps://api.proxywing.com/v1

Get your API key in the dashboard under Account Security.

Bearer authentication600 requests / min per IPIdempotent writes

Authentication

Get an API key from your dashboard under Account → Security. Every request must include it as a Bearer token in the Authorization header:

Authorization: Bearer pk_live_XXXXXXXX

Live keys are prefixed pk_live_. Keys can be scoped and revoked at any time from GET /account/api-keys and DELETE /account/api-keys/{key_pub_id}.

Errors

Every error body is JSON with a top-level detail key. What sits inside it takes one of three forms, so read the HTTP status first and treat detail as either a string, an object, or an array.

application/json
// 1. A plain message — most 400 / 401 / 403 / 404 responses
{ "detail": "Order not found" }

// 2. A coded error — newer endpoints (sub-users, gateways, whitelist removal).
//    Branch on detail.error.code; the message is for humans and may change.
{
  "detail": {
    "error": {
      "code": "insufficient_unallocated_traffic",
      "message": "not enough unallocated traffic on this service"
    }
  }
}

// 3. Request validation — always HTTP 422, one entry per rejected field
{
  "detail": [
    {
      "type": "value_error",
      "loc": ["body", "gb"],
      "msg": "Value error, gb must be a whole number of GB (1, 2, 3, ...); got 1.5",
      "input": 1.5
    }
  ]
}

A robust client reads the status code, then checks whether detail is an object containing error.code before falling back to rendering it as text. Error codes named in this reference always appear at detail.error.code.

StatusMeaning
400Bad request — malformed or missing parameters.
401Unauthorized — missing or invalid API key.
404Not found — the resource does not exist on this account.
409Conflict — the request conflicts with the resource's current state.
429Too many requests — rate limit exceeded.
500Internal server error — retry with backoff.

Rate limits

Requests are limited to 600 requests per minute per IP. Exceeding the limit returns a 429 status — back off and retry after a short delay.

Idempotency

Order, extend, top-up and sub-user write endpoints require an Idempotency-Key header — omitting it returns 400 before anything is charged or created. Send a unique key (a UUID works well) per new request; retrying after a timeout or network error with the same key guarantees the work happens at most once.

A replayed request returns the original result and carries an Idempotent-Replayed: true response header, so you can tell a safely-ignored retry from a fresh write — the body alone is identical either way.

Two exceptions worth coding for. Sub-user allocate and reclaim do not replay: a reused key returns 409 request_in_progress rather than the earlier outcome, so use a fresh key per attempt and read the sub-user back to confirm state. And reusing a key whose sub-user was since deleted returns 409 idempotency_key_reused instead of the dead record.