Open data · CC BY 4.0

The business VPN pricing dataset: 24 vendors, 59 plans, in JSON and CSV

What is in the two files behind this site, column by column, how much of each field the vendors actually publish, and what has changed since the data opened.

Two files hold the same dataset: 24 vendors and 59 plans in data.json, and the 24 plans the formula can run in tool-data.csv. Both are CC BY 4.0 and free to take.

Every figure is copied from the vendor's own pricing page and carries that page's URL and the date it was read. No computed value is stored in either file, and nothing is estimated. First published 2026-08-21; the change log below lists everything that has changed since.

The files

Which of the two you want

The same dataset in two shapes. Both are generated by the same build, from the same source rows.
 data.jsontool-data.csv
One row isone vendorone plan we can compute with
Rows2424
Vendors covered2410
Plans covered59, including contact-sales tiers and add-ons24
Shapenested: plans sit inside their vendorflat: one line per plan, no nesting
Also carriesthe reason a price is missing, the fields the vendor does not state, optional charges, quantity conditions, the vendor's own wording, and the change logthe fourteen columns below and nothing else
Use it foranything that has to be honest about what is missingdropping straight into a spreadsheet

Scroll sideways on a phone.

The CSV is the smaller claim. It holds only what can be divided by a number of people, so a vendor that publishes nothing, or publishes something that is not a rate per person, is simply not in it. That absence is not a judgment about the vendor, and the JSON says so explicitly for every one of them.

Why fourteen vendors are in the JSON but not the CSV

Ten of the 24 vendors have at least one plan the formula can run. The other fourteen fall into three groups, and this site does not mix them:

  1. Seven do not publish a price. Their own pages ask you to contact sales: Appgate SDP, Cato Networks, Cisco Secure Access, Cloudflare One, SonicWall Cloud Secure Edge, Todyl and Zscaler.
  2. Four publish a page we could not read. The figures are drawn by scripts that did not run when we retrieved the page. That is our limitation, not a refusal by the vendor: ExpressVPN for Teams, Perimeter81, Proton VPN Business and Surfshark Business.
  3. Three publish something, but not a rate per person. Their numbers are in the JSON with the vendor's own wording, and they are kept out of every per-user ranking on this site.
    • Pritunl — it is billed per server, so the cost per person depends on how many people share it.
    • PureVPN Business — two of its plans publish the price as a “from” figure and the one exact per-person amount on the page belongs to an optional add-on.
    • VyprVPN Business — four of its plans publish a flat monthly fee rather than a rate per person.

The fourteen CSV columns

Every column in tool-data.csv, and what an entry in it means.
ColumnWhat it holds
vendorThe vendor's own name for itself. The short identifier used in this site's URLs is in data.json, not here.
planThe vendor's own name for the plan or tier.
categoryZero-trust network access, business VPN, or self-hosted and per-server.
currencyThe currency the vendor publishes in. Nothing is converted, so this column is not something to sort across.
per_user_annualThe per-user monthly rate the vendor publishes for yearly billing.
per_user_monthlyThe per-user rate for month-to-month billing.
min_usersThe smallest number of users the plan bills, where the vendor states one. Empty means nothing is stated, which is not the same as a stated minimum of one.
max_usersThe upper limit on the plan, where one is published.
free_usersThe published free allowance, in users.
required_fixed_monthlyA fixed monthly charge the vendor states is required. Optional charges are left out of this column and kept in data.json with their own flag.
fixed_labelThe vendor's own name for that charge.
setup_feeA published one-off fee.
checkedThe date this row was last read from the vendor's page.
source_urlThe page it was read from.

Scroll sideways on a phone.

The header line and one real row, exactly as the file has them:

vendor,plan,category,currency,per_user_annual,per_user_monthly,min_users,max_users,free_users,required_fixed_monthly,fixed_label,setup_fee,checked,source_url NordLayer,Core,Zero-trust network access,USD,,11,5,,,40,Server with Dedicated IP,,2026-08-21,https://nordlayer.com/pricing/

