Heardlist Docs

Heardlist API

Overview

Heardlist is a free, read-only HTTP API that serves lists of public proxies: HTTP, HTTPS, SOCKS4 and SOCKS5. It merges three community-maintained sources, drops duplicates, private addresses and credentialed entries, and ranks what’s left so entries with real verification evidence come first. The data refreshes every hour.

It’s a list API. It doesn’t relay your traffic, and it doesn’t check proxies for you at request time. Read Data quality and Using proxies safely before you build on it.

Quick start

Get five verified SOCKS5 proxies as JSON:

curl "https://YOUR-HOST/v1/proxies?protocol=socks5&verified=true&limit=5"

Or as plain host:port lines, ready for a tool that reads a proxy file:

curl "https://YOUR-HOST/v1/socks5.txt?verified=true&limit=50"

Or one random station, formatted as a full proxy URL:

curl "https://YOUR-HOST/v1/random?protocol=http&format=txt&scheme=true"

Base URL & access

All endpoints live under https://YOUR-HOST/v1.

  • No authentication. No API key, no signup.
  • CORS is open. Responses carry Access-Control-Allow-Origin: *, so you can call the API from a browser.
  • Methods. GET, HEAD and OPTIONS. Anything else returns 405.
  • Public data only. Don’t use the list to attack or abuse other people’s services.

Responses

List endpoints return a JSON envelope by default. The example below uses documentation-range addresses, not real proxies.

{
  "meta": {
    "count": 2,
    "total": 118,
    "limit": 2,
    "offset": 0,
    "sort": "quality",
    "updated_at": "2026-10-07T10:07:04.112Z"
  },
  "data": [
    {
      "proxy": "203.0.113.10:1080",
      "url": "socks5://203.0.113.10:1080",
      "protocol": "socks5",
      "host": "203.0.113.10",
      "port": 1080,
      "country": "US",
      "anonymity": null,
      "latency": 0.18,
      "source": "monosans",
      "verified": true
    },
    {
      "proxy": "198.51.100.7:8080",
      "url": "http://198.51.100.7:8080",
      "protocol": "http",
      "host": "198.51.100.7",
      "port": 8080,
      "country": "DE",
      "anonymity": null,
      "latency": 2.55,
      "source": "monosans",
      "verified": true
    }
  ]
}
FieldTypeMeaning
proxystringhost:port.
urlstringProxy URL to hand to a client. The scheme describes how you talk to the proxy. https entries are plain HTTP proxies that tunnel TLS, so their URL starts with http://.
protocolstringhttp, https, socks4 or socks5.
host, portstring, integerIPv4 address and port.
countrystring | nullISO 3166-1 alpha-2 code, when the source provides one.
anonymitystring | nullelite, anonymous or transparent. Only some sources state it; otherwise null.
latencynumber | nullResponse time in seconds measured by the upstream checker at its last run. null when the source doesn’t measure it.
sourcestringmonosans, proxifly or thespeedx.
verifiedbooleantrue when the source verifies every entry it publishes. Heardlist itself does not re-check.

List responses also set X-Total-Count (matches before paging) and X-Updated-At (when the data was last refreshed) as headers, which is handy with format=txt and format=csv.

Errors

Errors are JSON with a stable code and a human-readable message.

{ "error": { "code": "invalid_param", "message": "Invalid protocol: ftp. Allowed: http, https, socks4, socks5." } }
StatusCodeWhen
400invalid_paramA query parameter has a bad value. The message names it.
404not_foundNo such endpoint.
405method_not_allowedAnything other than GET, HEAD or OPTIONS.
429rate_limitedToo many requests. Wait for the Retry-After seconds.
500internal_errorSomething broke on our side. Retry shortly.

An empty result is not an error: filters that match nothing return 200 with "data": [].

Limits & caching

  • Rate limit. By default, 120 requests per minute per IP. The operator of a deployment can change it.
  • Page size. limit is 1–5000, default 100. Page with offset.
  • Refresh cadence. Data is rebuilt hourly. Polling more often than every few minutes gains nothing.
  • Caching. Responses are cached for one minute in browsers and five minutes at the edge. /v1/random and sort=random are never cached.
  • Staleness. If every upstream is unreachable, the last good data keeps being served. After 12 hours without a successful refresh it expires and the list becomes empty rather than serve very old addresses. /v1/health reports this.

GET /v1/proxies

The main list endpoint. Combine any of these filters; they’re ANDed together. Comma-separated values within one filter are ORed.

