Downloads
| Dataset | What it contains | Files |
|---|---|---|
| Daily aggregates | Per UTC day, probe, test and transport: tests, successes, rate, median time. The best starting point. | 30 days CSV 90 days CSV 90 days JSON |
| Raw measurements | Every probe result, oldest first. At most 31 days per file and 200,000 rows; ask for longer periods in several pieces with from and to. | 7 days CSV 7 days JSON 30 days CSV |
| Events | Up to 500 events and notes (ongoing first, then newest), with the rates before and during. | CSV · JSON |
| App data, daily | Published app-data cells per day, country and transport (only above the device threshold and after the embargo; up to a year back). Empty while app data are off. | CSV · JSON |
Files are named colitu-lab-{dataset}-{from}-{to}.{csv|json}. Times are UTC in RFC 3339; rates are fractions from 0 to 1 (four decimals in CSV); empty cells mean “not measured”. A custom period: https://api.colitu.com/api/v1/lab/export/measurements.csv?from=2026-10-01&to=2026-10-08.
API
Base URL: https://api.colitu.com/api/v1/lab. Read-only, GET only, no authentication. Every answer is JSON in the same envelope:
{
"data": { … },
"license": "CC BY 4.0 — Colitu Lab, lab.colitu.com"
}Errors use {"error":{"code":"…"}} with status 400 (INVALID_RANGE, INVALID_COUNTRY, INVALID_ASN, INVALID_TRANSPORT, RANGE_TOO_LONG, …), 404 (NOT_FOUND), 429 (RATE_LIMITED) or 500 (LAB_UNAVAILABLE).
Common parameters
range—24h,48h,7d,30dor90d, ending now. Orfromandto(RFC 3339 orYYYY-MM-DD;todefaults to now; at most 366 days).country— ISO 3166 code of the vantage point, e.g.RU. Never the server's country.asn— the vantage point's network,8359orAS8359.probe— a probe's short name from/probes.transport— comma list ofhysteria2,vless-reality,vless-xhttp,trojan,shadowsocks,tuic.
Endpoints
| Path | Parameters | Returns |
|---|---|---|
/overview | — | Everything the home page shows: totals, last-24-hour transport health with the change against the 24 hours before, probes, countries, recent events, the 25 newest measurements and the app-data settings (field). |
/summary | country, asn, probe, transport, range | from, to (default 7d) | Success rate, tests, median time and status per transport for the selection, with prev_rate for the window before; reach tests separately. |
/series | country, asn, probe, transport, range | from, to (default 30d) | Success rate over time per transport. Buckets of 1 h (≤ 48 h), 2 h (≤ 8 d), 6 h (≤ 31 d) or 1 day; empty buckets have rate null. |
/countries | range | from, to (default 30d) | Every country measured, from probes, app data or both, with per-transport rates. |
/countries/{cc} | range | from, to (default 30d) | One country: transports, reach, baselines, networks, probes, events and app data. |
/networks/{asn} | range | from, to (default 7d) | One network (AS8359 or 8359): transports, reach, baselines, fingerprint, probes, events and app data. |
/protocols/{transport} | range | from, to (default 30d) | One transport: summary, by vantage point, by server country, compared with the others, app data by country. |
/events | country, asn, probe, transport, status=ongoing, limit (≤ 500, default 100) | Detected degradations and outages and editorial notes, ongoing first, then newest. |
/measurements | probe, country, asn, transport (one), test, from, to, before_id, limit (≤ 1000, default 100) | Raw results, newest first; with from, oldest first. Page back with before_id. transport also takes dns-udp, dns-tcp or https; test is tunnel, reach or baseline. |
/probes | — | The vantage points: location, network, type, version, last report, 24-hour success, 7-day reporting share. |
/export/{dataset}.{csv|json} | range | from, to (default 7d) | Bulk files; see Downloads. |
Example: /summary?country=RU&range=7d · /series?transport=hysteria2,vless-reality&range=30d
Limits and caching
- Rate limit: 240 requests per minute per client, downloads included. Above it the API answers 429; wait a minute.
- CORS: open for
GETfrom any origin (Access-Control-Allow-Origin: *), so the API can be called from a browser. - Caching: answers are cached for 60 seconds (
Cache-Control: public, max-age=60); downloads for 5 minutes. New results arrive about every 20 minutes per probe, so polling faster than once a minute gains nothing.
Embeds
Every view in Compare has an Embed button that copies the code for exactly that selection. Embeds take the same parameters as Compare — country, asn, probe, transport, range (24h, 7d, 30d or 90d) — load no third-party code and carry the attribution with them.
Success over time
<iframe src="https://lab.colitu.com/embed/series?country=RU&transport=hysteria2,vless-reality&range=7d"
title="VPN connectivity in Russia — Colitu Lab" width="100%" height="380"
style="border:0" loading="lazy"></iframe>Transport health (bars)
<iframe src="https://lab.colitu.com/embed/summary?country=RU&range=30d"
title="Transport health in Russia — Colitu Lab" width="100%" height="380"
style="border:0" loading="lazy"></iframe>How to cite
Cite “Colitu Lab, lab.colitu.com”, with the date you retrieved the data and, ideally, the query or file you used. For example:
Colitu Lab. (2026). Colitu Lab: Open measurements of VPN connectivity [Data set]. https://lab.colitu.com (retrieved YYYY-MM-DD)@misc{colitulab2026,
author = {{Colitu Lab}},
title = {Colitu Lab: open measurements of VPN connectivity},
year = {2026},
howpublished = {\url{https://lab.colitu.com}},
note = {Data licensed under CC BY 4.0. Accessed YYYY-MM-DD}
}Licence
The data are licensed under CC BY 4.0: share and adapt them for any purpose, including commercially, with attribution. Network names in the data come from DB-IP ASN Lite (CC BY 4.0). The experiment scripts are at github.com/colitu/vpn-lab. Questions: hello@colitu.com.