ProxyWing
Browse endpoints

ProxyWing Developer API

Residential

Buy residential traffic per GB, serve it on your own gateway hostname, and pull usage reports. Reselling through sub-users has its own section.

GET /residential/products

List residential tiers

Returns the residential proxy tiers available for purchase. Residential traffic is sold per gigabyte; bulk-volume discounts apply automatically at checkout.

Auth · Bearer
Request GET /residential/products
curl -X GET "https://api.proxywing.com/v1/residential/products" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response 200 · application/json
{
  "tiers": [
    {
      "tier": "premium",
      "per_gb": 6
    },
    {
      "tier": "standard",
      "per_gb": 2.5
    }
  ]
}
POST /residential/orders

Order residential traffic

Purchases residential proxy traffic (in GB) on the chosen tier using the account balance. This is a one-time purchase — there is no billing cycle or recurring charge; the traffic stays on the service until used. The invoice total is computed by billing — bulk-volume discounts are applied automatically, so larger orders can cost less than gb × per_gb. Once paid, the service provisions immediately and appears in GET /residential/services. Supply an Idempotency-Key header so retries never double-charge. The order_id in the response is the id you use on every later call for this resource, and it is only known once the order provisions — it is null while the order is still awaiting_payment. Pay the invoice, then either re-read the response of a balance-settled order or poll the relevant list endpoint to pick the resource up. Idempotency-Key is REQUIRED on this endpoint — omitting it returns 400 and nothing is charged.

Auth · Bearer Idempotency-Key

Body parameters

  • tier string required

    "premium" or "standard", from GET /residential/products.

  • gb integer required

    Gigabytes of traffic to purchase (1–1000).

  • promo_code string optional

    Optional promo code. Only percentage-discount promo codes under 100% off apply via the API (a code that would zero the total is rejected).

Request POST /residential/orders
curl -X POST "https://api.proxywing.com/v1/residential/orders" \
  -H "Authorization: Bearer pk_live_XXXXXXXX" \
  -H "Idempotency-Key: b3f2a1c4-7e9d-4a2b-8c6f-1d5e9a0b3c7f" \
  -H "Content-Type: application/json" \
  -d '{"tier":"standard","gb":5}'
Response 200 · application/json
{
  "order_id": "resi_100001",
  "invoice_id": "inv_200004",
  "tier": "standard",
  "gb": 5,
  "status": "paid"
}
POST /residential/services/{svc_id}/top-up

Add bandwidth to a service

Adds GB of traffic to an EXISTING residential service — no new order or new credentials, the extra traffic lands on the same service. An invoice is created for the added GB (bulk-volume discounts apply, so larger top-ups cost less per GB) and, if the balance covers it, paid automatically and the traffic is credited immediately. If the balance is short the invoice stays open (awaiting_payment) and can be settled from the dashboard. Supply an Idempotency-Key header so retries never double-buy. Idempotency-Key is REQUIRED on this endpoint — omitting it returns 400 and nothing is charged.

Auth · Bearer Idempotency-Key

Path parameters

  • svc_id string required

    The residential service id, e.g. resi_100001, from GET /residential/services.

Body parameters

  • gb integer required

    Gigabytes of traffic to add (1–10000).

Request POST /residential/services/{svc_id}/top-up
curl -X POST "https://api.proxywing.com/v1/residential/services/{svc_id}/top-up" \
  -H "Authorization: Bearer pk_live_XXXXXXXX" \
  -H "Idempotency-Key: b3f2a1c4-7e9d-4a2b-8c6f-1d5e9a0b3c7f" \
  -H "Content-Type: application/json" \
  -d '{"gb":5}'
Response 200 · application/json
{
  "service_id": "resi_100001",
  "gb_added": 5,
  "old_gb": 3,
  "new_gb": 8,
  "invoice_id": "inv_200020",
  "total": 11.25,
  "status": "paid"
}
GET /residential/services

List residential services

