Extract API
Exchange an API key for a batch of passwordless ip:port entries — every parameter, response format, error code and rate limit.
The Extract API fixes the region and session configuration up front and hands back a batch of ip:port entries. Those ports are authorised by source-IP whitelist, so clients need no username or password.
/api/v1/proxy/extractAuthorisation requires all four
The API key goes in the query string, not a header. It belongs to a single proxy account — exactly one key per account — and its plaintext value is visible on the console's proxy account page.
Parameters
The proxy account's API key, 20–128 characters. Passed in the query string.
How many to extract, from 1 to 100.
Response format, txt or json.
Separator for txt output. Only three literal values are accepted: \n, \r\n, ,.
Note that this parameter is validated first even when type=json, so an illegal value still returns 400.
Two uppercase ISO country letters. The server enforces length 2 and characters in A-Z.
State or province name, up to 100 characters.
Compatibility behaviour: when country is empty and region is exactly 2 characters, region is treated as a country code.
City name, up to 100 characters.
Session mode, sticky or rotating.
Exit sticky session duration in minutes, from 1 to 120.
- Required when
session=sticky - Must be omitted when
session=rotating; supplying it returns400
Example requests
curl 'https://api.example.com/api/v1/proxy/extract?apikey=YOUR_KEY&num=5&type=json&country=US®ion=California&city=Los%20Angeles&session=sticky&time=10'
Rotating mode (no time):
curl 'https://api.example.com/api/v1/proxy/extract?apikey=YOUR_KEY&num=10&type=txt&country=DE&session=rotating'
Response formats
txt (default)
1.2.3.4:20001
1.2.3.4:20002
1.2.3.4:20003
Changing the separator:
# Comma-separated
curl '.../extract?apikey=KEY&num=3&format=,'
# → 1.2.3.4:20001,1.2.3.4:20002,1.2.3.4:20003
json
{
"code": 0,
"data": [
{ "ip": "1.2.3.4", "port": 20001 },
{ "ip": "1.2.3.4", "port": 20002 }
]
}
Using them directly
# Passwordless, no credentials at all
curl -x http://1.2.3.4:20001 https://api.ipify.org
SOCKS5 works on the same port (no-auth method):
curl -x socks5h://1.2.3.4:20001 https://api.ipify.org
How long the ports live
Port bindings are removed when:
- The API key is revoked
- The corresponding whitelist entry is deleted
- The whitelist entry is auto-cleaned after 10 consecutive idle days
- The gateway node serving that port becomes unhealthy — the stale binding is deleted and reassigned on the next extraction
- The proxy account or API key record is deleted
Port ranges
Port ranges are registered by each gateway node and are not fixed constants. Registration constraints:
- Start port ≥
1024 - End port ≤
65535 - At most
4096ports per node
So don't hard-code a port range in firewall rules; configure from whatever the API returns.
Rate limits
120 requests per minute, counted separately for source IP and API key — exceeding either returns 429 with Retry-After: 60.
Complete error reference
| Status | Code | Meaning |
|---|---|---|
400 | invalid_proxy_extract_time | time not an integer or outside 1–120; sticky missing time; rotating supplied time |
400 | invalid_proxy_extract_count | num not an integer or outside 1–100 |
400 | invalid_proxy_extract_type | type is neither txt nor json |
400 | invalid_proxy_extract_format | format is not \n / \r\n / , |
400 | invalid_proxy_extract_session | session is neither sticky nor rotating |
401 | proxy_api_key_invalid | Invalid key format or status; account/user unavailable or expired |
403 | proxy_source_not_whitelisted | Source IP not whitelisted |
422 | proxy_api_invalid | The selected country, state, city or session option combination is unavailable |
429 | proxy_extract_rate_limited | Over 120/min per IP or per key; includes Retry-After: 60 |
502 | client_ip_unavailable | The caller's public IPv4 could not be determined |
503 | proxy_gateway_unavailable | No healthy gateway; binding unconfirmed; ports exhausted. Includes Retry-After: 2 |
500 | internal_error | Rate-limit storage or other internal error |
A usable wrapper
import time
from dataclasses import dataclass
import requests
API = "https://api.example.com/api/v1/proxy/extract"
@dataclass
class ExtractError(Exception):
status: int
code: str
message: str
def extract(
api_key: str,
*,
count: int = 10,
country: str | None = None,
region: str | None = None,
city: str | None = None,
sticky_minutes: int | None = 10,
attempts: int = 3,
) -> list[str]:
"""Extract a batch of passwordless proxies, returning http://ip:port entries."""
params: dict[str, object] = {
"apikey": api_key,
"num": count,
"type": "json",
}
if country:
params["country"] = country
if region:
params["region"] = region
if city:
params["city"] = city
# sticky requires time; rotating must omit it
if sticky_minutes is None:
params["session"] = "rotating"
else:
params["session"] = "sticky"
params["time"] = sticky_minutes
for attempt in range(attempts):
response = requests.get(API, params=params, timeout=15)
if response.status_code == 200:
return [
f"http://{item['ip']}:{item['port']}"
for item in response.json()["data"]
]
# Both 429 and 503 supply Retry-After; honour it
if response.status_code in (429, 503) and attempt < attempts - 1:
time.sleep(int(response.headers.get("Retry-After", "2")))
continue
error = response.json().get("error", {})
raise ExtractError(
status=response.status_code,
code=error.get("code", "unknown"),
message=error.get("message", response.text[:200]),
)
raise ExtractError(status=503, code="exhausted", message="retries exhausted")
pool = extract("YOUR_API_KEY", count=5, country="US", sticky_minutes=10)
print(pool)
When not to use the Extract API
| Scenario | Use instead |
|---|---|
| Egress IP changes (home broadband, containers, multi-cloud) | Username options on 58971, see Quick start |
| Operator (ASN) targeting needed | Username options; extraction doesn't support it |
| A different region per request | Username options, where region varies per request |
| Frequent IP changes | Username options plus new connections; don't hammer the 120/min limit |