Rates API
API v1Price one code, a batch of codes, or a year-by-year series against the Medicare Physician Fee Schedule.
Single rate lookup
Price one HCPCS/CPT code for a locality (or the national amount, if none is given) and setting.
/v1/rates/{hcpcs}
- locality
- string
- Composite key "{mac}-{code}", e.g. "01182-18" — see /v1/localities.
- locality_id
- integer
- Numeric locality ID, as an alternative to the composite key.
- zip
- string
- A ZIP resolves the locality via the versioned crosswalk. Combined with an explicit locality, it must agree (422 otherwise). An ambiguous ZIP is rejected — see GET /v1/zip/{zip} for the same ZIP resolved on its own, which answers ambiguous ZIPs instead of erroring.
- setting
- facility|non_facility
- Which practice-expense RVU to use. Default non_facility.
- modifier
- string
- Up to 2 characters, e.g. "26".
- sequestration
- boolean
- Apply the ~2% sequestration reduction after the formula. Default false.
- time_minutes
- number
- Anesthesia only: raw minutes, to compute a real anesthesia amount for status J codes.
- qpp
- boolean
- Physician QPP conversion-factor split (CY2026+).
| Param | Type | Description |
|---|---|---|
| locality | string | Composite key "{mac}-{code}", e.g. "01182-18" — see /v1/localities. |
| locality_id | integer | Numeric locality ID, as an alternative to the composite key. |
| zip | string | A ZIP resolves the locality via the versioned crosswalk. Combined with an explicit locality, it must agree (422 otherwise). An ambiguous ZIP is rejected — see GET /v1/zip/{zip} for the same ZIP resolved on its own, which answers ambiguous ZIPs instead of erroring. |
| setting | facility|non_facility | Which practice-expense RVU to use. Default non_facility. |
| modifier | string | Up to 2 characters, e.g. "26". |
| sequestration | boolean | Apply the ~2% sequestration reduction after the formula. Default false. |
| time_minutes | number | Anesthesia only: raw minutes, to compute a real anesthesia amount for status J codes. |
| qpp | boolean | Physician QPP conversion-factor split (CY2026+). |
curl "https://localishealth.com/v1/rates/99213?locality=01182-18&setting=non_facility" \
-H "Authorization: Bearer sk_live_…"
{
"hcpcs": "99213",
"modifier": null,
"setting": "non_facility",
"payable": true,
"amount": 97.20,
"gross_amount": 97.20,
"status_code": "A",
"sequestration_applied": false,
"conversion_factor": 33.29,
"qpp": false,
"citations": { "sources": { "rvu": { … }, "gpci": { … } }, "calculation": { … } },
"release": { "schedule": "pfs", "year": 2026, "quarter": "A", "revision": 1 },
"locality": { "mac": "01182", "code": "18", "state": "CA", "name": "Los Angeles, CA" }
}
See Citations & provenance
for the full shape of citations. A non-payable result omits
amount/gross_amount and returns
reason instead. Carrier-priced status-C results also include
mac_fee_lookup_hint with reason: carrier_priced
and the matching /v1/mac-fees/{hcpcs} path.
Bulk rate lookup
Price up to 500 codes in one request against a shared locality/setting/release context. A code
that can't be priced doesn't fail the batch — it comes back with payable: false and
a reason.
/v1/rates/bulk
- codes
- array — required
- Up to 500 entries. Each is a string ("99213", "71046-26") or an object { code, modifier?, time_minutes?, qpp? } for per-line anesthesia claims.
- locality / locality_id / zip
- string / integer / string
- Same as the single lookup — shared across every code in the batch.
- setting, sequestration, year, quarter, as_of
- Same as the single lookup — shared across every code in the batch.
| Param | Type | Description |
|---|---|---|
| codes | array — required | Up to 500 entries. Each is a string ("99213", "71046-26") or an object { code, modifier?, time_minutes?, qpp? } for per-line anesthesia claims. |
| locality / locality_id / zip | string / integer / string | Same as the single lookup — shared across every code in the batch. |
| setting, sequestration, year, quarter, as_of | Same as the single lookup — shared across every code in the batch. |
curl -X POST https://localishealth.com/v1/rates/bulk \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{"codes": ["99213", "99214-26"], "locality": "01182-18"}'
{
"release": { "schedule": "pfs", "year": 2026, "quarter": "A", "revision": 1 },
"locality": { "mac": "01182", "code": "18", "state": "CA", "name": "Los Angeles, CA" },
"setting": "non_facility",
"sequestration_requested": false,
"count": 2,
"results": [
{ "hcpcs": "99213", "modifier": null, "amount": 97.20, "payable": true, … },
{ "hcpcs": "99214", "modifier": "26", "amount": 135.61, "payable": true, … }
]
}
Rate history
What one code paid over time, one point per calendar year, priced from that year's earliest published quarter. An explicit locality stays fixed; a ZIP follows the locality assigned by each year's crosswalk, and every point echoes both the release and locality that answered it. A year you want in quarterly detail can be re-requested from the single lookup with year and quarter.
Years the code wasn't separately payable stay in the series carrying their status and a reason rather than a $0 — a code that was carrier-priced until CY2019 reads as exactly that, and change_from_previous compares against the last payable year rather than treating the gap as zero.
/v1/rates/{hcpcs}/history
- locality / locality_id
- string / integer
- Same as the single lookup and held constant across every year in the series.
- zip
- string
- Resolved against each year's versioned crosswalk. If the ZIP moved between payment localities, locality_varies is true and each history point identifies the locality that priced it.
- setting, modifier, sequestration, qpp
- Same as the single lookup — also held constant across the series.
- from_year
- integer
- First calendar year to include. Open-ended results are capped to the most recent 20 available years.
- to_year
- integer
- Last calendar year to include. Omit for the most recent. A closed from_year/to_year window may span at most 20 years and must not run backwards (422).
| Param | Type | Description |
|---|---|---|
| locality / locality_id | string / integer | Same as the single lookup and held constant across every year in the series. |
| zip | string | Resolved against each year's versioned crosswalk. If the ZIP moved between payment localities, locality_varies is true and each history point identifies the locality that priced it. |
| setting, modifier, sequestration, qpp | Same as the single lookup — also held constant across the series. | |
| from_year | integer | First calendar year to include. Open-ended results are capped to the most recent 20 available years. |
| to_year | integer | Last calendar year to include. Omit for the most recent. A closed from_year/to_year window may span at most 20 years and must not run backwards (422). |
curl "https://localishealth.com/v1/rates/99213/history?locality=01182-18&from_year=2024" \
-H "Authorization: Bearer sk_live_…"
{
"hcpcs": "99213",
"setting": "non_facility",
"locality": { "mac": "01182", "code": "18", "state": "CA", "name": "Los Angeles, CA" },
"locality_varies": false,
"basis": "One point per calendar year, priced from that year's earliest published quarter.",
"count": 3,
"history": [
{ "year": 2024, "release": { "year": 2024, "quarter": "A", … },
"locality": { "mac": "01182", "code": "18", … }, "payable": true, "amount": 94.55, … },
{ "year": 2025, "release": { "year": 2025, "quarter": "A", … }, "payable": true, "amount": 96.10,
"change_from_previous": { "amount": 1.55, "percent": 1.64 } },
{ "year": 2026, "release": { "year": 2026, "quarter": "A", … }, "payable": true, "amount": 97.20,
"change_from_previous": { "amount": 1.10, "percent": 1.14 } }
]
}
One request is one rate computation per year, so it costs one rate-limit unit per year in the window (capped at 20) rather than a flat unit per call. A closed from_year/to_year window over 20 years is rejected with 422; an open-ended request returns the most recent 20 available points.
RVU rows
The raw PPRRVU file row(s) behind a rate answer — work/PE/malpractice RVUs, status code, and every payment-policy indicator (global days, bilateral/assistant/co-surgeon, PC/TC split) for one code, every modifier variant included. Reach for this when you need the RVU inputs themselves to reproduce or audit a calculation, not just the priced result from the rate endpoint.
The PPRRVU file's DESCRIPTION column is AMA-copyrighted and is
never included in this response — every other column is.
/v1/rvu/{hcpcs}
- year, quarter, as_of
- Answer from a specific PFS release instead of the latest.
| Param | Type | Description |
|---|---|---|
| year, quarter, as_of | Answer from a specific PFS release instead of the latest. |
curl https://localishealth.com/v1/rvu/99213 \
-H "Authorization: Bearer sk_live_…"
{
"hcpcs": "99213",
"release": { "schedule": "pfs", "year": 2026, "quarter": "A", "revision": 1 },
"source": { "dataset": "rvu", "file": "PPRRVU2026_Jan_nonQPP.csv", "sha256": "…", "row_count": 11762 },
"count": 1,
"rows": [
{
"hcpcs": "99213", "modifier": null, "status_code": "A",
"work_rvu": 1.30, "pe_rvu_nonfacility": 1.46, "pe_rvu_facility": 0.33, "mp_rvu": 0.09,
"total_nonfacility": 2.85, "total_facility": 1.72,
"pctc_indicator": "9", "global_days": "XXX",
"multiple_proc_indicator": "0", "bilateral_surg_indicator": "0",
"assistant_surg_indicator": "0", "co_surg_indicator": "0", "team_surg_indicator": "0",
"endo_base_code": null, "diag_imaging_family": null
}
]
}
A code with -26/-TC component pricing comes back as multiple rows, one per modifier, sorted
with the base (no-modifier) row first. A code absent from the release returns
404.
Bulk RVU rows
The same raw RVU rows as the single lookup, for up to 500 codes against one shared release. A
code with no RVU row doesn't fail the batch — it comes back with count: 0 and an empty rows array.
/v1/rvu/bulk
- codes
- array — required
- Up to 500 HCPCS codes. Each entry is a 5-character string, e.g. "99213".
- year, quarter, as_of
- Same as the single lookup, shared across every code in the batch.
| Param | Type | Description |
|---|---|---|
| codes | array — required | Up to 500 HCPCS codes. Each entry is a 5-character string, e.g. "99213". |
| year, quarter, as_of | Same as the single lookup, shared across every code in the batch. |
curl -X POST https://localishealth.com/v1/rvu/bulk \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{"codes": ["99213", "99214"]}'
{
"release": { "schedule": "pfs", "year": 2026, "quarter": "A", "revision": 1 },
"source": { "dataset": "rvu", "file": "PPRRVU2026_Jan_nonQPP.csv", "sha256": "…", "row_count": 11762 },
"count": 2,
"results": [
{ "hcpcs": "99213", "count": 1, "rows": [ { … } ] },
{ "hcpcs": "99214", "count": 1, "rows": [ { … } ] }
]
}