For agencies, patient organizations and clinics
Run this for your condition, your state, your people
The whole application is one download, and it runs on your own machine in four commands.
Three ways to adopt
Pick the one that fits. The first needs no code; the second is one line of HTML.
A patient organization or a clinic
Share a survey link with your community
No code, no account, nothing to install
Type your organization’s name and get your own survey link, a QR code, a paragraph to paste, a one-page flyer and a page where your own count appears.
Make your kitA clinic, a patient organization or an agency site
Put a button on your website
One line of plain HTML
A “Price your diagnostic journey” button that opens Waypoint Ledger in a new tab. No script, no cookie, any content security policy.
See it on /developersShow the lineHide the lineThe HTML to paste, with a copy button
Paste into your page <a href="https://waypointledger.org/" target="_blank" rel="noopener" style="display:inline-block;min-height:44px;box-sizing:border-box;padding:12px 20px;border-radius:999px;background:#0e2a3a;color:#fff;font:600 16px/1.2 system-ui,sans-serif;text-decoration:none">Price your diagnostic journey</a>An agency or a team
Run your own copy
One download, four commands
Source, data, migrations, tests and a README, on your own machine. One Cloudflare account runs the full stack with its database.
Take it, in four steps
What you get
Every piece is open. Each tile opens the thing itself.
- Open sourceThe code is Apache-2.0. The data is CC0 1.0, public domain.Read the licence
- Six data filesEvery published figure with its file, year, basis and population.See the six files
- An HL7 FHIR R4 BundleEvery ledger downloads as an HL7 FHIR R4 Bundle.Open an example
- An open-data catalogDCAT-US v1.1, the metadata standard data.gov harvests.Open /data.json
- A QR code and flyer kitA survey link, QR code and one-page flyer for your community.Make yours
- 1 Cloudflare accountOne D1 database and one KV namespace run the full stack.How to run it
Interoperability standards, and where each one stands today
Standards it speaks today
Written, switched off
Not connected, not claimed
The rule that has to survive the fork
No model, average or interpolation in this codebase produces a dollar figure. Every priced line is a row of a published federal file, or the product of published federal figures with the formula printed, carrying its year, its basis and the population it describes.
Long COVID The two long COVID year-ahead rows are a peer-reviewed analysis of a federal survey: they are labelled as that, shown apart and never added to a total.
If you keep one thing when you adapt this, keep that.
Take it, in four steps
This page is the procedure, not the pitch: the files you change, the command that refuses a figure that does not reproduce, and what happens when no federal file describes the people you serve.
Download it and run it
No account, no request, nothing to sign. The archive is the tree this site is built from, minus the build output and our own credentials: app/, components/, lib/, data/, cf/functions/, cf/migrations/, scripts/, tests/, and a README that is these commands with the reasons attached.
Show the commandsHide the commandsDownload, test and run it, then the full stack with its database
Download, test, run # the whole application: source, data, migrations, tests, README curl -sL https://waypointledger.org/waypoint-ledger-source.tar.gz | tar -xz cd waypoint-public npm install npm run build:static # the static export the size budgets measure npm test # the suite that guards every rule below npm run dev # http://localhost:3000 # the full stack, with the database, on your own Cloudflare account npx wrangler d1 create waypoint-ledger # put the id in cf/wrangler.toml npx wrangler kv namespace create LEDGER # put the id in cf/wrangler.toml npm run db:migrate:local npm run dev:full # http://localhost:8788The Cloudflare configuration ships with placeholders rather than our project’s identifiers, so a first run cannot point at somebody else’s deployment. Nothing in the archive talks to us: take it offline and every figure on this page still reproduces from the published files it cites.
Prove every figure reproduces
The two commands that keep it honest, and the suite that guards every rule.
Show the two checks and the test suiteHide the two checks and the test suiteverify_price_table.py, gen-locality-table.mjs and npm test, and what each one refuses
Run python3 data/verify_price_table.pyRe-downloads every federal file, hashes it, and re-derives every figure. Exits 1 if a row does not reproduce from the file it cites.
Run node scripts/gen-locality-table.mjsRecomputes all 5,668 locality figures from the published RVUs and geographic indices. Exits 1 on one cent of drift, and names the row.
Run npm testRuns the rules as tests, not as prose: that no code path can produce a dollar figure, that figures on different bases are never added, that the published catalog validates against the government’s schema, and that the licence on the page is the licence in the tree.
Point it at your people
Four kinds of change. Open the one you need.
Another condition
One object in data/conditions.json. No figure lives there.One object in data/conditions.json, pointing at a row that already exists in the price table. No figure lives in the conditions file, so adding a condition cannot introduce a number nobody checked.
adding a condition # 1. find or add the published figure, in data/prices.json # a row needs the file it came from, the year, the population it describes # and its basis. Nothing else may carry a dollar amount. # 2. prove the row reproduces from the file it cites python3 data/verify_price_table.py # exits 1 if your row does not # 3. name the condition, in data/conditions.json { "id": "sickle-cell", "label": "Sickle cell disease", "icd10cm": "D57.1", "icd10cm_source": "CDC/NCHS, ICD-10-CM code descriptions, FY2026", "price_row_id": "your-new-row-id", # or null, and the product says so "figure_kind": "condition_attributed", # or "excess"; they are not the same number "note": "…" } # 4. nothing else. The panel renders whatever that row says.No published figure Set
price_row_idto null. The product then says, in its own voice, that no federal source publishes an annual figure for that condition, and sends the person to the gap so the absence is counted. An absence you count is data. An absence you fill with the nearest number is a fabrication.Another state
Nothing to edit. All 109 CMS payment localities ship with the tool.Nothing to edit. All 109 CMS payment localities ship with the tool, so a person in any state sees their own locality’s figure and the drawer shows the three geographic indices that produced it. What you change is what you build on top: hand the API your state and it reprices every line without the interface.
checking or adding a state figure # every state is already priced. To check one: grep '^cms-99213,.*,TX-31,' public/data/locality-prices.csv # to add a service, add a row to data/prices.json with its CPT/HCPCS code, # then re-derive every locality figure from the CMS files: python3 data/build_state_prices.py <dir-with-PPRRVU2026_Jul_nonQPP.csv-and-GPCI2026.csv> node scripts/gen-locality-table.mjs # recomputes all 5,668, exits 1 on a cent of driftOne curl returns your state’s figure with the arithmetic:
GET /api/table?locality=IA-00, or/api/localities/IA-00for every figure published for one place.Refused, never guessed A locality we cannot honour is refused with a sentence, never answered with the national number.
The generator is also the audit: it recomputes every one of the 5,668 figures from the RVUs and the geographic indices on its own row and exits non-zero if a single one is off by a cent. A published number that drifts from the formula printed beside it cannot leave this repository.
Another population
lib/fit.ts holds the whole rule in one function.lib/fit.ts holds the whole rule in one function: given a published row and a person, does this figure describe them. It chooses between published figures and never computes one.
adding a coverage rule // lib/fit.ts: fitOf() is the whole rule, in one function. // Add the coverage to COVERAGE_OPTIONS, then add its branch: case 'tricare': return base('REFERENCE PRICE', 'TRICARE pays its own rates and they are not in this table. ' + 'This is the federal reference figure for the same service.'); // A population with no published figure returns NOT DESCRIBED with // offerGap: true. That is the honest answer and it is counted at /gap, // never filled with the nearest number.The API answers the same question as the screen, from the same module:
POST /api/pricewithcoverageandstatereturns the fitted figure and the verdict per line. See the API.Your own community, counted separately
Give your organization a channel slug on the survey link.The burden instrument takes a channel. Give your organization a slug and every answer through your link carries it, in the public export and in the channel counts on the register. The register prints the slug exactly as it arrived and never an organization’s name, and anyone who has the link can answer through it, so read that count as answers through the link.
your organization's survey link https://waypointledger.org/survey?c=your-org-slug # the slug keeps lowercase letters, digits and hyphens, 24 at most. A link # typed as ?c=MEAction is read as meaction, and the person answering is told # which slug their answer is counted under. It is published as the channel # column of /api/export/survey.csv, so answers through your link are # separable from everyone else's, by you and by anyone reading the export. # Anyone who has the link can answer through it.Small cells Small cells are suppressed on the server before anything is published: a self-description held by fewer than 11 answers is counted as “fewer than 11, not shown” and never named, and the export carries no self-description at all.
The instrument, its exact wording and every response option are in dictionary.csv, so a reviewer can read the questions without running the site.
Send back what your community finds
The corrections, and the care that never entered a claims file. What we would want to know says why.
What you are starting from
Six files hold everything. Each one has an open download.
data/prices.json274 published figures: 272 from federal files and 2 from a peer-reviewed analysis of a federal survey. 251 of them are priced and addable, each with its file, year, basis, population and combination rules. Version 2026-09-09.1.
data/state-prices.json5,668 figures: 52 CMS codes priced for each of the 109 Medicare payment localities in 53 states and territories, every one re-derived from CMS’s own formula.
data/conditions.json72 conditions. 68 carry an ICD-10-CM code from the CDC/NCHS file; 3 point at a published year-ahead figure and the rest carry an explicit null, because no federal file publishes one.
data/synonyms.jsonExtra plain-language phrases that map to a unit of care, beyond the ones each price row already carries. This and the row synonyms are the whole matcher; there is no model behind it.
public/data.jsonA DCAT-US v1.1 catalog describing every open file here (the metadata standard data.gov harvests), validated against the government’s own published JSON Schema. Point a harvester at it and these files appear in a catalog beside the federal files they came from.
cf/migrations/0001_init.sqlThe whole schema: journeys, corrections, gap reports, survey responses, interviews, the change log. One file, no ORM.
Column meanings: price-dictionary.csv and locality-dictionary.csv. The data is CC0 1.0: the federal figures are U.S. Government works and already public domain, and our arrangement of them is dedicated to the public domain too. The code is Apache-2.0. Both are files you can read, not sentences on a page: LICENSE and NOTICE, which says line by line which licence covers what.
Every condition the tool reads, its published figures and their sources, and the schema for adding one: Conditions.
Standards
HL7 FHIR R4 is live. Nothing listed is a connection we do not have.
Where this tool stands against each standard the challenge names, today. Nothing on this list is a connection we do not have.
| Standard | Today | What that means here | Next step |
|---|---|---|---|
| HL7 FHIR R4 | Live | Every ledger downloads as an HL7 FHIR R4 Bundle, with CPT and HCPCS codes, and a LOINC code on 36 of our 81 lab tests. /api/fhir/example returns one. The test suite checks every Bundle against HL7’s official R4 schema. | Run the same HL7 validator against the US Core profiles and publish every gap, as was done for base R4 (0 errors, 14 warnings). |
| USCDI | Four data classes | The Bundle carries data from four USCDI classes and no others: Encounter Information (the kind of visit), Procedures (CPT and HCPCS codes), Laboratory (the test, by its LOINC code) and Provenance (who wrote the record, and when). It has no name, birth date, dates of care or other identifiers, because the tool never asks for them. It does not use the US Core profiles. | Add a fifth class, Health Insurance Information, as the coverage type the person already picks on their own device, with no member or payer ID. |
| Blue Button 2.0 | Written, switched off | Blue Button lets a person with Medicare share their Part A, B and D claims with an app. Our import is written against the CMS sandbox and stays off until CMS issues us credentials. /api/bluebutton/status says so. | Sandbox import built and tested on CMS's synthetic claims; switched on once Precision Federal accepts the CMS terms. |
| CMS Interoperability Framework | Not pledged | CMS’s voluntary criteria for health data networks and the apps that use them. We are not a CMS Aligned Network. Two of its criteria match choices already made here: lab codes in LOINC inside FHIR, and passkeys for sign-in. Price transparency is one of its newest use cases. | Check this tool against each of the framework’s criteria and publish the result, including one it does not meet: accepting a CMS-approved IAL2 digital credential at sign-in. |
| TEFCA | Not connected | The nationwide framework HHS set up for sharing health records between providers, patients, payers and public health. This tool holds no health records and takes no part in it. | None as built: TEFCA moves patient data between hospitals, health systems and public health agencies, and this tool never asks for a name, birth date or record number (what we store). |
| USCDI+ | Not used | Lists of data elements that extend USCDI for a particular program or field. We use none today. | Propose the elements this ledger uses (a billing code, its published price and the federal file behind it) on the USCDI+ platform when it opens a submission window for a fitting domain, as it has for public health use cases. |
What we would want to know
The corrections, not a thank-you.
If you stand this up, the thing worth sending back is not a thank-you. It is the corrections: which published figure your community says does not describe them, and what care never entered a claims file at all. Each correction is bound to the row of the agency that published the number, so it can be handed to that agency.
Not yet delivered None has been delivered to an agency yet. It will carry more weight with more than one community behind it.
Here is what one of those looks like: the provenance and the counts for a single row, in a form that needs nothing of ours to read.
Questions, or a row you think is wrong: Contact.







