For developers & agents
Claim scrubbing and denial resolution, callable by an agent
An autonomous medical billing agent mid-task needs to know whether a line will bundle, whether a unit count exceeds a limit, and what a denial actually means, with a citation it can show its user. DenialPath exposes the same engine behind the site as a REST API and a hosted MCP server, so an agent calls a tool instead of guessing at an edit.
Quickstart
No key, no signup, one call
Every endpoint works at the anonymous rate with no key. Scrub a claim and get every finding back with the source it came from and a confidence flag.
request
curl -X POST https://denialpath.vercel.app/api/v1/scrub \
-H "Content-Type: application/json" \
-d '{"dateOfService":"2026-07-18","payerSlug":"medicare","lines":[{"code":"10021","modifiers":[],"units":1},{"code":"11102","modifiers":[],"units":1}]}'response 200
{
"data": {
"input": {
"dateOfService": "2026-07-18",
"payerSlug": "medicare",
"lines": [
{
"code": "10021",
"modifiers": [],
"units": 1
},
{
"code": "11102",
"modifiers": [],
"units": 1
}
]
},
"editQuarter": "2026 Q3",
"findings": [
{
"kind": "ptp",
"status": "fail",
"lineIndexes": [
0,
1
],
"codes": [
"10021",
"11102"
],
"summary": "11102 is bundled into 10021 and will be denied as billed",
"rule": "PTP edit with modifier indicator 1. CMS rationale: Sequential procedure. A modifier may bypass this edit, but only when the services were genuinely separate.",
"remedy": "If the two services were distinct (different session, different site, different encounter), append the modifier that describes that distinction to the 11102 line. If they were not distinct, remove 11102.",
"resolvingModifiers": [
"59",
"XE",
"XS",
"XP",
"XU",
"25",
"24",
"57",
"91",
"LT",
"RT",
"78",
"79",
"58"
],
"citation": {
"source": "CMS Medicare NCCI Procedure to Procedure Edits, Practitioner Services",
"url": "https://www.cms.gov/medicare/coding-billing/national-correct-coding-initiative-ncci-edits/medicare-ncci-procedure-procedure-ptp-edits",
"quarter": "2026 Q3",
"retrievedAt": "2026-07-18",
"confidence": "verified"
}
},
{
"kind": "mue",
"status": "pass",
"lineIndexes": [
0
],
"codes": [
"10021"
],
"summary": "10021: 1 unit is within the MUE of 1",
"rule": "MUE 1, adjudication indicator MAI 2. Date of service edit, absolute. Units above this limit are never payable on the same date of service. The edit follows from policy or from the code definition itself and cannot be overcome by documentation, a modifier or an appeal.",
"remedy": "",
"citation": {
"source": "CMS Medicare NCCI Medically Unlikely Edits, Practitioner Services",
"url": "https://www.cms.gov/medicare/coding-billing/national-correct-coding-initiative-ncci-edits/medicare-ncci-medically-unlikely-edits",
"quarter": "2026 Q3",
"retrievedAt": "2026-07-18",
"confidence": "verified"
}
},
{
"kind": "mue",
"status": "pass",
"lineIndexes": [
1
],
"codes": [
"11102"
],
"summary": "11102: 1 unit is within the MUE of 1",
"rule": "MUE 1, adjudication indicator MAI 2. Date of service edit, absolute. Units above this limit are never payable on the same date of service. The edit follows from policy or from the code definition itself and cannot be overcome by documentation, a modifier or an appeal.",
"remedy": "",
"citation": {
"source": "CMS Medicare NCCI Medically Unlikely Edits, Practitioner Services",
"url": "https://www.cms.gov/medicare/coding-billing/national-correct-coding-initiative-ncci-edits/medicare-ncci-medically-unlikely-edits",
"quarter": "2026 Q3",
"retrievedAt": "2026-07-18",
"confidence": "verified"
}
}
],
"summary": {
"total": 3,
"failures": 1,
"bypassed": 0,
"noData": 0,
"clean": false
},
"coverage": {
"ptpPairsLoaded": 40009,
"mueCodesLoaded": 15162,
"note": "Checked against 40009 PTP pairs and 15162 MUE values curated from published CMS sources. This is a subset of the full CMS files. Codes marked no data were not checked and may still be subject to an edit."
}
},
"request_id": "req_2f9c41a7b0e84d15",
"disclaimer": "DenialPath provides billing and administrative guidance based on published CMS and X12 sources. It is not medical advice, not a coverage determination, and not a guarantee of payment. NCCI and MUE edits are republished quarterly and payer policies vary by contract. Always confirm against the payer's own current policy before submitting or appealing."
}Note the citation and status on every finding, and that an unchecked code or pair returns no_data rather than a silent pass. See the full API reference for the citation shape, error codes and the hosted MCP endpoint at https://denialpath.vercel.app/api/mcp.
Built for agents
What an agent actually needs from this API
One engine behind everything
The REST API, the MCP server and the free browser scrubber all run the same pure, dependency-free scrubbing and denial-resolution engine. There is no separate ingestion path to drift, and no finding is ever returned without the citation it came from.
A citation and a confidence on every finding
Each PTP, MUE, CARC and RARC value carries a source URL and a confidence flag: "verified" was read directly off the cited CMS or X12 page, "verify" renders as Unverified so your agent never repeats an unconfirmed value as if it were settled fact.
Single-key auth
One key unlocks the REST API and the MCP server. Send Authorization: Bearer <your-api-key>, live or test. No OAuth dance, no per-endpoint credentials.
Machine-readable docs
A full reference and a spec at /api/openapi, so an agent can onboard itself without a human reading a page first.
Deterministic, no model in the path
Every response is a lookup against cited CMS/X12 data plus deterministic arithmetic. The same claim or denial always returns the same verdict, and a status of no_data means not checked, never a pass, so an agent cannot mistake absence of an edit for a clean claim.
Free to try, safe by default
Every endpoint works with no key, throttled to 4/min and 20/day per IP. A free test key raises that to 10/min against the real engine and never bills, so an agent loop cannot run up a surprise charge while you build.
REST API
Every endpoint
Base URL https://denialpath.vercel.app/api/v1. Send Authorization: Bearer <key> to lift the throttle to your plan's quota. Every endpoint also works with no key at all at the anonymous rate.
/api/v1/scrub
Key optionalScrub a claim: the same engine as the free browser scrubber. Given a date of service, an optional payer, and billed lines (code, modifiers, units), returns every PTP and MUE finding, the CMS edit quarter checked against, and a coverage disclosure. A finding with status no_data means the code or pair was not checked, not that it passed.
request
curl -X POST https://denialpath.vercel.app/api/v1/scrub \
-H "Content-Type: application/json" \
-d '{"dateOfService":"2026-07-18","payerSlug":"medicare","lines":[{"code":"10021","modifiers":[],"units":1},{"code":"11102","modifiers":[],"units":1}]}'/api/v1/denial
Key optionalExplain a denial. Given a CARC (with or without a group prefix) and any RARCs, returns the plain-meaning explanation, ranked corrective actions, an appeal-worthiness rating, and, when a payer is supplied, the appeal deadline context.
request
curl "https://denialpath.vercel.app/api/v1/denial?carc=CO-16&rarc=M51&payer=medicare"
/api/v1/ncci
Key optionalLook up the NCCI PTP edit governing two procedure codes on a date of service, if we hold one: the column order, modifier indicator, effective/deletion dates, and the CMS citation. Returns a no_data status, not a pass, when the pair is outside our loaded dataset.
request
curl "https://denialpath.vercel.app/api/v1/ncci?code1=10021&code2=11102&dos=2026-07-18"
/api/v1/mue
Key optionalLook up the medically unlikely edit for one procedure code: the MUE value, the adjudication indicator (MAI 1, 2 or 3) and what it means for whether an overage can be overcome. Returns a no_data status when the code is outside our loaded dataset.
request
curl "https://denialpath.vercel.app/api/v1/mue?code=0001U"
/api/v1/appeal
Requires a live keyGenerate an appeal letter for a denial: the argument built from cited corrective actions, the citations behind it, and a list of fields the letter could not fill in (claim number, provider name, and so on) that the practice must complete before sending. Requires a live key on Pro or Scale.
request
curl -X POST https://denialpath.vercel.app/api/v1/appeal \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{"carc":"16","payerSlug":"medicare","providerName":"Example Family Medicine","claimNumber":"CLM-2026-00042","dateOfService":"2026-07-18"}'/api/v1/timely-filing
Key optionalDays elapsed and remaining to file an initial claim for a payer, given a date of service, where we hold a published limit. Returns null for a payer whose limit is set by individual contract rather than public policy, rather than guessing a number.
request
curl "https://denialpath.vercel.app/api/v1/timely-filing?payer=medicare&dos=2026-07-18"
/api/pricing
Key optionalMachine-readable plans and quotas, built from the same PLANS constant the pricing page and Stripe checkout read.
request
curl https://denialpath.vercel.app/api/pricing
DenialPath provides billing and administrative guidance based on published CMS and X12 sources. It is not medical advice, not a coverage determination, and not a guarantee of payment. NCCI and MUE edits are republished quarterly and payer policies vary by contract. Always confirm against the payer's own current policy before submitting or appealing.
Keys are not being issued yet.
Accounts open at launch, so you cannot mint a test or live API key on this deployment today. Every endpoint still works right now with no key at the anonymous rate, and the MCP server answers the same way. Everything above describes how a key lifts the throttle once accounts open.
A key lifts the throttle, it does not gate the data
Every endpoint is free at the anonymous rate. A test key is free on every plan, runs the real engine, and never bills, so you can build against the whole surface before you pay. A live key raises you to your plan's quota. See /api/pricing for the machine-readable version.
See plans & quotas