Returns every active residential service on the account, with its tier and the gateway hostname it connects through.

Auth · Bearer
Request GET /residential/services
curl -X GET "https://api.proxywing.com/v1/residential/services" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response 200 · application/json
{
  "services": [
    {
      "id": "resi_100001",
      "tier": "standard",
      "status": "active",
      "gateway": "quality.proxywing.com"
    },
    {
      "id": "resi_100002",
      "tier": "premium",
      "status": "active",
      "gateway": "premium.proxywing.com"
    }
  ]
}
GET /residential/services/{svc_id}/credentials

Get connection credentials

Returns the gateway, available ports, and the username/password for a residential service. targeting_field tells you which credential carries geo-targeting and session tokens when you build proxy strings by hand — use POST /residential/services/{svc_id}/generate-proxy-list to have them built for you.

Auth · Bearer

Path parameters

  • svc_id string required

    The service id, e.g. resi_100001, from GET /residential/services.

Request GET /residential/services/{svc_id}/credentials
curl -X GET "https://api.proxywing.com/v1/residential/services/{svc_id}/credentials" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response 200 · application/json
{
  "id": "resi_100001",
  "tier": "standard",
  "gateway": "quality.proxywing.com",
  "http_ports": [
    8888,
    7000,
    7001,
    7002,
    7003,
    7004,
    7005
  ],
  "socks5_ports": [
    1080,
    6000,
    6001,
    6002,
    6003,
    6004,
    6005
  ],
  "username": "pkg-private2",
  "password": "sample_password",
  "targeting_field": "username"
}
GET /residential/services/{svc_id}/traffic

Get traffic usage

Returns the traffic balance for a residential service in gigabytes. Fields not tracked for a given tier are null.

Auth · Bearer

Path parameters

  • svc_id string required

    The service id, e.g. resi_100001.

Request GET /residential/services/{svc_id}/traffic
curl -X GET "https://api.proxywing.com/v1/residential/services/{svc_id}/traffic" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response 200 · application/json
{
  "tier": "standard",
  "total_gb": 20,
  "used_gb": 1.21,
  "available_gb": 18.79
}
GET /residential/services/{svc_id}/usage-report

Get a usage report

Returns per-hostname traffic usage for a residential service over a date window. Values are in the requested unit; total is the sum across all rows.

Auth · Bearer

Path parameters

  • svc_id string required

    The service id, e.g. resi_100001.

Query parameters

  • date_from string required

    Start date, YYYY-MM-DD.

  • date_to string required

    End date, YYYY-MM-DD.

  • unit string optional

    Measurement unit for the data values: "B", "KB", "MB" or "GB" (default GB).

Request GET /residential/services/{svc_id}/usage-report
curl -X GET "https://api.proxywing.com/v1/residential/services/{svc_id}/usage-report" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response 200 · application/json
{
  "tier": "standard",
  "date_from": "2026-06-01",
  "date_to": "2026-07-01",
  "unit": "GB",
  "total": 3.42,
  "rows": [
    {
      "date": "2026-06-15",
      "hostname": "example.com",
      "data": 2.1,
      "requests": 1840
    },
    {
      "date": "2026-06-16",
      "hostname": "api.example.com",
      "data": 1.32,
      "requests": 910
    }
  ]
}
GET /residential/access

List countries & cities

Two calls, depending on what you need. **Countries:** send only tierGET /residential/access?tier=premium. **Cities:** add countryGET /residential/access?tier=premium&country=US. Each entry has a code and a display name, and **the code is what you pass** as city / country to generate-proxy-list (losangeles, not "Los angeles"). Coverage differs sharply between tiers, so query the tier you actually sell: losangeles and sanfrancisco exist on Premium but not Standard, and Premium carries 2030 US cities against Standard's 534. A city missing from the list produces a credential the gateway refuses, so resolve names here rather than guessing. **ASNs have no listing endpoint** — you supply the AS number yourself (e.g. 7922 for Comcast); see the isp parameter on generate-proxy-list.

