API

All endpoints are open. No key, no registration, no counting. The responses are published under the same licence as the dataset.

Basics

Base address
https://vpn-matrix.com
Authentication
none
Cross origin
open to all origins
Format
JSON, UTF-8, unless stated otherwise
Licence
CC-BY-SA-4.0
Usage limit
no hard limit. If you need the whole dataset, fetch the export once instead of ninety profiles one by one.
Caching
Responses carry cache-control and may be cached. The dataset changes in days, not in seconds.
Stability
The criterion keys are stable and the reliable basis for your own analysis. New fields can appear at any time, so consumers should ignore unknown fields instead of failing on them.

Endpoints

GET/api/provider/{slug}

One provider profile with all evidenced cells and their sources.

Cells without a value and cells with confidence unknown are omitted. The coverage block reports the number of criteria, of filled cells and of cells with at least one source.

Parameters

slug
The slug of the provider, for example mullvad. The list of all slugs is in the full export.
locale
Language of the notes, de or en. Default is de. Values themselves are language neutral.

Errors

404
Unknown slug.

Example response

{
  "license": {
    "id": "CC-BY-SA-4.0",
    "url": "https://creativecommons.org/licenses/by-sa/4.0/",
    "attribution": "vpn-matrix.com"
  },
  "generatedAt": "2026-08-03T09:12:44.201Z",
  "provider": {
    "slug": "mullvad",
    "name": "Mullvad VPN",
    "status": "active",
    "kind": "vpn",
    "parentCompany": "Amagicom AB",
    "cluster": "independent-privacy",
    "websiteUrl": "https://mullvad.net/en",
    "verified": false
  },
  "coverage": { "criteria": 158, "filled": 90, "sourced": 90 },
  "data": {
    "logging.activity_logs": {
      "value": "no",
      "confidence": "confirmed",
      "note": "Razzia 04/2023: die Behörden gingen ohne Daten.",
      "sources": [
        {
          "url": "https://mullvad.net/en/blog/2023/4/20/...",
          "title": "Mullvad VPN was subject to a search warrant",
          "retrievedAt": "2026-08-03",
          "archiveUrl": "https://web.archive.org/web/2026/...",
          "kind": "vendor_doc"
        }
      ]
    }
  }
}
Call it live

GET/api/cell/{provider}/{criterion}

A single cell with value, confidence, all sources and the public history.

The history contains published changes only. Pending suggestions and rejected submissions never appear, here or anywhere else.

Parameters

provider
The slug of the provider.
criterion
The key of the criterion, for example logging.activity_logs. The dot does not need encoding.

Errors

404
Unknown provider or unknown criterion.

Example response

{
  "provider": { "slug": "mullvad", "name": "Mullvad VPN" },
  "criterion": {
    "key": "logging.activity_logs",
    "labelDe": "Aktivitäts- und Traffic-Logs",
    "labelEn": "Activity and traffic logs",
    "type": "enum",
    "unit": null,
    "volatile": false,
    "categoryKey": "logging"
  },
  "datapoint": {
    "value": "no",
    "confidence": "confirmed",
    "noteDe": "...",
    "noteEn": "...",
    "lastAuthorType": "editor",
    "updatedAt": "2026-08-03T09:12:44.201Z"
  },
  "sources": [
    {
      "url": "https://mullvad.net/en/help/no-logging-data-policy",
      "title": "No-logging of user activity policy",
      "retrievedAt": "2026-08-03",
      "archiveUrl": null,
      "kind": "vendor_doc"
    }
  ],
  "history": []
}
Call it live

GET/api/export

The complete dataset in one response.

Contains categories, the criteria catalogue and all providers with their datapoints and sources. This response is several hundred kilobytes and should be cached.

Parameters

format
json or csv. Default is json.

Errors

400
Unknown format.

Example response

{
  "license": { "id": "CC-BY-SA-4.0", "attribution": "vpn-matrix.com" },
  "generatedAt": "2026-08-03T09:12:44.201Z",
  "counts": { "providers": 85, "criteria": 161, "datapoints": 728, "sources": 969 },
  "categories": [{ "key": "company", "labelDe": "...", "labelEn": "...", "sortOrder": 1 }],
  "criteria": [
    {
      "key": "logging.activity_logs",
      "categoryKey": "logging",
      "type": "enum",
      "enumValues": ["no", "yes", "unclear"],
      "labelDe": "...", "labelEn": "...", "helpDe": "...", "helpEn": "...",
      "sortOrder": 23, "volatile": false, "system": false
    }
  ],
  "providers": [
    {
      "slug": "mullvad",
      "name": "Mullvad VPN",
      "status": "active",
      "kind": "vpn",
      "parentCompany": "Amagicom AB",
      "verified": false,
      "datapoints": [
        {
          "criterionKey": "logging.activity_logs",
          "value": "no",
          "confidence": "confirmed",
          "noteDe": "...", "noteEn": "...",
          "sources": [{ "url": "https://...", "retrievedAt": "2026-08-03", "kind": "vendor_doc" }]
        }
      ]
    }
  ]
}
Call it live

GET/api/health

Operating state of the application and the database.

Answers with 200 only when the database is reachable as well, otherwise with 503. Meant for container orchestration and uptime checks, not for data queries.

Example response

{
  "status": "ok",
  "database": "up",
  "latencyMs": 3,
  "time": "2026-08-03T09:12:44.201Z"
}
Call it live

Citing and reusing

The licence asks for attribution and share alike. If you quote a cell, please quote its source with the retrieval date too. That is the whole point: we are not the evidence, the source behind the cell is.

Creative Commons Attribution-ShareAlike 4.0 International

For AI assistants

A short machine readable description of the project, the licence, the endpoints and the citation request lives at /llms.txt. Anyone quoting from this dataset should name the source behind the cell and not only us.

/llms.txt