# Free proxy API

`GET /api/free-proxy` returns Litport's current public free-proxy observations. It requires no authentication.

## Request

```bash
curl --get 'https://litport.net/api/free-proxy' \
  --data-urlencode 'country=de' \
  --data-urlencode 'protocol=http' \
  --data-urlencode 'uptimeRating=90' \
  --data-urlencode 'sortBy=responseTimeMs_asc' \
  --data-urlencode 'limit=50'
```

| Parameter | Type | Default | Current behavior |
| --- | --- | --- | --- |
| `country` | string | all | Case-insensitive ISO-2 code. The value is uppercased; no aliases are applied. |
| `limit` | integer | 50 | Accepted range 10–1000. Invalid or out-of-range values are ignored. |
| `page` | integer | 1 | Accepted range 1–1000. Invalid or out-of-range values are ignored. |
| `sortBy` | string | pingAt_desc | Field: pingAt, responseTimeMs, or createdAt. Direction: asc or desc. Invalid values are ignored. |
| `anonymityLevel` | string | all | Exact filter. Unknown values usually return an empty array. |
| `protocol` | string | all | Exact filter such as http, https, or socks5. Unknown values usually return an empty array. |
| `uptimeRating` | integer | none | Minimum 24-hour uptime percentage, 1–100. Invalid values are ignored. |
| `responseTimeMs` | integer | none | Maximum HTTP response time in milliseconds, 1–10000. Invalid values are ignored. |
| `format` | string | json | json, csv, txt, or txt-proto. Unknown values fall back to JSON. |
| `download` | flag | off | When present for a supported format, returns an attachment. |

`country` uses a case-insensitive ISO-2 code and is uppercased for lookup. It has no alias table: use `country=gb`; `country=uk` may return an empty array. PPG proxy usernames have different compatibility behavior.

## Response behavior

The default JSON response is a bare array with no `data` envelope, total, or `hasMore` value. Pagination is blind: page offset is `(page - 1) * limit`, and an empty array means no rows matched that page.

Responses send `Cache-Control: no-cache, no-store, must-revalidate`. Do not rely on an intermediary cache. Invalid numeric parameters and invalid `sortBy` values are silently ignored in this version, leaving their defaults. Unknown exact filter values commonly produce an empty array rather than a `400` response.

```json
[
  {
    "protocol": "http",
    "host": "192.0.2.10",
    "port": 8080,
    "externalIp": "192.0.2.10",
    "geoCountry": "US",
    "responseTimeMs": 420,
    "uptimeRating": 97,
    "pingAt": "2026-08-25T12:00:00.000Z"
  }
]
```

Example addresses in this documentation are reserved for documentation and are not live proxies.

## JSON fields

| Field | Type | Meaning |
| --- | --- | --- |
| `protocol` | string | Proxy protocol. |
| `host` | string | Proxy hostname or IP address. |
| `port` | integer | Proxy port. |
| `externalIp` | string | Observed exit IP. |
| `geoCountry` | string | ISO-2 exit country. |
| `geoCountryFlagEmoji` | string | Country flag for display. |
| `geoRegion` | string | Observed exit region. |
| `geoCity` | string | Observed exit city. |
| `geoTimezone` | string | Observed exit timezone. |
| `asn` | integer | Observed autonomous system number. |
| `asnOrgName` | string | Observed network organization. |
| `anonymityLevel` | string | Measured anonymity classification. |
| `anonymityLevelRating` | integer | Normalized anonymity score. |
| `responseTimeMs` | integer | Measured HTTP response time in milliseconds. |
| `responseTimeRating` | integer | Normalized response-time score. |
| `uptimeRating` | integer | Rounded 24-hour uptime percentage. |
| `createdAt` | date-time | When Litport first observed this proxy. |
| `pingAt` | date-time | When Litport last checked this proxy. |

`createdAt` records when Litport first observed the proxy. `pingAt` records the last check and is the relevant freshness signal.

## CSV and text formats

```bash
# CSV
curl 'https://litport.net/api/free-proxy?format=csv&limit=25'
```

```bash
# host:port, one proxy per line
curl 'https://litport.net/api/free-proxy?format=txt&limit=25'
```

```bash
# protocol://host:port, one proxy per line
curl 'https://litport.net/api/free-proxy?format=txt-proto&limit=25'
```

Use `download=1` with a supported format to request an attachment. CSV is returned as `text/csv`; text variants use `text/plain`; JSON uses `application/json`.

## JavaScript example

```js
const url = new URL('https://litport.net/api/free-proxy')
url.searchParams.set('country', 'us')
url.searchParams.set('limit', '25')

const response = await fetch(url)
if (!response.ok) throw new Error(`HTTP ${response.status}`)
const proxies = await response.json()
```

## Python example

```python
import json
import urllib.parse
import urllib.request

query = urllib.parse.urlencode({"country": "us", "limit": 25})
with urllib.request.urlopen(f"https://litport.net/api/free-proxy?{query}") as response:
    proxies = json.load(response)
```
