ProxyWing LogoProxyWing
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
RequestGET /residential/products
curl -X GET "https://api.proxywing.com/v1/residential/products" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response200 · 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 · BearerIdempotency-Key

Body parameters

  • tierstringrequired

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

  • gbintegerrequired

    Gigabytes of traffic to purchase (1–1000).

  • promo_codestringoptional

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

RequestPOST /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}'
Response200 · 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 · BearerIdempotency-Key

Path parameters

  • svc_idstringrequired

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

Body parameters

  • gbintegerrequired

    Gigabytes of traffic to add (1–10000).

RequestPOST /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}'
Response200 · 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
RequestGET /residential/services
curl -X GET "https://api.proxywing.com/v1/residential/services" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response200 · 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_idstringrequired

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

RequestGET /residential/services/{svc_id}/credentials
curl -X GET "https://api.proxywing.com/v1/residential/services/{svc_id}/credentials" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response200 · 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_idstringrequired

    The service id, e.g. resi_100001.

RequestGET /residential/services/{svc_id}/traffic
curl -X GET "https://api.proxywing.com/v1/residential/services/{svc_id}/traffic" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response200 · 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_idstringrequired

    The service id, e.g. resi_100001.

Query parameters

  • date_fromstringrequired

    Start date, YYYY-MM-DD.

  • date_tostringrequired

    End date, YYYY-MM-DD.

  • unitstringoptional

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

RequestGET /residential/services/{svc_id}/usage-report
curl -X GET "https://api.proxywing.com/v1/residential/services/{svc_id}/usage-report?date_from=2026-07-01&date_to=2026-07-26&unit=GB" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response200 · 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

  • tierstringrequired

    "premium" or "standard".

  • countrystringoptional

    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.

RequestGET /residential/access
curl -X GET "https://api.proxywing.com/v1/residential/access?tier=premium" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response200 · 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_idstringrequired

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

Query parameters

  • countrystringoptional

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

RequestGET /residential/services/{svc_id}/access
curl -X GET "https://api.proxywing.com/v1/residential/services/{svc_id}/access?country=US" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response200 · 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_idstringrequired

    The service id, e.g. resi_100001.

RequestGET /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"
Response200 · 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_idstringrequired

    The service id, e.g. resi_100001.

Body parameters

  • enabledbooleanrequired

    true to enable auto-topup, false to disable.

  • threshold_gbnumberoptional

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

  • amount_gbnumberoptional

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

RequestPUT /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}'
Response200 · 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_idstringrequired

    The service id, e.g. resi_100001.

Body parameters

  • countintegeroptional

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

  • protocolstringoptional

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

  • formatstringoptional

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

  • portintegeroptional

    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").

  • countrystringoptional

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

  • citystringoptional

    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`.

  • ispstringoptional

    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.

  • sessionstringoptional

    "rotating" (default) or "sticky".

  • session_ttlstringoptional

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

  • ipv4booleanoptional

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

  • streamingbooleanoptional

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

  • directbooleanoptional

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

  • skip_static_ispbooleanoptional

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

  • hoststringoptional

    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`.

RequestPOST /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"}'
Response200 · 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
RequestGET /residential/gateways
curl -X GET "https://api.proxywing.com/v1/residential/gateways" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response200 · 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

  • tierstringrequired

    Either premium or standard.

RequestGET /residential/gateways/{tier}/target
curl -X GET "https://api.proxywing.com/v1/residential/gateways/{tier}/target" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response200 · 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

  • tierstringrequired

    Either premium or standard.

Body parameters

  • hostnamestringrequired

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

RequestPUT /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"}'
Response200 · 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

  • tierstringrequired

    Either premium or standard.

RequestPOST /residential/gateways/{tier}/verify
curl -X POST "https://api.proxywing.com/v1/residential/gateways/{tier}/verify" \
  -H "Authorization: Bearer pk_live_XXXXXXXX"
Response200 · 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

  • tierstringrequired

    Either premium or standard.

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