A medical document extraction API should accept scans and PDFs of EOBs, claims, lab reports and intake forms, and return structured fields rather than raw text. Each field should carry a typed value, a confidence score and its page location. It should also handle long documents asynchronously, sign a BAA, log access and delete files on your schedule.
What does a medical OCR API do beyond plain text OCR?
A medical OCR API turns a page into named, typed fields, while plain text OCR stops at characters and their positions. Optical character recognition (OCR) reads the letters on an image. Extraction decides which of those letters are the allowed amount on line 2 and returns them as a number.
Plain OCR output is a list of words or lines with coordinates. That is useful for search and for making a scanned chart findable, but a billing system cannot post a payment from it. Someone, or something, still has to find the claim number, match each amount to its column and know that "CO 45" beside a line is an adjustment code.
A medical document extraction API adds several steps on top of OCR.
- Classification. It works out what kind of document each page is, so an EOB is not parsed with lab report rules.
- Splitting. It separates a packet into documents, and a bulk EOB into patients and claims.
- Field extraction. It finds each field the document type defines and returns it under a stable name.
- Normalization. It turns "09/02/26" into a date and "$1,250.00" into an amount, so every consumer does not reinvent the parsing.
- Scoring and locating. It says how sure it is of each field and where on the page the field sits.
The last step is the one that separates a useful healthcare OCR API from a demo. A wrong number in a patient's account costs more than a slow one, so the caller needs to know which fields to trust and which to send to a person. What that score means is explained in what an OCR confidence score measures, and the object that holds it is shaped in JSON schema for medical documents.
Readers choosing a tool without writing code will find the buying questions in how to choose a medical OCR vendor. This post stays with what the endpoint itself accepts and returns.
Request and response shape of a healthcare document AI API
A healthcare document AI API usually works as a job: you upload a file, receive a job ID, and collect the result when processing finishes. Synchronous calls suit a single-page form. A 40-page records packet or a multi-claim EOB can take longer than an HTTP request should stay open.
The request should accept the file and a small set of hints. Useful hints are the expected document type when you know it, a callback URL for completion, and your own reference so you can match the result to the right inbox item. The API should not require the type, because mixed fax batches are common.
The request below is an example only. It posts to https://api.example.com, a placeholder address, not a real service, and the file and patient are fictional. Schema Care offers no API, SDK, webhooks, FHIR output, 835 output or 837 output, so none of these endpoints are Schema Care's.
POST https://api.example.com/v1/documents
Content-Type: multipart/form-data; boundary=example
--example
Content-Disposition: form-data; name="file"; filename="example-intake-packet.pdf"
Content-Type: application/pdf
(binary PDF bytes)
--example
Content-Disposition: form-data; name="client_reference"
inbox-item-EX-77120
--example
Content-Disposition: form-data; name="callback_url"
https://api.example.com/hooks/extraction-done
--example--
A fictional example response to that request returns at once with a job, not with fields:
{
"job_id": "job_example_5531",
"status": "queued",
"client_reference": "inbox-item-EX-77120",
"pages_received": 3
}
When the job completes, an example result groups output by detected document. Every name and value below is fictional, including the patient.
{
"job_id": "job_example_5531",
"status": "completed",
"documents": [
{
"document_type": "patient_intake_form",
"type_confidence": 0.97,
"pages": [1, 2],
"fields": {
"patient_last_name": { "value": "Okonkwo-Lind", "confidence": 0.95, "source": { "page": 1, "bbox": [0.12, 0.2, 0.41, 0.23] } },
"date_of_birth": { "value": "1984-03-11", "confidence": 0.72, "source": { "page": 1, "bbox": [0.55, 0.2, 0.7, 0.23] } },
"insurance_member_id": { "value": "EXM-448-0192", "confidence": 0.91, "source": { "page": 2, "bbox": [0.12, 0.31, 0.38, 0.34] } }
},
"needs_review": ["date_of_birth"]
},
{
"document_type": "unknown",
"type_confidence": 0.41,
"pages": [3],
"fields": {},
"needs_review": ["document_type"]
}
]
}
Three details in that example matter more than the field names. The packet came back as two documents, not one, because page 3 did not belong to the intake form. The low-confidence birth date is listed in needs_review instead of being silently accepted. The unclassified page is returned as unknown with a low score rather than forced into a type. Job states, retries and callback delivery are covered in job states in async document processing APIs.
Which document types should a medical extraction API cover?
A medical extraction API should cover the documents your team keys by hand today, and it should name the fields it returns for each one. Billing teams mostly need EOBs, CMS-1500 and UB-04 claims and billing statements. Clinical teams mostly need lab reports, prescriptions, discharge summaries, intake forms and outside medical records.
Breadth matters less than depth on the types you have. An API that claims twenty document types but returns only a patient name and a date for most of them saves little work. Ask for the field list per type and compare it with the fields your staff actually type.
For billing paperwork, the details that separate APIs are at the line level. An EOB has to come back as claims with service lines, each with billed, allowed, adjusted, patient and paid amounts and the adjustment codes that explain them. Claims need diagnosis codes, procedure codes and the pointers between them. What an EOB endpoint should return line by line is laid out in the EOB API post.
For lab paperwork, the hard parts are units, reference ranges, flags and panels. A result without its unit is unsafe to file, and a reference range printed as text has to survive as text. What a lab endpoint should return per test, including amended results, is covered in the lab report API post.
Handwriting and poor scans cut across every type. Ask whether the API reads handwritten intake answers and how its confidence behaves on a faxed page, then test it on your own worst examples.
Schema Care reads EOBs, claims, lab reports, prescriptions, discharge summaries, billing statements, intake forms and medical records into fields, each with a confidence score and a link to its spot on the page, and it holds back anything under your threshold for a person to check. It offers no API or SDK, so it is not a candidate for this checklist; the field list for each document type is on the Schema Care document types section.
Evaluating a medical document extraction API: a checklist
Evaluating a medical document extraction API comes down to running your own documents through it and checking each claim against evidence. A vendor's own sample set tells you how the API does on that set. The checklist below names what to test in a trial and what proof to ask for, and it applies to any vendor.
| Item | Why it matters | What to test in a trial | Evidence to ask for |
|---|---|---|---|
| Input formats | Paperwork arrives as fax TIFFs, phone photos, scanned PDFs and portal PDFs | Send one of each, including a skewed fax and a multi-page TIFF | A list of accepted file types, page limits and size limits |
| Field coverage | Unlisted fields still have to be keyed by hand | Compare returned fields with the fields your staff type for each document type | A field list per document type, with types and formats |
| Per-field confidence | One score per document hides the single bad field | Check that a smudged member ID scores lower than a clean one on the same page | Documentation of what the score means and how it behaves |
| Source coordinates | Reviewers need to see where each value came from | Draw the returned boxes on the page and confirm they land on the value | The coordinate system, units and page numbering |
| Async support | Long documents outlast a single HTTP request | Submit a 50-page packet and a batch of 200 single pages | Job states, callback retries and rate limits |
| BAA availability | Real patient documents should not be sent without one | Ask for the BAA before any real document leaves your system | The BAA itself and the list of subprocessors |
| Audit logs | You need to know who saw or changed a field and when | Make a correction and look for it in the log | A sample log entry and how long logs are kept |
| Data retention | Source files should not live longer than you need | Delete a document and confirm it is gone from results and storage | The written retention policy and the deletion method |
Run the trial on de-identified or fictional documents first. Score the API field by field, not page by page, and count how many fields would have gone to a person at your chosen threshold. The number of fields that pass with high confidence and are still wrong matters more than any average.
Vendor accuracy figures need the same scrutiny. The questions that expose a weak number are in how to read vendor accuracy claims. The security side, including what a BAA vendor should answer and which answers need evidence attached, belongs to the healthcare vendor security questionnaire guide and to choosing a BAA OCR vendor.
Two items rarely appear on vendor checklists and often decide the outcome. The first is how the API handles a document type it does not know: a good one says "unknown" with a low score. The second is whether a corrected value can be sent back, so the record of what a person changed lives next to the field and not in a separate spreadsheet.
When not to call a healthcare OCR API directly from the browser
A healthcare OCR API should almost never be called directly from a user's browser. The call needs a secret API key, and anything shipped to a browser can be read by whoever opens the page. Run extraction calls from your own server, which holds the key and decides what each user may send.
The key is only the first reason. A server-side call lets you check the file before it leaves your system: its size, its type, and whether the user is allowed to upload documents for that patient. It also lets you record who submitted what, which a browser call cannot do reliably.
The result is the second reason. An extraction response is full of protected health information. If the browser receives it straight from the vendor, your system has no copy, no log of who viewed it and no chance to strip fields the user should not see. Route the response through your server, store it, and send the browser only what that user needs.
Callbacks are the third reason. A completion webhook must land on a server address that can verify the sender. A browser tab cannot receive one, and polling from many tabs multiplies requests against your rate limit.
There are narrow exceptions. An internal tool on a locked-down network, using short-lived upload URLs that your server issues for one file at a time, can send the file bytes directly to storage. Even then, the extraction call and its result should still pass through your server.
A practical layout puts three pieces in a row: the browser uploads to your server, your server calls the extraction API and stores the job ID, and a webhook handler on your server collects the result and writes it to your database. Reviewers then see results inside your own application, where you control access and keep the audit trail.