The dataset behind every figure on this site
Every figure on this site comes out of one file, and that file is published. It holds 35 vendors and 110 plans, each one copied from the vendor's own pricing page, with the address of that page and the day it was read. It is free to reuse under CC BY 4.0.
The same rows come in two shapes. data.json keeps each vendor's plans inside it. The two CSV files are flat, so they open in a spreadsheet. vendors.csv has one row per vendor, 35 rows and 15 columns. plans.csv has one row per plan, 110 rows and 28 columns, and joins back on vendor_key.
What is in it
| Vendors | 35 |
| Published plans | 110 |
| Vendors sold in the United States | 23 |
| Vendors sold in the United Kingdom | 15 |
| Categories | 4: payroll, payroll and HR, PEO, employer of record |
| Vendors publishing a figure we can compute with | 20 |
| Plans published only as a “from” price | 19 |
| Plans whose per-employee fee steps with headcount | 4 |
| Plans that must be bought on top of another plan | 3 |
| Fields a vendor does not state, and which we left empty | 90 |
| Recorded price changes and corrections | 18 |
| Currencies | 2, never converted into each other |
| Oldest and newest check date in the file | 2026-08-20 and 2026-09-06 |
The files
| vendors.csv | One row per vendor: the pricing page, what the vendor publishes, the setup fee, the contract minimum and the check date. UTF-8, comma separated, list values separated by |. |
| plans.csv | One row per plan, with the base fee, the per-employee fee and the eligibility limits. vendor_key joins it to vendors.csv. |
| data.json | One object per vendor with plans[] and the observed price history nested inside. Served with CORS open, so you can fetch it from your own page. |
| feed.xml | RSS. One item per vendor per day a figure moved. |
| changes | The same history as a page, with the old value beside the new one. |
What one row means
In plans.csv a row is one plan as the vendor publishes it, not a price at a headcount. What that plan costs at a given headcount is worked out from base_monthly, per_employee_monthly, includes_employees and tiers; the method page writes out the arithmetic. A vendor with four plans occupies four rows carrying the same vendor_key and check date.
Row order carries no meaning. Vendors and plans come out in the order the source file holds them, not in any ranking, so sorting the file yourself changes nothing about what it says.
| Column | Type | What it holds |
|---|---|---|
key | string | The vendor's identifier on this site. The vendor page is /d/<key>. |
brand | string | Vendor name exactly as the vendor writes it. |
page_url | url | The page on this site that holds this vendor. |
category | string | payroll, payroll-hr, peo or eor. One vendor sits in one category, and figures are only ever compared inside a category. |
markets | list | US, UK or both. A plan only appears in a market whose currency it is priced in, so a vendor sold in both markets can still have plans in one. |
vendor_url | url | The vendor's own home page. |
pricing_url | url | The published pricing page every figure in this vendor's rows was read from. |
pricing_status | string | How much of the price the vendor publishes: public_list (a plain list price), public_formula (published parts that add up to a price), public_calculator (a price only its own calculator will give you), starting_price (published as a “from” price) or quote_only (nothing published). |
pricing_public | boolean | True where the published price is a number this site can compute with, which is public_list and public_formula only. Kept for compatibility with the two-value field this site started with. |
setup_fee | number | One-off setup or implementation fee in the plan's currency. 0 where the vendor states there is none. Empty where the vendor does not say. |
contract_min_months | number | Minimum contract length in months. 0 where the vendor states there is no minimum. Empty where the vendor does not say. |
free_trial_days | number | Length of the free trial in days, where one is published. Empty where none is. |
affiliate_brand | string | The name this vendor carries in our affiliate program register, or empty where the vendor has no program we could join. It changes nothing about ordering; ordering is by computed cost only. |
checked | date | The day this vendor's pricing page was last read. A page is re-read and re-dated even when nothing has moved. |
unconfirmed | list | Fields the vendor does not state publicly, and which are therefore empty rather than estimated. Separated by |. |
| Column | Type | What it holds |
|---|---|---|
vendor_key | string | The key of the vendor this plan belongs to. Join to vendors.csv on it. |
brand | string | Vendor name, repeated on every one of its plans. |
plan_name | string | The plan name exactly as the vendor writes it. |
currency | string | USD or GBP. The currency the vendor publishes the plan in. We never convert one into the other. |
base_monthly | number | The fixed monthly fee, before any per-employee fee. 0 where the vendor charges none. Empty where the vendor publishes no fixed fee figure at all. |
per_employee_monthly | number | The monthly fee per employee. Empty where the vendor publishes none, or where it varies by headcount band and sits in tiers instead. |
includes_employees | number | How many employees the base fee already covers. 0 where the per-employee fee is charged from the first employee. |
min_employees | number | The smallest headcount the plan can be bought at. Empty where the vendor sets none. |
max_employees | number | The largest headcount the plan can be bought at. Empty where the vendor sets none. |
billing | string | monthly, annual or both: the billing term the published price requires. |
price_is_from | boolean | True where the vendor shows the figure as a “from” price. Such a plan is shown on the vendor page but left out of every computed figure, because a lower bound is not a price. |
tiers | json | Where the per-employee fee steps with headcount, the published steps as [{from, to, per_employee}]. Empty where one rate covers every headcount. |
product_type | string | domestic_payroll, global_payroll, peo, eor, contractor, hr_platform or other. Cost is only ever compared inside one product type. |
addon_to | list | For a plan that cannot be bought on its own, the plans it must be added to. Empty where the plan stands alone. Separated by |. |
per_location | boolean | True where the fee is charged per location rather than per company. |
includes_tax_calculation | string | included, add_on, not_included or not_stated. not_stated is the default and means the vendor's own page does not say; it is never filled in by inference. |
includes_tax_filing | string | As above, for filing payroll taxes with the authority. |
includes_direct_deposit | string | As above, for paying employees directly into their accounts. |
includes_year_end_forms | string | As above, for year-end forms such as W-2, 1099 or P60. |
includes_multi_state | string | As above, for payroll across more than one state or jurisdiction. |
includes_off_cycle | string | As above, for payroll runs outside the normal schedule. |
includes_contractor_payments | string | As above, for paying contractors. |
includes_notes | json | The vendor's own wording behind each includes_ value, for the keys where we hold one. |
addons | json | Add-on fees the vendor publishes on the same page, as [{item, kind, amount, source}]. item is multi_state or year_end_forms; kind is how the amount is charged: monthly_flat, monthly_per_extra_state, annual_flat or annual_per_form. Empty where the vendor publishes no add-on figure. Never an estimate: the source field carries the vendor's own wording. |
notes | string | Any condition the vendor attaches to the price, in the vendor's own words. |
pricing_url | url | The vendor's published pricing page this row was read from. |
checked | date | The day that page was last read. |
sources | json | Field-level sources, where a figure on this row was read from a vendor page other than pricing_url, as {field: {url, checked, quote}}. Empty where every figure on the row came from pricing_url on the date in checked. It is never a third-party source: this site reads vendor pages only. |
What is deliberately not in it
No computed values. The monthly total at a headcount, the effective cost per employee per month, the annual and three-year totals and the headcount where one vendor becomes cheaper than another are all worked out at build time from these columns; none of them is stored, so nobody has to trust a number whose derivation is invisible.
No converted currencies. US prices stay in dollars and UK prices stay in pounds. A converted figure is one nobody published, and it would need an exchange rate and a date we do not hold.
No guesses. Where a vendor does not publish something, the field is empty and the field name is listed in unconfirmed instead. 90 fields are excluded that way. An empty cell and a zero are different things: setup_fee is 0 where the vendor states there is no setup fee, and empty where the vendor says nothing about one. The same holds for the seven includes_ columns, where not_stated means the vendor's page does not say: 81 of the 770 cells across 110 plans carry a value the vendor publishes, and the rest are left as not stated rather than assumed.
No ratings. There is no score, star or rank column anywhere in it. Ordering on this site comes from one computed number and nothing else.
The price history is in data.json and not in the CSV. Each vendor's changelog holds the changes observed on its own page since we started checking it, with the old value, the new value, the date and the source. It is history rather than a current figure, so it is left in the JSON and published in full in changes and the feed. We do not reconstruct history from before we started checking a vendor.
How to read what a vendor publishes
pricing_status says how much of the price the vendor puts on its own page, and it is the field to read before comparing anything. Two values, public_list and public_formula, give a number this site can compute with. The other three do not: public_calculator is a vendor whose price exists only inside its own calculator, starting_price is a lower bound rather than a price, and quote_only publishes nothing at all. Plans from the last three are shown on the vendor page and left out of every computed figure.
| pricing_status | Vendors |
|---|---|
public_list | 18 |
quote_only | 11 |
starting_price | 3 |
public_formula | 2 |
public_calculator | 1 |
Comparing across categories or across product types is the other thing the file will let you do and this site will not. A PEO price and a payroll subscription buy different things, so category and product_type are the fences every figure here is computed inside.
How often it changes
Prices are re-read against the vendor's own page and re-dated even when nothing has moved, so a check date is a statement that the page was looked at that day. Any figure older than 90 days is labeled on the page where it appears. The URLs above are stable: the file at each one is replaced, never moved.
License
The data is published under Creative Commons Attribution 4.0. You may reuse it, including commercially, if you credit Per Employee Per Month and link back. The prices themselves are facts published by the vendors; the collection, the column definitions and the wording on this site are ours.
Cite this data
If you quote a figure, please cite the dataset rather than an individual page, and give the date you took it. The figures move.
| Reference | Per Employee Per Month (2026). Published payroll and HR software prices, United States and United Kingdom [Data set]. https://seatbill.com/payroll-pricing/data |
| In a sentence | “According to Per Employee Per Month (2026), …” with a link to https://seatbill.com/payroll-pricing/data |
| License | CC BY 4.0 |
The three research pages on this site are built from this same file, and each one says which plans it counts: how much of a payroll bill the base fee is, what vendors publish about their prices and where one vendor becomes cheaper than another. If you need a cut of the file that is not here, ask and it will be produced.
If a figure is wrong
Tell us through the contact form with the vendor's pricing page you saw it on. It will be re-read, corrected, re-dated, and the correction published in changes with the old value beside the new one.
Related
- Method: the arithmetic and where every figure comes from
- All 35 vendors, and what each one publishes
- The calculator, with your own headcount
- What changed, and when
Written by Kaz, independent publisher. No commercial relationship with the companies named unless it is listed on the disclosure page.
Page last updated: 2026-09-07. Sources: vendor pricing pages only. Figures checked between 2026-08-20 and 2026-09-06. I have not used these products. Nothing here is a personal test result.
Ranking method and formulas: Method. Listing position on this site is not for sale.
Corrections: contact form.