Skip to main content

PublicVPNList API v1

Read current prebuilt snapshots of technically checked OpenVPN, VLESS, Trojan, VMess, Shadowsocks, Hysteria2, TUIC, WireGuard and IKEv2 endpoints. API responses never build the catalog or run a VPN check in the request.

Important: PublicVPNList does not operate these third-party servers. A successful technical check does not guarantee privacy, identity, operator trust, logging practices or future availability.

Quick start

Use the versioned /api/v1/ paths. Respect 429, apply backoff, cache the ETag, and check both expires_at and each record’s last_checked_at.

EndpointPurpose
GET /api/v1/serversFilter, sort and paginate server records
GET /api/v1/servers/{public_id}One record by stable public ID
GET /api/v1/countriesAvailable countries and counts
GET /api/v1/protocolsPublished protocols and transports
GET /api/v1/statsSnapshot counters
GET /api/v1/datasetVersion, lifecycle and export links
GET /api/v1/healthLightweight snapshot health
curl -H 'Accept: application/json' \
  'https://publicvpnlist.com/api/v1/servers?protocol=vless&status=online&sort=last_checked&order=desc&per_page=50'
Result will appear here.

Filters and pagination

ParameterAccepted value
countryTwo-letter ISO code, for example US
protocolopenvpn, vless, trojan, vmess, shadowsocks, hysteria2, tuic, wireguard or ikev2. Omitted keeps the original OpenVPN default.
transporttcp, udp, websocket, grpc and other documented normalized transports
port1–65535
fresh_withinAge in seconds, 1–259200
min_speed, max_latency, min_uptimeNumeric technical filters; unknown uptime is null
statusonline means online at the last technical check
sortspeed, latency, uptime, last_checked, score, first_seen
orderasc or desc
page, per_pageDefault 1 / 50; maximum page size 200
fieldsComma-separated public fields
formatjson

Examples

PHP

$url = 'https://publicvpnlist.com/api/v1/servers?country=US&per_page=10';
$data = json_decode(file_get_contents($url), true);

Python

import requests
r = requests.get('https://publicvpnlist.com/api/v1/servers', params={'country': 'US'}, timeout=15)
r.raise_for_status()
print(r.json()['data'])

JavaScript

const response = await fetch('https://publicvpnlist.com/api/v1/stats');
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const payload = await response.json();

Record fields

FieldsMeaning
idStable public endpoint ID; never a Bitrix element ID.
country_code, country_name, cityPublished location metadata. Unknown or unverified city is null.
hostname, ip, protocol, transport, portPublic connection endpoint metadata allowed by the catalog policy.
speed_mbps, latency_msRepresentative measurements from the PublicVPNList checker region, not a client-side guarantee.
uptime_percent_7d, uptime_hours, sessionsnull until a matching trustworthy measurement window exists; values are never invented.
technical_quality_score, score_labelReachability/performance/freshness signal. It is not a privacy, identity or trust assessment.
last_checked_at, first_seen_at, config_updated_atUTC ISO 8601 timestamps; unknown config-update time is null.
freshness_status, availability_statusSnapshot-relative freshness and state at the last technical check.
source_name, source_urlUpstream attribution.
server_page_url, config_download_urlPublic catalog and current download location. OpenVPN keeps its existing protected download flow; verified URI protocols return the same download URL used by their live table.
transport_security, exit_ip, handshake_ms, https_first_byte_msProtocol-specific connection metadata and checker measurements. Unsupported or unknown values remain null; they are never inferred.
risk_flags, config_sha256Non-secret caution flags and a content hash where available; no configuration content is returned.

HTTP behavior

  • Free API limit: 60 requests per minute per short-lived keyed IP hash. The small cacheable health endpoint is not tied to the filesystem counter so monitoring remains available during counter-storage failures.
  • 400 invalid parameter, 404 unknown endpoint/record, 405 method, 429 rate limit, 500 safe internal error.
  • Use ETag or Last-Modified; unchanged GET/HEAD requests return 304.
  • CORS allows public GET/HEAD without credentials. Duplicate query parameters are rejected.
  • Technical quality score is not a privacy, identity or trust assessment.

See the exact machine-readable contract in OpenAPI JSON and stable files on the exports page.

Changelog and migration policy

v1.2 — August 31, 2026: additive protocol filters, compact checked snapshots, current config download URLs and dedicated documentation for VLESS, Trojan, VMess, Shadowsocks, Hysteria2, TUIC, WireGuard and IKEv2. The no-filter default remains OpenVPN.

v1.1 — July 28, 2026: source-reported and PublicVPNList-measured fields are separate; health exposes snapshot age and generator state and remains independent of counter storage.

v1.0 — July 28, 2026: stable public IDs, strict filters, pagination, conditional caching, rate-limit headers and snapshot exports.

The earlier multiprotocol preview remains temporarily available on its old specialist routes and with ?legacy=1 for list routes. New integrations should use the documented dataset response; legacy compatibility may be retired only after a published migration window.

Breaking changes require a new versioned path. Additive fields may appear in v1; integrations should ignore unknown fields. A deprecated major version will be documented before removal.

Acceptable use: cache results, avoid scraping HTML, do not use the service to conceal abuse, and report unwanted or incorrect endpoint listings through contact/takedown.