ProxioDocs
API Reference

Services

List your Proxio services and read connection info with GET /services and GET /services/{id}, and toggle auto-renewal with PATCH /services/{id}. A service is a package, residential services return a gateway endpoint and credential, static services return a fixed proxy list.

A service is a package you own. GET /services lists them (cursor paginated), GET /services/{id} returns one service plus its connection details, and PATCH /services/{id} toggles auto-renewal.

Scope: read for both GETs, write for the PATCH.

List services

The list is cursor-paginated and stays lightweight: it returns summary figures rather than computing detailed usage.

Query parameters

ParameterValuesDefaultNotes
limit1 to 10020Page size.
cursoropaque-From the previous page's next_cursor.
categoryRESIDENTIAL, ISP, DC, MOBILE, STATIC_RESIDENTIAL-Case-insensitive. Any other value fails with VALIDATION_ERROR.
statusactive | expired | allactiveactive means active and not expired. Case-insensitive. Any other value fails with VALIDATION_ERROR.
qstring-Substring match on the service id only. At most 50 characters of letters, digits, _, and -.
created_after, created_beforeISO 8601 timestamps-Both inclusive. See Pagination.
orderasc | descdescThere's no sort parameter here: created_at is the only order this list supports, so there's nothing to name.

created_at is the only sort key

Unlike orders or wallet transactions, this list has no second sort key: sort=created_at is accepted (it's also the default), and any other value fails with VALIDATION_ERROR naming created_at as the only allowed value. order still works to flip newest-first to oldest-first.

Unrecognized filter values are rejected, not ignored

A category outside the list above fails with VALIDATION_ERROR (400), and so does a status outside active, expired, and all. The error names the field and lists what it accepts, as details: [{ "field": "category", "issue": "invalid", "allowed": [...] }]. You never get the unfiltered list back in place of a filter, so an empty page means you own nothing that matches. Both are case-insensitive, so residential and RESIDENTIAL are the same filter. The accepted SET still differs from GET /orders, which filters the category you bought rather than the one stored on the service, so datacenter works there and DC works here.

q is an id substring search, not a general search: it does not look at labels or any other field. Keep it to at most 50 characters of letters, digits, _, and -, which is what a service id is made of. A longer term, or one carrying anything else, fails with VALIDATION_ERROR instead of returning your whole list, so ?q=my service tells you the term is wrong rather than answering as if it had searched.

curl "https://dashboard.proxio.net/api/v1/services?status=active&category=RESIDENTIAL&limit=20" \
  -H "Authorization: Bearer pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"
import requests

BASE = "https://dashboard.proxio.net/api/v1"
API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"

resp = requests.get(
    f"{BASE}/services",
    headers={"Authorization": f"Bearer {API_KEY}"},
    params={"status": "active", "category": "RESIDENTIAL", "limit": 20},
    timeout=15,
)
resp.raise_for_status()
body = resp.json()
print(body["data"], body["meta"]["next_cursor"])
const BASE = "https://dashboard.proxio.net/api/v1"
const API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"

const res = await fetch(
  `${BASE}/services?status=active&category=RESIDENTIAL&limit=20`,
  { headers: { Authorization: `Bearer ${API_KEY}` } },
)
const body = await res.json()
console.log(body.data, body.meta.next_cursor)

200 response:

{
  "data": [
    {
      "id": "clpkg_2a9x",
      "category": "RESIDENTIAL",
      "product_key": "RESIDENTIAL",
      "is_unlimited": false,
      "status": "active",
      "limit":     { "bytes": "50000000000", "bytes_num": 50000000000, "gigabytes": 50 },
      "remaining": { "bytes": "31240000000", "bytes_num": 31240000000, "gigabytes": 31.24 },
      "expires_at": "2026-08-01T00:00:00.000Z",
      "auto_renewal_enabled": false,
      "credential_count": 2,
      "created_at": "2026-07-02T10:00:00.000Z"
    }
  ],
  "meta": { "next_cursor": "eyJpZCI6…", "has_more": true, "request_id": "req_8Ke2jP4mQ" }
}

For unlimited packages, limit and remaining are null. Byte amounts are quantity objects, the exact-bytes string is authoritative. The list stays lightweight; for detailed used figures call the usage endpoint.

Get one service

GET /services/{id} adds a connection block. Its shape depends on how the category is delivered.

curl https://dashboard.proxio.net/api/v1/services/clpkg_2a9x \
  -H "Authorization: Bearer pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"
import requests

BASE = "https://dashboard.proxio.net/api/v1"
API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"
SERVICE_ID = "clpkg_2a9x"

resp = requests.get(
    f"{BASE}/services/{SERVICE_ID}",
    headers={"Authorization": f"Bearer {API_KEY}"},
    timeout=15,
)
resp.raise_for_status()
print(resp.json()["data"]["connection"])
const BASE = "https://dashboard.proxio.net/api/v1"
const API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"
const SERVICE_ID = "clpkg_2a9x"

const res = await fetch(`${BASE}/services/${SERVICE_ID}`, {
  headers: { Authorization: `Bearer ${API_KEY}` },
})
const { data } = await res.json()
console.log(data.connection)

Residential (gateway)

Residential services connect through Proxio's gateway. The connection block gives you the gateway endpoint, your primary credential (password included), and a hint about embedding targeting in the username.

{
  "data": {
    "id": "clpkg_2a9x",
    "category": "RESIDENTIAL",
    "is_unlimited": false,
    "status": "active",
    "expires_at": "2026-08-01T00:00:00.000Z",
    "connection": {
      "delivery": "gateway",
      "endpoint": { "host": "geo.proxio.cc", "port": 16666, "protocols": ["http", "socks5"] },
      "credential": { "id": "clsub_7h2k", "username": "abc123xyz", "password": "secretpass", "is_primary": true },
      "proxies": null,
      "targeting_hint": "Embed targeting in the username: {username}-region-us-city-newyork-sessid-<id>-sesstime-10"
    }
  },
  "meta": { "request_id": "req_8Ke2jP4mQ" }
}

To turn this into ready-to-paste lines with targeting already applied, use the proxy-list generator. To mint more credentials, see Credentials.

Static delivery (ISP, datacenter)

ISP and datacenter services are delivered as a fixed list of static proxies. There's no gateway endpoint or username targeting, just a proxies array of concrete host:port:username:password entries.

{
  "data": {
    "id": "clpkg_5d3m",
    "category": "ISP",
    "is_unlimited": true,
    "status": "active",
    "connection": {
      "delivery": "static",
      "delivery_status": "ready",
      "endpoint": null,
      "credential": null,
      "proxies": [
        { "host": "203.0.113.10", "port": 8080, "username": "u1", "password": "p1", "protocol": "http" }
      ]
    }
  },
  "meta": { "request_id": "req_8Ke2jP4mQ" }
}

New orders provision shortly

Right after a purchase, delivery_status is "provisioning" and proxies is [] while your static proxies are allocated. Poll until it reads "ready" and the list fills in.

Update auto-renewal

PATCH /services/{id} toggles auto_renewal_enabled, it's the only field this endpoint writes. Scope: write.

Body

FieldTypeNotes
auto_renewal_enabledbooleanRequired.
curl -X PATCH https://dashboard.proxio.net/api/v1/services/clpkg_2a9x \
  -H "Authorization: Bearer pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x" \
  -H "Content-Type: application/json" \
  -d '{ "auto_renewal_enabled": true }'
import requests

BASE = "https://dashboard.proxio.net/api/v1"
API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"

resp = requests.patch(
    f"{BASE}/services/clpkg_2a9x",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={"auto_renewal_enabled": True},
    timeout=15,
)
resp.raise_for_status()
print(resp.json()["data"]["auto_renewal_enabled"])
const BASE = "https://dashboard.proxio.net/api/v1"
const API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"

const res = await fetch(`${BASE}/services/clpkg_2a9x`, {
  method: "PATCH",
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ auto_renewal_enabled: true }),
})
console.log((await res.json()).data.auto_renewal_enabled)

