# Public proxy detection API: open proxies at both ends

VPNDetection's API now answers is_pubproxy for open HTTP, HTTPS and SOCKS proxies, where they listen and where their traffic leaves, and ships it as a database.

Since October 18, the API answers `is_pubproxy`: whether the address sits at either end of a public proxy, an open HTTP, HTTPS or SOCKS proxy that anyone can send traffic through, with no account and no payment. The same data ships as [Public Proxy IP](https://vpndetection.io/databases/public-proxy-ip), a database in six windows.

## What a public proxy is

A public proxy takes connections from anyone who knows its address and port: an HTTP proxy, an HTTP proxy that also tunnels HTTPS connections (CONNECT), or a SOCKS4 or SOCKS5 proxy. They cost nothing to use, so they turn up wherever a large number of attempts matters more than any one of them: credential stuffing, scraping and spam signups.

They're a different thing from the residential, datacenter and mobile proxies the API already flags, which people pay a proxy network to use. An open proxy is one address that forwards whatever it's sent. Of the 3,000 we looked up for this post (below), 2,209 were on networks the API types as `isp` and 700 on `hosting`.

## What a lookup answers

Here's the answer for an address that public proxies' traffic left from on October 24, looked up on October 25 with a Max key, its `ip`, `location` and `asn` cut:

```json
{
  "is_vpn": false,
  "is_hosting": false,
  "is_relay": false,
  "is_tor": false,
  "is_cdn": false,
  "is_resproxy": false,
  "is_dcproxy": false,
  "is_mobproxy": false,
  "is_pubproxy": true,
  "vpn": {},
  "hosting": {},
  "relay": {},
  "tor": {},
  "cdn": {},
  "resproxy": {},
  "dcproxy": {},
  "mobproxy": {},
  "pubproxy": {
    "entry": false,
    "exit": true,
    "protocols": [
      "http",
      "https"
    ],
    "num_ports": 0,
    "num_proxies": 3,
    "last_seen": "2026-10-24",
    "last_usable": "2026-10-24"
  }
}
```

Every other flag is `false`, so a rule built on the eight older flags lets this address through. The `pubproxy` object says what it is:

| Field | What it holds |
|---|---|
| `entry` | a public proxy listens on the address |
| `exit` | a public proxy's traffic left from it: the address a request through that proxy arrives from |
| `protocols` | `http`, `https`, `socks4` or `socks5`, for the proxies at either end |
| `num_ports` | how many ports a proxy listens on there, 0 on an exit only |
| `num_proxies` | how many proxies' traffic left from it, 0 on an entry only |
| `last_seen` | the last day the address was seen at either end |
| `last_usable` | the last day a request through a proxy there was answered, `""` when none was |

The flag covers the last 90 days, like the other proxy flags. `is_pubproxy` and its object come with every paid plan, from Starter up. A free key or none leaves both out, and a field your plan doesn't include is missing, never `false` ([pricing](https://vpndetection.io/pricing)). All twelve SDKs read the new fields, as `isPubproxy` in Node.js and `is_pubproxy` in Python.

## Both ends of the proxy

A request through a proxy often arrives from a different address than the one the proxy listens on. That's why every exit is its own row, marked as one. In the one-day window of October 24, 2026:

- 16,088 addresses were at one end of a public proxy or the other: 13,464 entries and 8,255 exits.
- 2,624 of the exits (32%) were exits only. No proxy listened on them, so a blocklist of the addresses proxies listen on would never have held them, and they're the addresses your logs show.
- 3,605 exits (44%) carried traffic from two or more proxies, and the busiest from 26.

The protocols, counted per address: `http` on 10,615, `https` on 6,824, `socks5` on 2,567 and `socks4` on 2,295.

## Working, or gone quiet

Most open proxies work only some of the time. Of the 13,464 entries, 8,852 (66%) had a proxy answer a request through it on October 24. At the other 4,612, no request through a proxy had been answered, so their `last_usable` is empty. A rule can weigh an address whose proxy answered yesterday above one where no proxy ever has.

## What the other flags already catch

On October 25 we looked up 3,000 IPv4 addresses picked at random from that day's window, on a Max key, and counted the other flags each answered:

| What the API answered | Addresses | Also `is_resproxy` | Also `is_hosting` | Also `is_vpn` | No other flag |
|---|---:|---:|---:|---:|---:|
| Entry only | 1,347 | 316 (23%) | 562 (42%) | 592 (44%) | 251 (19%) |
| Entry and exit | 1,189 | 621 (52%) | 210 (18%) | 648 (54%) | 176 (15%) |
| Exit only | 464 | 348 (75%) | 104 (22%) | 116 (25%) | 56 (12%) |
| All | 3,000 | 1,285 (43%) | 876 (29%) | 1,356 (45%) | 483 (16%) |

483 of the 3,000 (16%) answered no flag but `is_pubproxy`. Three in four exits only had also been seen in a residential proxy pool, and entries only were the likeliest to be on hosting space.

## Adding it to a rule

If your code lists the flags it treats as masked, add `is_pubproxy` to the list. We've done that in the age-gate code of [Utah SB 73: what a site can and can't know about VPN users](https://vpndetection.io/blog/utah-sb-73-vpn) and the [Online Safety Act](https://vpndetection.io/blog/online-safety-act-vpn-detection) post, and reran both with an open proxy among the visitors. An open proxy on a hosting network is a server, which nobody's home line shares. One on an ISP's address may be someone's own connection, so send it to a check rather than turning it away.

## The database

[Public Proxy IP](https://vpndetection.io/databases/public-proxy-ip) comes in six rolling windows, 1, 7, 14, 30, 60 and 90 days, rebuilt daily. A row is one address, with a lookup's fields plus its country: `ip`, `exit`, `entry`, `protocols`, `num_ports`, `num_proxies`, `country`, `last_seen` and `last_usable`. It ships as a gzipped CSV and an MMDB of the same rows, so the file works as a blocklist as it is, and a lookup by the address a request came from finds an exit. The 90-day window held 30,358 rows on October 25.

The [docs](https://docs.vpndetection.io/database/pubproxy-ip) describe every column and give the download call. The database page has a sample cut from the current build, and the full files are licensed: [talk to us](https://vpndetection.io/contact) about yours.

## Getting started

[Sign up](https://app.vpndetection.io/auth/signup) for a key and choose a plan on [pricing](https://vpndetection.io/pricing): Starter and up answer `is_pubproxy` from the first lookup. The [API docs](https://docs.vpndetection.io/api) have the full response.

