Extract structured biomarker data from PDF and image lab reports using the Lab Report Parsing API with automatic LOINC code matching.
Junction’s Lab Report Parsing API converts lab report files into structured JSON. You can upload PDF, JPEG, and PNG reports from external laboratories, patient-uploaded records, or historical chart archives, then retrieve extracted metadata, results, reference ranges, interpretations, and LOINC matches.Lab Report Parsing is separate from Junction’s ordered lab test workflow. It does not place an order, collect a sample, or request a result from a lab. It reads an existing report document and returns the data Junction can extract from that document.
This feature is in closed beta.Interested in this feature? Get in touch with your Customer Success Manager.
Create a parsing job with the Create Lab Report Parser Job endpoint. The request is multipart/form-data and requires:
Field
Required
Description
file
Yes
One lab report file, or multiple image files for one report.
user_id
Yes
Junction user ID to associate with the parsed report.
needs_human_review
No
Set to true to request manual review where enabled for your team. Defaults to false.
Supported file formats and upload limits:
Upload
Supported formats
Limit
Single file
PDF, JPEG, or PNG
10 MB
Multiple files
JPEG and PNG only
Up to 8 files, 10 MB per file, 20 MiB combined
PDF pages
PDF upload
Up to 20 pages
When you upload multiple image files, Junction merges them into a single PDF before sending the report to the parser. Multi-file uploads cannot include PDFs. Junction validates both the declared Content-Type and the file’s magic bytes, so spoofed or corrupted files are rejected before parsing starts.
The status field describes the state of the parsing job.
Status
Description
upload_pending
Job was created and the file upload is being finalized. This is the status returned by the create endpoint.
started
The file was uploaded and parsing is in progress.
completed
Parsing completed and results are available in data.
failed
Parsing failed. Check failure_reason for more information.
For parser jobs, failure_reason commonly includes:
Failure reason
Meaning
invalid_input
The parser determined that the document is not a lab report containing medical test results.
not_english
The report language is not supported.
processing_error
Junction could not process the report because of an internal parser or provider failure.
Parser status and failure reason enums are non-exhaustive. Store unknown values safely and avoid hard-failing if Junction adds a new value or returns failure_reason: null.
Some invalid uploads are rejected synchronously by the create endpoint instead of becoming failed parser jobs. These errors return an HTTP error response and do not produce a completed async parsing result.
Set needs_human_review to true to mark the job as requiring manual review where enabled for your team. Human review is useful for high-impact workflows, low-quality scans, complex multi-page reports, or reports where your application needs a higher-confidence extraction path.Human review is not enabled for every team by default. Contact your account manager before depending on it in production.If your team is not enabled for human review, creating a job with needs_human_review=true returns a 400 response:
Error
{ "detail": "Human review is not supported yet for your team please contact support"}
The response includes two review fields:
Field
Meaning
needs_human_review
Whether the job was submitted with a manual-review request.
is_reviewed
Whether manual review has been completed, where a manual-review workflow is enabled.
metadata is extracted from the document header and surrounding report content when present.
Field
Description
patient_first_name
Patient first name from the report.
patient_last_name
Patient last name from the report.
dob
Patient date of birth as printed or normalized from the report.
gender
Extracted patient gender normalized to male, female, or other.
lab_name
Name of the lab or reporting organization.
date_reported
Date the report was issued.
date_collected
Date the specimen was collected.
specimen_number
Lab specimen, accession, or sample identifier.
Not every report contains every metadata field. Treat patient names, date of birth, lab name, report dates, and specimen number as nullable. Treat unknown or unsupported gender values as other.
data.results[].value is always returned as a string. Do not assume it can always be parsed as a number.For type: "numeric", value should be a number encoded as a string, such as "5" or "5.0". For other result types, value can contain comparators, text, boolean-like values, durations, percentages, or ratios. Use type before deciding how to parse or display the value.
Type
Example value
Notes
numeric
"90", "1e-3"
Numeric result encoded as a string. Use units for measurement units.
range
"<5", ">=10", "≤1e-3", "3-7"
May include comparators, approximate values, scientific notation, or lower-to-upper range notation. Do not parse as a plain float.
Boolean or presence-style findings can vary by report wording.
duration
"3h", "12 min", "10:00"
Duration-like values are preserved as strings because reports can use different formats.
percentage
"5.4%"
Inferred when the value includes %. If the value is "5.4" and units is %, the result may be returned as numeric; read value, type, and units together.
ratio
"97/100"
Slash-form ratios are inferred when type is not already supplied. Other ratio-like formats, such as colon-form titers, may be returned as comment.
The parser output is optimized to preserve what was reported. Store the raw value string and derive typed values in your application only after checking type, units, and reference range fields.
The parser-specific type values are related to, but not identical to, the order result ResultType values documented in Result Formats. Parser results currently include numeric, range, comment, boolean, duration, percentage, and ratio.When type is not supplied by extraction, Junction infers it from value. For example, "<50", "≥2000", and "10-20" are inferred as range; "20%" is inferred as percentage; "97/100" is inferred as ratio; and unrecognized text is inferred as comment.
The parser may extract min_reference_range and max_reference_range as numeric bounds when the report includes a parseable reference range. It may also return:
interpretation: possible values are normal, abnormal, critical, or unknown.
is_above_max_range: whether the result is above the extracted maximum
is_below_min_range: whether the result is below the extracted minimum
These fields depend on the quality and structure of the source report. Some reports include clear numeric bounds; others include textual ranges, age-specific ranges, sex-specific ranges, comments, or formatting that cannot be normalized into numeric bounds.For numeric values, Junction can infer whether the result is above or below the extracted numeric reference bounds. For comparator range values, Junction only sets range flags when the comparator is conclusive. For example, ">2000" with a max reference range of 1100 is above range, but ">500" with the same max is inconclusive.If a value is conclusively outside the extracted bounds, interpretation is abnormal. Numeric values without an out-of-range flag are interpreted as normal. Non-numeric and inconclusive range values are interpreted as unknown unless the parser extracted a more specific interpretation.If you need custom boundary logic, read the result value, type, units, and reference range fields together. For general order-result reference range guidance, see Reference Range.
Junction attempts to match extracted results to LOINC codes so you can compare markers across different labs and report formats.Each loinc_matches[] item includes:
Field
Description
loinc_code
LOINC code, such as 2345-7.
loinc_name
Official or normalized LOINC name.
display_name
Display label for the match.
aliases
Alternate names associated with the match.
confidence_score
Relative score for this LOINC candidate.
confidence_score is a matching score for the candidate LOINC code. It is not an accuracy score for the extracted lab result, patient metadata, units, reference ranges, or interpretation. A high score means Junction’s LOINC matcher found a stronger candidate for that result row than lower-scored candidates; it does not prove that the source document was parsed correctly.In most integrations, use loinc_match_status for workflow decisions instead of building your own thresholds on confidence_score. Store the score for debugging, audit, or support workflows, but avoid using it as a clinical-confidence or result-accuracy signal.Use loinc_match_status to decide how much review your workflow needs:
Status
Meaning
auto_match
Junction found a likely LOINC match.
needs_review
Junction found possible matches, but review is recommended.
no_match
Junction could not identify a match.
LOINC matches are not guaranteed for every extracted result. Your integration should handle loinc_matches: null, an empty match list, low confidence scores, needs_review, no_match, and future match statuses.
Sandbox lab report parsing has a team-level report limit. The error response includes the configured limit for your team. For example, a team limited to 150 reports receives:
Error
{ "detail": "Sandbox lab report parsing is limited to 150 reports. Please upgrade your contract to continue."}
This is a sandbox usage limit, not a file-level validation error. Retrying the same request, creating more users, or changing the report file does not reset the limit. Contact your account manager or support@junction.com if you need the limit increased for higher-volume testing or production access.