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.

Command example
curl --fail --max-time 20 'https://freeproxyhub.com/api/v1/proxies?protocol=socks5&country=US&limit=50'

Filters and formats

ParameterAccepted valuesDefault
protocolhttp, https, socks4, socks5All
countryTwo-letter country code, e.g. USAll
response500, 1500, 5000 (maximum ms)Any
anonymityelite, anonymous, transparentAll
portInteger from 1 to 65535; exact matchAll
age1, 5, 10, 15 (check age in minutes, exclusive)15
formatjson, csv, txtjson
addressplain or url; TXT onlyplain
limit1–500, paginated JSON only100
cursornextCursor from the previous responseFirst page
download1 for a complete attachmentOff

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.

Command example
curl --fail --max-time 20 'https://freeproxyhub.com/api/v1/proxies?port=8080&age=5&format=txt&download=1' --output recent-8080.txt

A 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 null when unavailable.
https
true means recorded HTTP CONNECT support with certificate validation. false means that evidence is absent; it does not establish that HTTPS is impossible. This field is never null and is not a TLS-to-proxy setting.
checks
null when 24-hour observations are unavailable; otherwise an object with integer passed and total counts and windowHours: 24. total is positive and passed is between zero and total. Failed checks equal total - passed; passed / total is 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.

Example JSON response
{
  "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.

Command example
curl --fail --max-time 20 'https://freeproxyhub.com/api/v1/proxies?protocol=https&format=txt&address=url&download=1' --output proxies.txt

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