ParameterDefaultDescription
protocolanyhttp, https, socks4, socks5. Comma-separate to combine, e.g. socks4,socks5.
countryanyISO alpha-2 codes, case-insensitive: US,DE. Entries with no known country never match.
anonymityanyelite, anonymous, transparent. Entries where the source doesn’t state it never match.
sourceanymonosans, proxifly, thespeedx.
verifiedanytrue keeps only entries from sources that verify what they publish. false keeps the rest.
max_latencynoneSeconds, above 0 up to 120. Keeps entries with a measured response time at or under this value. Entries with no measurement are excluded.
sortqualityquality: source tier, then response time, then anonymity. latency: fastest measured first, unmeasured entries excluded. random: a fresh random draw each call.
limit1001–5000.
offset0Entries to skip. Ignored when sort=random.
formatjsonjson, txt (one host:port per line) or csv (columns host,port,protocol,country,anonymity,latency,source,verified).
schemefalseWith format=txt, prefix each line with the proxy URL scheme: socks5://203.0.113.10:1080.

Example: the 20 fastest verified HTTP proxies in Germany or France.

curl "https://YOUR-HOST/v1/proxies?protocol=http&country=DE,FR&verified=true&sort=latency&limit=20"

GET /v1/random

Shorthand for /v1/proxies?sort=random&limit=1. It accepts every filter above, and limit to draw several at once. Responses are never cached, so each call is a fresh draw. Use it for a quick rotation, and run your own check on whatever you get.

curl "https://YOUR-HOST/v1/random?protocol=socks5&verified=true"

GET /v1/{protocol}.txt

Plain-text lists for tools that load a proxy file. {protocol} is http, https, socks4 or socks5. It takes the same filters and paging as /v1/proxies, and always returns text/plain.

curl -o socks5.txt "https://YOUR-HOST/v1/socks5.txt?verified=true&limit=500"

GET /v1/stats

Counts and freshness for the current dataset. Counts are after de-duplication across sources.

{
  "total": 9024,
  "verified": 1435,
  "countries": 71,
  "by_protocol": { "http": 3100, "https": 980, "socks4": 640, "socks5": 4304 },
  "by_source":   { "monosans": 1435, "proxifly": 5200, "thespeedx": 2389 },
  "updated_at": "2026-10-07T10:07:04.112Z",
  "age_minutes": 12,
  "stale": false,
  "sources": {
    "monosans": { "ok": true, "fetched_at": "2026-10-07T10:07:04.112Z", "count": 1435 }
  }
}

The numbers are illustrative. stale turns true after three hours without a refresh. A source that failed its last run shows "ok": false with an error string, and its previous entries stay in the list until they expire.

GET /v1/sources

The upstream sources, their tier, whether they verify entries, their homepage and license, and the status of the last refresh. Use it to credit the data you rely on.

GET /v1/health

A cheap liveness check for monitors. It returns 200 when there is any data and 503 when the list is empty. In the body, ok is true only when the list is non-empty and fresher than three hours.

{ "ok": true, "total": 9024, "updated_at": "2026-10-07T10:07:04.112Z", "stale": false }

Protocols & anonymity

ProtocolWhat it isPick it for
httpApplication-layer proxy. For plain HTTP it can read and rewrite headers and bodies. For HTTPS it tunnels with the CONNECT method, which clients do automatically.General web requests.
httpsHTTP proxies a source explicitly flags as handling HTTPS. You still connect to the proxy over plain HTTP; the label is about what it can tunnel.When you need a source’s own HTTPS flag.
socks4Relays raw TCP. No UDP, no authentication, no remote DNS.Legacy TCP tools.
socks5Relays TCP and UDP, supports authentication and remote DNS, so hostnames resolve on the proxy and don’t leak from your machine.Most scraping and anything that isn’t only web traffic.

Entries from the verified tier labelled http are CONNECT-capable HTTP proxies, so they can carry HTTPS even though there is no separate https file for that source.

Anonymity is judged from the headers a target server sees. Elite proxies add nothing that identifies you or the proxy. Anonymous proxies hide your IP but announce themselves, for example with a Via header. Transparent proxies pass your real IP along in X-Forwarded-For and give no privacy at all. SOCKS proxies can’t add HTTP headers, so checkers tend to rate them elite. A checker that only tests over HTTPS will also rate a leaky HTTP proxy elite, because the tunnel hides its headers. Treat the anonymity field as a hint.

Data quality

