Extracting data from criminal background checks
Consumer reporting agencies compile criminal background checks from county and statewide court searches, and each agency prints its own report layout. Employers and property managers review one for every finalist candidate or rental applicant, often thousands a year. Reports arrive as PDF downloads from the agency's portal or as email attachments.
Adjudication needs the jurisdiction searched, each case number, the charge, its offense level and its disposition. An applicant tracking system matches those records against the employer's adjudication criteria, and a disqualifying record starts the adverse action notices the Fair Credit Reporting Act requires.

What makes criminal background checks hard
Records nest four levels deep
A search holds case files, a case holds charges, and each charge carries its own sentencing block, such as jail time or restitution.
Every agency designs its own report
Each consumer reporting agency sets its own layout, so one agency prints a disposition in a charge table and another in a label grid.
Each court uses its own terms
Dispositions follow the wording of the court that recorded them, from guilty and convicted to deferred adjudication and nolle prosequi.
Parse, extract, verify
Parse
Parse turns the document into reading-order Markdown and a hierarchy of blocks (text, tables, figures), and grounds each block to its exact location on the page.
Extract
You define the fields in a JSON schema, and Extract returns their values in a consistent, structured format, each linked back to where it appears in the Markdown.
Verify
Each value links back to where it appears, down to the character range in the Markdown, and the page and bounding box in the source document, so every result can be verified.
One criminal background check, end to end
About this document: A sample employment screening report published by Accurate Background, a consumer reporting agency. Three portrait pages: candidate information and disclosures, a summary of eleven searches, and a county criminal search with one case file. Page 3 is featured. The subject's name and address were replaced with stand-ins, and the later sections of the report were removed.
Processing objective: The objective is to read one criminal record from search to sentence. It shows where the search ran, which case it found, the first charge and how the court resolved it, down to the restitution ordered. Each value grounds to the line or cell that prints it.
Demonstration fields: Jurisdiction searched, Case number, Charge, Disposition, Restitution ordered
The document
3 of 3 pages
Page 1
Page 2
Page 3shown below
Where each value came from

criminal_searches[0].jurisdiction
{
"value": "CA / PLACER",
"page": 3,
"range": {
"end": 3851,
"start": 3825
},
"box": {
"xmin": 0.03714,
"ymin": 0.14854,
"xmax": 0.4323,
"ymax": 0.16639
}
}criminal_searches[0].cases[0].case_number
{
"value": "GH56327",
"page": 3,
"range": {
"end": 4006,
"start": 3999
},
"box": {
"xmin": 0.33628,
"ymin": 0.31827,
"xmax": 0.50831,
"ymax": 0.34423
}
}criminal_searches[0].cases[0].charges[0].description
{
"value": "ASSAULT WITH A DEADLY WEAPON",
"page": 3,
"range": {
"end": 4362,
"start": 4334
},
"box": {
"xmin": 0.41255,
"ymin": 0.45219,
"xmax": 0.7405,
"ymax": 0.47745
}
}criminal_searches[0].cases[0].charges[0].disposition
{
"value": "GUILTY",
"page": 3,
"range": {
"end": 4392,
"start": 4386
},
"box": {
"xmin": 0.82499,
"ymin": 0.45219,
"xmax": 0.95427,
"ymax": 0.47737
}
}criminal_searches[0].cases[0].charges[0].sentence.restitution
{
"value": "$100,000.00",
"page": 3,
"range": {
"end": 4778,
"start": 4767
},
"box": {
"xmin": 0.77525,
"ymin": 0.61845,
"xmax": 0.95081,
"ymax": 0.64714
}
}How to try it yourself
Everything on this page is reproducible. The sample, its schema, and the Parse and Extract API outputs are published. You can repeat the same two calls from whichever surface you already build on.
- Claude Skilldescribe the job; the agent writes it
- CLIno code at all
- MCPexpose ADE docs as an agent tool
- REST APIany language
- Pythonlandingai-ade
- TypeScriptlandingai-ade
Documents into data
Accurate
The best accuracy on the difficult documents other tools get wrong, such as messy scans, complicated tables, checkboxes and handwriting.
Auditable
Every answer cites its sources. Values come back with an audit trail (page, bounding box, character range) so a human can review them.
Agentic
Applies multi-step reasoning, and plans before it acts. Handles documents it has never seen before and adapts to variations.
API-first
Composable APIs that drop into any tech stack and can be called from anywhere. Easy to build on and embed in your pipelines and products.
Affordable
Cost-competitive rates with complete price transparency. Spend controls before you run, and every job reports its exact cost.
Enterprise-grade
Built for production and scale from day one. Fully observable and monitored, running securely in our cloud or yours.
Built for high-volume, high-throughput production
- Zero data retention
- Priority rate limits
- Enhanced support
- VPC and on-prem deployment
Available on Team and Enterprise plans. VPC and on-prem deployment require an Enterprise plan.