data.json carries more than these fourteen. Only there will you find why a price is missing, which fields the vendor does not state, optional charges and the conditions attached to them, the number of devices and the contract length where those are published, the vendor's own sentence behind each figure, and the change log. If you are reporting on what vendors disclose rather than on prices, the JSON is the file with the answer.

How much of each field the vendors actually publish

Counted over all 59 plans in the dataset, including the ones with no price at all. An empty cell is never a zero and never a guess.

Plans that state each field, out of 59.
FieldPlans stating itWhat an empty one means
per_user_monthly26The vendor publishes no month-to-month rate for that plan.
per_user_annual8No yearly rate is published, or the plan is not billed per user.
min_users19No minimum is stated. We do not read that as a minimum of one; we read it as nothing stated.
max_users9No upper limit is stated.
free_users5The plan has no published free allowance.
fixed_monthly15The plan carries no gateway, dedicated-IP or base charge with a published amount.
fixed_label15Empty wherever there is no fixed charge; otherwise it holds the vendor's own words for it.
fixed_required18Empty where there is no fixed charge. False means the charge exists and is optional, and every computed figure ignores it.
fixed_qty_note17The vendor states no quantity condition, such as one per network or one per member.
devices_included7No device count is published for the plan.
contract_months6No contract length is attached to the published price.
free_trial_days11No trial length is published.
setup_fee0No setup fee is published.
notes59Never empty. Every plan carries the vendor's own wording for the condition behind the figure.

Scroll sideways on a phone.

The setup fee is the clearest case. The formula has a place for one and not a single plan here publishes one, so the column is empty in all 59 rows. It stays in both files rather than being dropped, because “no vendor publishes this” is a finding and a missing column is not.

The vendor-level fields, and the least complete one

Each of the 24 vendor entries carries a name, a home page, a pricing page, a currency, a category, one of three reasons its price is or is not readable, and a list of the fields it does not state. Those lists hold 115 entries between them, which is the honest size of what these vendors leave unsaid.

Ownership is the field we have least of: a parent company is recorded for one of the 24 vendors, and the rest name parent_company in their unconfirmed list. Several of these companies have been bought or renamed, and we will not print an owner we cannot point at a page for.

Versions, and what has changed

The dataset opened on 2026-08-21, when all 24 vendors were read on the same day, and that is still the date of the last full re-read of every row. There is no version number: the check date on each row is the version, and _updated at the top of data.json is the date of the last full refresh.

Since then the change log holds seven entries across two vendors (Firezone and OpenVPN CloudConnexa), on one date (2026-09-05).

Every one of them is a correction to our own reading — a figure this site had wrong, or a plan that had been renamed on the vendor's page before we looked again. Not one is a vendor raising or lowering a published price. That is worth saying plainly rather than letting a change log imply a market is moving when what moved was our reading of it.

The entries themselves, one per figure, are in each vendor's changelog in data.json and listed in full under what changed here.

To tell whether your copy is stale: compare _updated at the top of data.json with the date on this page, then compare _checked on the individual rows you care about. A row re-read on its own carries a later date than the full refresh, and any figure older than 90 days is labeled on the site as not re-checked.

What is not in the files

License, and how to cite it

Both files are published under Creative Commons Attribution 4.0. You may republish, reshape and sell work built on them, including commercially, as long as you credit the source. No permission needs to be asked for and none is withheld.

A citation that carries the version:

Per User Plus. Business VPN and zero-trust access pricing per user. Data read 2026-08-21, retrieved 2026-09-07. https://seatbill.com/vpn-pricing/dataset CC BY 4.0.

If you find a figure that does not match the vendor's page, say so. It will be re-read, re-dated, and written into the change log whichever way it turns out.

How we count

Several different totals appear on this site because they answer different questions. All of them are computed from the same dataset at build time; none is typed by hand.

Related


Written by Kaz (pen name). Figures are copied from providers' published pricing pages on the dates shown. We have not used these products. Corrections: contact form.