Auth · Bearer

Query parameters

  • tier string required

    "premium" or "standard".

  • country string optional

    ISO country code, e.g. US. When set, returns that country's cities instead of the country list. Case-insensitive on input; the `code` values in the response are lowercase.

Request GET /residential/access
curl -X GET "https://api.proxywing.com/v1/residential/access" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response 200 · application/json
{
  "tier": "premium",
  "countries": [
    {
      "code": "us",
      "name": "United States"
    },
    {
      "code": "gb",
      "name": "United Kingdom"
    },
    {
      "code": "de",
      "name": "Germany"
    }
  ]
}
GET /residential/services/{svc_id}/access

List a service's countries & cities

The same geo catalogue as GET /residential/access, scoped to one of your services so you do not need to know or send its tier. Send it bare for every available country; add country for that country's cities — the sample below shows the cities form. code values are lowercase and are what you pass as city / country to generate-proxy-list. Read-scope keys are sufficient.

Auth · Bearer

Path parameters

  • svc_id string required

    The residential service id, from GET /residential/services.

Query parameters

  • country string optional

    ISO country code, e.g. US. When set, returns that country's cities instead of the country list.

Request GET /residential/services/{svc_id}/access
curl -X GET "https://api.proxywing.com/v1/residential/services/{svc_id}/access" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response 200 · application/json
{
  "tier": "standard",
  "country": "US",
  "cities": [
    {
      "code": "chicago",
      "name": "Chicago"
    },
    {
      "code": "dallas",
      "name": "Dallas"
    }
  ]
}
GET /residential/services/{svc_id}/auto-topup

Get auto-topup settings

Returns the auto-topup configuration for a residential service. When enabled, the account buys more traffic automatically once the remaining balance falls below the threshold.

Auth · Bearer

Path parameters

  • svc_id string required

    The service id, e.g. resi_100001.

Request GET /residential/services/{svc_id}/auto-topup
curl -X GET "https://api.proxywing.com/v1/residential/services/{svc_id}/auto-topup" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response 200 · application/json
{
  "service_id": "resi_100001",
  "enabled": true,
  "threshold_gb": 2,
  "amount_gb": 5,
  "payment_source": "balance",
  "last_topup_at": null
}
PUT /residential/services/{svc_id}/auto-topup

Set auto-topup

Enables or disables auto-topup for a residential service. When enabling, both threshold_gb and amount_gb are required and top-ups are paid from the account balance. (Card-funded auto-topup is configured from the dashboard.)

Auth · Bearer

Path parameters

  • svc_id string required

    The service id, e.g. resi_100001.

Body parameters

  • enabled boolean required

    true to enable auto-topup, false to disable.

  • threshold_gb number optional

    Top up when remaining traffic drops below this many GB (1–10000). Required when enabling.

  • amount_gb number optional

    How many GB to buy each time (1–10000). Required when enabling.

Request PUT /residential/services/{svc_id}/auto-topup
curl -X PUT "https://api.proxywing.com/v1/residential/services/{svc_id}/auto-topup" \
  -H "Authorization: Bearer pk_live_XXXXXXXX" \
  -H "Content-Type: application/json" \
  -d '{"enabled":true,"threshold_gb":2,"amount_gb":5}'
Response 200 · application/json
{
  "service_id": "resi_100001",
  "enabled": true,
  "threshold_gb": 2,
  "amount_gb": 5,
  "payment_source": "balance",
  "last_topup_at": null
}
POST /residential/services/{svc_id}/generate-proxy-list

Generate a proxy list

Builds ready-to-use proxy strings for a residential service with the geo-targeting and session behaviour you specify. Rotating sessions get a new exit IP on every request; sticky sessions keep the same exit IP for the session TTL. This endpoint only formats credentials — it never charges the account.

Auth · Bearer

