MedBillAnalyzer

API

Seven operations

Send a bill and the Explanation of Benefits your insurer issued for the same care. Get back where the two disagree, and a letter you can send about it.

Status: live. The base URL is https://medbillanalyzer.onrender.com and it answers now. It runs on an instance that spins down when nothing is calling it, so the first request after a quiet spell takes about 50 seconds; everything after that is immediate. The document below is generated from the code that serves these operations, not written alongside it.

Shape

What the calls are

CallDoesCosts
POST /v1/cases Reads the documents and compares them. Returns how many findings there are and how much is in question. Free
GET /v1/cases/{id} The same summary, plus every finding in detail once the case is unlocked. Free / paid
POST /v1/cases/{id}/unlock Returns a checkout URL. It never charges anything itself. $10, or $10/mo
POST /v1/cases/{id}/outputs The dispute letter and the phone script, in the patient's name. Paid
GET /v1/cases/{id}/export Everything held about the case, as JSON. Needs no token and costs nothing — you cannot be charged to see what we hold about you. Free
POST /v1/cases/{id}/outcome What came of the letter — corrected, refused, ignored, or never sent. The answer is counted in aggregate and never recorded against the case. Free
DELETE /v1/cases/{id} Destroys the case. Needs the one-time delete token issued when it was created; the case id alone reads, it does not erase. Free

Seven, deliberately. Four do the work; two exist because a person is entitled to take their record back and to destroy it, and a right nobody can exercise through the API is not a right. An agent works better against a surface it can hold at once, so there are no others.

Two things that bite

Read these before you call it

  • Never add the findings together. amount_in_question_cents is already de-duplicated. Two findings routinely describe the same dollars from different angles — a line billed above the contracted rate is usually also part of a bill that asks for more than the plan says is owed — so summing them overstates the problem in a letter a patient signs and sends. Use the total we give you.
  • next_step is addressed to you, not to the patient. It says things like "Ask the patient for a clearer copy". If you are rendering straight to a person, use you_can, which is the same guidance in the second person.
  • The comparison is not done by a model. A reader transcribes what is printed; fixed rules decide what it means. The same documents always produce the same findings, and every finding names the rule behind it.
  • Send the document, not your own transcription. Both work, but bill_document is read by an extractor tuned for these forms and measured against a field-accuracy harness. Your own parse is not.

Errors

Every failure says what to do

Each error carries a stable code to branch on, a message that is safe to show a patient, and guidance. The status is specific on purpose: a generic 4xx sends an agent into a debugging loop that burns the user's usage meter.

StatusMeans
402The case is not unlocked. Call unlock first.
409Nothing to unlock — there were no findings. Do not offer to sell anything.
415We cannot read that kind of file.
422The document was too poor to check. Ask for a clearer copy.
429Back off and retry.
503A dependency is down. Retryable.

Also

MCP, if you prefer it

The same seven operations are exposed as MCP tools over stdio, with the same names and the same schemas — both faces are generated from one declaration, so they cannot drift apart. check_medical_bill, get_case, unlock_case, get_case_outputs, delete_case, export_case, report_outcome.

The machine-readable description is at /openapi.json. It is generated from the routing table, so it describes what the server actually answers rather than what someone remembered to write down.