200 response: the updated service, in the same shape as a list item.

Turning auto-renewal off always succeeds. Turning it on requires a service the renewal cycle can actually pick up: UNSUPPORTED_OPERATION if the service has no expires_at at all (nothing to renew against), or if it's already expired (renew it first, then enable auto-renewal). This mirrors the toggle in the dashboard's service settings.

Fields

FieldTypeNotes
idstringService (package) id.
categorystringe.g. RESIDENTIAL, ISP.
product_keystringThe product this service was bought as. Falls back to category when there's no linked product record. List items only.
is_unlimitedbooleantrue for unlimited-bandwidth packages.
statusstringactive or expired.
limit / remainingobject | nullByte quantities; null when unlimited. List items only (see the note below).
expires_atstring | nullExpiry (ISO 8601 UTC), if any.
auto_renewal_enabledbooleanWhether this service auto-renews. List items only.
credential_countintegerActive credentials on this service. List items only.
created_atstringWhen the service was provisioned (ISO 8601 UTC). List items only.
connection.deliverystringgateway (rotating gateway) or static (fixed proxy list). Detail only.
connection.endpointobject | nullGateway host, port, and protocols (gateway only). Detail only.
connection.credentialobject | nullPrimary credential incl. password (gateway only). Detail only.
connection.proxiesarray | nullFixed proxy entries (static only). Detail only.
connection.delivery_statusstringprovisioning or ready (static only, delivery: "static"). Detail only.
connection.targeting_hintstringA human-readable tip with an example username showing where targeting segments go (gateway only, delivery: "gateway"). Detail only.

List vs. detail fields

limit and remaining appear on list items (GET /services); the detail response (GET /services/{id}) returns the connection block instead. For live usage figures on a single service, call GET /services/{id}/usage.

A service the key doesn't own returns NOT_FOUND.

On this page