Path parameters

  • svc_id string required

    The service id, e.g. resi_100001.

Body parameters

  • count integer optional

    Number of proxy strings to generate, 1–1000. Default 10.

  • protocol string optional

    "http" (default), "socks5", or "mix". "mix" is Standard tier only — one port answering both HTTP and SOCKS5; requesting it on Premium returns 400.

  • format string optional

    Output format. One of "hostname:port:username:password" (default), "hostname:port@username:password", "username:password@hostname:port", "username:password:hostname:port".

  • port integer optional

    Specific gateway port to use. Must be one of the ports published for that protocol — Premium accepts 102 HTTP and 102 SOCKS5 ports, Standard 111 HTTP, 112 SOCKS5, and 5555 for "mix". Defaults to the tier's rotating or sticky port based on `session` (5555 for "mix").

  • country string optional

    ISO country code(s) to target, e.g. "US" or "US,GB" for a multi-country pool. Omit for random.

  • city string optional

    City to target. Requires exactly ONE `country` — with a comma-separated multi-country value the city is dropped. Available on BOTH tiers; discover valid names with `GET /residential/services/{svc_id}/access?country=US` (Premium carries far more cities than Standard). Spaces are removed, so "Los angeles" is sent as `LosAngeles`.

  • isp string optional

    ASN to target, e.g. `7922` for Comcast. Requires exactly ONE `country`, same as `city`, and combines with it to pin both (Comcast in Chicago). Premium accepts an AS number or a provider name; Standard expects an AS number. There is no ASN discovery endpoint — supply the AS number yourself.

  • session string optional

    "rotating" (default) or "sticky".

  • session_ttl string optional

    How long a sticky session keeps its exit IP, e.g. "30s", "10m", "2h", "1d".

  • ipv4 boolean optional

    Standard tier only: restrict to the IPv4-only pool. Default true.

  • streaming boolean optional

    Premium tier only: use the high-end streaming pool. Default false.

  • direct boolean optional

    Premium tier only: direct connection mode, for protocols such as IMAP that dislike the default path. Default false.

  • skip_static_isp boolean optional

    Premium tier only: skip static-ISP exits. Default false.

  • host string optional

    Emit a raw entry IP instead of the DNS gateway hostname. Must be one of the tier's published entry IPs, or the tier gateway name; anything else returns 400. Leave it unset unless you need it — the gateway hostname is geo-routed, so pinning an IP sends every user of that string to a single region. The available IPs come back from the sub-user credentials endpoint as `entry_ips`.

Request POST /residential/services/{svc_id}/generate-proxy-list
curl -X POST "https://api.proxywing.com/v1/residential/services/{svc_id}/generate-proxy-list" \
  -H "Authorization: Bearer pk_live_XXXXXXXX" \
  -H "Content-Type: application/json" \
  -d '{"count":2,"protocol":"http","country":"US","session":"sticky","session_ttl":"10m"}'
Response 200 · application/json
{
  "gateway": "quality.proxywing.com",
  "port": 8888,
  "protocol": "http",
  "count": 2,
  "proxies": [
    "quality.proxywing.com:8888:pkg-private2-pool-onlyipv4-country-US-session-a1b2c3d4-ttl-10:sample_password",
    "quality.proxywing.com:8888:pkg-private2-pool-onlyipv4-country-US-session-e5f6g7h8-ttl-10:sample_password"
  ]
}
GET /residential/gateways

List your gateway hostnames

Your whitelabel gateway hostnames, one per tier, each with its live DNS status. With none configured the platform defaults are used and everything behaves exactly as before.

Auth · Bearer
Request GET /residential/gateways
curl -X GET "https://api.proxywing.com/v1/residential/gateways" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response 200 · application/json
{
  "gateways": [
    {
      "tier": "premium",
      "hostname": "gw.yourdomain.com",
      "status": "active",
      "in_use": true,
      "resolves_to": [
        "149.51.212.54"
      ],
      "expected_ips": [
        "149.51.212.54"
      ],
      "last_checked_at": "2026-07-26T08:17:01Z",
      "error": null
    }
  ],
  "defaults": {
    "premium": "premium.proxywing.com",
    "standard": "quality.proxywing.com"
  }
}
GET /residential/gateways/{tier}/target