Heardlist merges three upstream lists and orders them by tier:

  1. monosans/proxy-list (verified: true). Re-checked hourly with a full real-page fetch; proxies that connect and then stall are excluded. Provides response time and country. MIT licensed.
  2. proxifly/free-proxy-list. A large raw pool with anonymity and country fields. We don’t verify it. In the combined file reviewed on 7 Oct 2026, 50,855 of 51,262 entries were labelled transparent, and its score was 1 for every entry, so we ignore it.
  3. TheSpeedX/PROXY-List. Daily host:port files with no metadata and no verification evidence.

When the same protocol + host:port appears in more than one source, the highest tier wins. Private, loopback, link-local and carrier-grade-NAT addresses, invalid ports and entries that carry credentials are dropped. At most 10,000 entries per protocol are kept from any one source, which truncates proxifly’s very large SOCKS5 file.

“Verified” means the source’s check passed at its last run. Heardlist does not re-check, and a free proxy’s status decays within hours. In a research probe on 7 Oct 2026, 25 HTTP proxies from the verified tier were tried through a real request minutes after the hourly re-check: 9 answered correctly (36%), with response times from 0.75 s to 16.2 s and a median of 6.3 s. That is the best case. Expect fewer to work later in the hour, and fewer still from the unverified tiers.

So: always put a checker you control between the list and your workload. There’s one in the examples.

Using proxies safely

Free public proxies are untrusted by construction. Whoever runs one can see and change whatever isn’t protected end to end, and some are run as honeypots or are compromised machines.

  • Never send credentials, tokens, session cookies, payment data or private API keys through one. Public data only.
  • Don’t send plain HTTP. The operator can read it, log it and inject scripts into the response.
  • Keep TLS certificate verification on. A tunnel keeps the payload encrypted, but a hostile proxy can still refuse, downgrade or tamper with the handshake. The hostname you connect to is also visible to the operator, unless you use Encrypted Client Hello.
  • Use short timeouts. Three seconds or less for connect and read, so a stalling proxy can’t hold your workers.
  • Rotate and expect blocks. Many target sites block datacenter ranges and known proxy lists.
  • Isolate the workload. Run checkers and scrapers in a stateless container with no access to your internal network.

If you need reliability or privacy, a paid provider with an authenticated endpoint is the right tool. A free list is the right tool for large volumes of public, non-sensitive requests.

Code examples

Fetch, check, then use (Python)

Pull a candidate set, keep only the proxies that complete a real HTTPS request inside three seconds, and use those. This needs aiohttp and aiohttp-socks.

import asyncio
import aiohttp
from aiohttp_socks import ProxyConnector

API = "https://YOUR-HOST/v1/proxies?verified=true&limit=200"
TEST_URL = "https://example.com/"

async def alive(proxy_url: str) -> bool:
    try:
        connector = ProxyConnector.from_url(proxy_url)   # http://, socks4://, socks5://
        timeout = aiohttp.ClientTimeout(total=3)
        async with aiohttp.ClientSession(connector=connector, timeout=timeout) as s:
            async with s.get(TEST_URL) as r:
                return r.status == 200
    except Exception:
        return False

async def main():
    async with aiohttp.ClientSession() as s:
        async with s.get(API) as r:
            candidates = [p["url"] for p in (await r.json())["data"]]

    results = await asyncio.gather(*(alive(u) for u in candidates))
    good = [u for u, ok in zip(candidates, results) if ok]
    print(f"{len(good)} of {len(candidates)} passed")
    for u in good[:10]:
        print(u)

asyncio.run(main())

Fetch and test an HTTP proxy (Node.js)

Node 18+ with undici installed.

import { ProxyAgent, fetch } from "undici";

const API = "https://YOUR-HOST/v1/proxies?protocol=http&verified=true&limit=20";
const { data } = await (await fetch(API)).json();

for (const p of data) {
  try {
    const res = await fetch("https://example.com/", {
      dispatcher: new ProxyAgent(p.url),
      signal: AbortSignal.timeout(3000),
    });
    console.log(res.status, p.proxy);
  } catch {
    // dead, slow or hostile: skip it
  }
}

Load a text list in the browser

CORS is open, so the API works from a web page. Here it feeds a country filter into a list.

const res = await fetch("https://YOUR-HOST/v1/proxies?country=IN&limit=10");
if (!res.ok) throw new Error((await res.json()).error.message);
const { meta, data } = await res.json();
console.log(`${meta.count} of ${meta.total}`, data.map((p) => p.proxy));