EOB extraction for claim-payment comparison

An EOB lists each claim line with billed, allowed, paid, and patient-responsibility columns. Here is how to read those columns.

What an EOB looks like

EOB — sample layoutannotated
Patient & provider
Who received care and the doctor, hospital, or facility that billed.
Claim number & service date
The insurer’s reference for the claim and when the service occurred.
Procedure (CPT) codes
Standardized codes describing each service performed.
Billed vs. allowed amount
What the provider charged vs. the negotiated amount your plan permits.
Insurance paid
The portion your plan paid the provider.
Patient responsibility
Your share — copay, coinsurance, or deductible — the amount you may owe.
Denial / adjustment codes
Reason codes explaining any amount that was not covered.

Illustrative layout for education. A real EOB may vary by issuer.

Evaluate this workflow

For billing teams and patient advocates

Keep billed, allowed, paid, and patient-responsibility amounts distinct.

Check before you accept a record

  • Match claim, provider, patient, and service date before comparing records.
  • Keep denial codes and explanatory text for reviewer context.
  • An EOB and a provider bill are different documents; compare corresponding services.
  • Member and patient may differ. This backend exposes member_name; do not assume it identifies the patient.

An exception to hold for review

Do not label the entire billed amount as patient responsibility. Inspect the source EOB and related bill before acting.

Run a small evaluation

  1. Extract a representative EOB.
  2. Match service and claim details with the comparison record.
  3. Route differences to the billing reviewer.

Record the number of files submitted, failed files, required-field corrections, and minutes spent reviewing each file. Those observations tell you whether this workflow fits your documents; a sample response does not measure extraction accuracy.

Example reviewed September 16, 2026 against the configured field names. Fictional values, partial field set, and a suggested human workflow; not a recorded extraction or a promise of automatic approval.

A measured synthetic extraction

On September 16, 2026 Pacific time, we sent one labeled text PDF for this document type to our production extraction service. It returned HTTP 200 in 4.88 seconds, including network time. This was a backend request, not a test of signup, payment or the complete upload interface.

3 selected field comparisons differed after the production field mapping. Successful delivery does not establish extraction accuracy.

Inspect the field differences
[
  {
    "path": "insurance_company",
    "expected": "Example Health Plan (fictional)",
    "actual": "Example Health Plan",
    "actualMissing": false
  },
  {
    "path": "patient_name",
    "expected": "Sample Patient",
    "actual": null,
    "actualMissing": true
  },
  {
    "path": "denial_codes",
    "expected": [],
    "actual": null,
    "actualMissing": true
  }
]

Expected values were fixed before the run. Comparison uses exact values and types, checks the expected object fields and requires exact array lengths. A numeric string differs from a number; missing and null values differ. These easy, clearly labeled synthetic pages do not represent scanned documents, complex official forms or customer accuracy. One observation cannot establish typical latency.

Field contract correction

We replayed the same recorded response after correcting field aliases, declared tax-number types and bank last-four handling. This is an offline replay, not another extraction request. 3 selected field comparisons still differ from the original expected sample. The original benchmark stays available; unsupported distinctions and source wording are not invented to make the comparison pass.

Inspect the corrected mapping results

Download the 15-page synthetic input packetDownload expected and returned fields

Illustrative structured output

These synthetic values explain the field layout; they are not a measured extraction result or an accuracy benchmark. Actual coverage depends on your document.

{
  "insurance_company": "Example Health Plan (fictional)",
  "provider_name": "Example Clinic",
  "claim_number": "SAMPLE-001",
  "service_date": "2026-08-10",
  "billed_amount": 200,
  "allowed_amount": 150,
  "insurance_paid": 120,
  "patient_responsibility": 30,
  "member_name": "Sample Patient",
  "denial_reason": null
}

Try the interactive sample without signupReview CSV, Excel, and JSON exportsSee the extraction API

Extract from your own EOB — 3 free, no credit card

Want the EOB extraction guide?

Get a free step-by-step guide to extracting and reviewing data from EOBs — plus tips for recurring workflows.

Free. No credit card. Unsubscribe anytime.

FAQ

What does an EOB look like?

An EOB lists each claim line with billed, allowed, paid, and patient-responsibility columns. Here is how to read those columns. The annotated example above shows each region and what it contains.

Can I use this EOB sample as a template?

Use it to understand the layout and fields. When you need the actual data off a real EOB, upload it and get structured JSON/CSV back — no manual typing.

Is an EOB a bill?

No. An EOB explains how your insurer processed a claim. The bill comes separately from the provider.

What does "allowed amount" mean on an EOB?

The allowed amount is the maximum your plan will pay for a service under its negotiated rates — often less than the billed charge.

This page shows an illustrative EOB example for educational purposes and is not tax, legal, or financial advice.