Get the DNS record to publish

Returns the exact DNS record to create for your own hostname. Use a CNAME, not A records: the gateway is geo-routed and answers with different addresses depending on where the request comes from, so each of your customers reaches a nearby entry point. Fixed A records would pin every one of them to a single region and break whenever those addresses change.

Auth · Bearer

Path parameters

  • tier string required

    Either premium or standard.

Request GET /residential/gateways/{tier}/target
curl -X GET "https://api.proxywing.com/v1/residential/gateways/{tier}/target" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response 200 · application/json
{
  "tier": "premium",
  "record_type": "CNAME",
  "target": "premium.proxywing.com",
  "ttl_hint": 300,
  "example": "gw.yourdomain.com.  IN  CNAME  premium.proxywing.com."
}
PUT /residential/gateways/{tier}

Set your gateway hostname

Points a tier at a hostname on your own domain, so the credentials and proxy strings you hand your customers carry your brand instead of ours. We check DNS immediately: status active means it is live and every credentials and proxy-list response now returns your hostname, while pending means the record is not right yet and the error field says why — until it is correct we keep serving the default gateway, so a misconfigured record can never hand your customers dead proxies. Each tier is independent. Returns 409 hostname_unavailable if another account already holds that hostname.

Auth · Bearer

Path parameters

  • tier string required

    Either premium or standard.

Body parameters

  • hostname string required

    A hostname on a domain you control, e.g. gw.yourdomain.com.

Request PUT /residential/gateways/{tier}
curl -X PUT "https://api.proxywing.com/v1/residential/gateways/{tier}" \
  -H "Authorization: Bearer pk_live_XXXXXXXX" \
  -H "Content-Type: application/json" \
  -d '{"hostname":"gw.yourdomain.com"}'
Response 200 · application/json
{
  "tier": "premium",
  "hostname": "gw.yourdomain.com",
  "status": "active",
  "in_use": true,
  "resolves_to": [
    "149.51.212.54"
  ],
  "expected_ips": [
    "149.51.212.54"
  ],
  "last_checked_at": "2026-07-26T08:17:01Z",
  "error": null
}
POST /residential/gateways/{tier}/verify

Re-check your gateway DNS

Re-checks the DNS for this tier straight away, instead of waiting for the background sweep. Use it after correcting a record. We keep re-verifying on our own too: if a hostname that was working stops resolving to our gateway we mark it drifted and fall back to the default for newly generated strings, then restore it automatically once the record is correct again.

Auth · Bearer

Path parameters

  • tier string required

    Either premium or standard.

Request POST /residential/gateways/{tier}/verify
curl -X POST "https://api.proxywing.com/v1/residential/gateways/{tier}/verify" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response 200 · application/json
{
  "tier": "premium",
  "hostname": "gw.yourdomain.com",
  "status": "active",
  "in_use": true,
  "resolves_to": [
    "149.51.212.54"
  ],
  "expected_ips": [
    "149.51.212.54"
  ],
  "last_checked_at": "2026-07-26T08:29:12Z",
  "error": null
}
DELETE /residential/gateways/{tier}

Remove your gateway hostname

Reverts this tier to the platform default gateway. Proxy strings you have already issued on your own hostname keep working for as long as your DNS record stays in place.

Auth · Bearer

Path parameters

  • tier string required

    Either premium or standard.

Request DELETE /residential/gateways/{tier}
curl -X DELETE "https://api.proxywing.com/v1/residential/gateways/{tier}" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response 200 · application/json
{
  "tier": "premium",
  "hostname": null,
  "serving": "premium.proxywing.com"
}