Free proxy list API
One read-only endpoint. The same recent observations you see in the directory, in a format your script can use.
On this page
Make your first request
Send a GET request to /api/v1/proxies. No FreeProxyHub API key is required. Use Copy API URL below the proxy table for a URL on the site you are browsing, including your current filters.
curl --fail --max-time 20 'https://freeproxyhub.com/api/v1/proxies?protocol=socks5&country=US&limit=50'Filters and formats
| Parameter | Accepted values | Default |
|---|---|---|
protocol | http, https, socks4, socks5 | All |
country | Two-letter country code, e.g. US | All |
response | 500, 1500, 5000 (maximum ms) | Any |
anonymity | elite, anonymous, transparent | All |
port | Integer from 1 to 65535; exact match | All |
age | 1, 5, 10, 15 (check age in minutes, exclusive) | 15 |
format | json, csv, txt | json |
address | plain or url; TXT only | plain |
limit | 1–500, paginated JSON only | 100 |
cursor | nextCursor from the previous response | First page |
download | 1 for a complete attachment | Off |
Filter by port and check age
Combine port=8080 with age=5 to request endpoints on port 8080 whose recorded checks are less than five minutes old. The same filters work with JSON, CSV and TXT. At exactly five minutes, an entry stops matching until a newer check is available.
curl --fail --max-time 20 'https://freeproxyhub.com/api/v1/proxies?port=8080&age=5&format=txt&download=1' --output recent-8080.txtA port number alone does not identify the protocol; include a protocol filter when your client requires one. Age limits apply at request time and do not keep a downloaded file current. If entries age out between paginated requests, a 409 response asks you to restart so results are not silently skipped.
Read a JSON response
API JSON and complete JSON downloads include snapshotId, generatedAt, latestCheck, total, count, nextCursor and a data array. total counts all matching endpoints; count counts rows in this response. generatedAt is the serialization time. latestCheck is the newest check in the complete snapshot, which may belong to an endpoint outside your filters. Use each row’s lastChecked to expire it. All timestamps use UTC ISO 8601 strings.
Each row contains id, ip, port, country, protocols, https, responseMs, anonymity, lastChecked and checks. port is an integer; protocols is an array containing recorded support for http, socks4 or socks5.
country- A two-letter code, or
"ZZ"when no country code is available. anonymity"elite","anonymous","transparent"or"unknown"when no supported classification is available.responseMs- A response duration in milliseconds, or
nullwhen unavailable. httpstruemeans recorded HTTP CONNECT support with certificate validation.falsemeans that evidence is absent; it does not establish that HTTPS is impossible. This field is nevernulland is not a TLS-to-proxy setting.checksnullwhen 24-hour observations are unavailable; otherwise an object with integerpassedandtotalcounts andwindowHours: 24.totalis positive andpassedis between zero andtotal. Failed checks equaltotal - passed;passed / totalis a check success rate, not continuous uptime.
Illustrative JSON only: the reserved example address, timestamps and measurements below are not a live proxy or actual check results.
{
"snapshotId": "00000000000000000000",
"generatedAt": "2026-09-17T12:00:00.000Z",
"latestCheck": "2026-09-17T11:59:00.000Z",
"total": 1,
"count": 1,
"nextCursor": null,
"data": [
{
"id": "203.0.113.10:8080",
"ip": "203.0.113.10",
"port": 8080,
"country": "US",
"protocols": ["http"],
"https": true,
"responseMs": 240,
"anonymity": "elite",
"lastChecked": "2026-09-17T11:59:00.000Z",
"checks": { "passed": 18, "total": 20, "windowHours": 24 }
}
]
}Read the field definitions and their limits before relying on a label.
JSON exports from the table
The table’s Download page as JSON and selected-row JSON buttons create a smaller browser export with generatedAt, count and data. These exports omit snapshotId, latestCheck, total and nextCursor, and their rows omit id. The other row fields and unknown values match the API. They contain only unexpired rows from that page or selection.
Use All matching proxies → Download JSON or the API for the complete API envelope.
Paginate or download one complete snapshot
For paginated JSON, pass nextCursor with the same filters and limit. Stop when it is null. A cursor belongs to its snapshot; if new checks or expiry change the snapshot, a 409 response asks you to restart.
For complete results, request download=1, or use TXT or CSV. Those modes return all matching endpoints and do not accept a limit or cursor. A single full download is the simplest way to avoid changing results between pages.
curl --fail --max-time 20 'https://freeproxyhub.com/api/v1/proxies?protocol=https&format=txt&address=url&download=1' --output proxies.txtTXT defaults to one IP:port endpoint per line; IPv6 addresses use brackets. Add address=url for protocol URLs. HTTPS CONNECT endpoints use http://; a protocol filter chooses that protocol, otherwise each endpoint uses its first listed protocol. CSV and JSON retain separate address and protocol fields and reject the address parameter. See stable download links.
Handle errors and request limits
- 400: invalid, repeated or unsupported parameters.
- 409: the cursor’s snapshot changed; restart without the cursor.
- 414: the request URL exceeds 4,096 bytes.
- 429: request limit reached; wait for the number of seconds in the Retry-After header before retrying.
- 503: fresh evidence is unavailable; wait at least 60 seconds.
An empty filter result returns 200: JSON contains an empty data array, TXT is empty, and CSV contains only its header row. Unsupported methods return 405. Successful data responses include an X-Snapshot-Id and X-Proxy-Count header.
Request limits apply to bursts and repeated requests. For automated downloads, start with one request per minute and back off when you receive a 429 or 503 response. Reusing a download does not update its check timestamps: expire each record according to lastChecked and the age filter you requested. Bulk files may be cached briefly, for at most 15 seconds and less when an included check is about to expire. Paginated JSON remains uncached so cursor checks use the current results.