ranges for each place. The script returns one location per range, so each place gets its own box.
The tutorial uses the ade-python library and ade-typescript library to:
- Parse this PDF: Pay Stub
- Extract these fields: Employee Name and Gross Pay
- Ground both fields with the Ground API
- Save a PNG of each place a field appears, a copy of each page with every location drawn and labeled, and a JSON file with each location’s page number and bounding box
These examples require the Python or TypeScript client library. Before running a script, set your API key and install the library and any required dependencies.
The Python script works with PDF and image files. The TypeScript script is written for PDF files. To export crops from other file types, use it as a reference and adapt the image export logic.
1. Download the Document to Process
Download the Pay Stub and save it to a local directory.2. Create the Script
Copy the script for your language and save it asgrounding.py or grounding.mts in the same directory as the PDF. The TypeScript script needs the .mts extension to run as an ES module, because the mupdf package it uses to render pages is an ES module.
3. Run the Script
Run the script from the same directory:4. View Output
The script saves the following files to theoutput folder:
Field Locations
Each entry inpay-stub_grounding_output.json is keyed by the field’s path in your schema (a nested field reads issuer.name, an array item items[0].price) and has these fields:
On the pay stub, the employee name appears twice and the gross pay once, in a table cell. A run on the pay stub saved this file. Your boxes and block IDs can differ slightly, because they come from your own parse:
pay-stub_grounding_output.json
How the Script Finds Each Location
The Ground response’sgrounding field has the same shape as extraction_metadata. The script walks both together, so each extracted value is paired with its grounding, and handles the three values a field’s grounding can take:
A value has one range for each place it was quoted from (see Grounding with Ranges), and Ground returns the blocks for all of a field’s ranges in one list (see Matching Blocks). For each range, the script:
- Keeps the blocks this range overlaps. Every returned block and every
atomic_groundingentry carries its ownrangein the Markdown. The script keeps the blocks whosegrounding.rangeoverlaps the field’s range, the same overlap Ground uses: thestartis inclusive and theendis exclusive. - Keeps the cell, not the table. A value inside a table matches both the
tableblock and thetable_cellthat contains it. The cell names the table inparent_id, so the script drops the table. - Uses the matching lines or words. Each returned block carries the
atomic_groundingentries the field’s ranges overlap: lines with DPT-3 Pro, words with DPT-3 Verity. The script keeps the entries this range overlaps, because their boxes are tighter than the block’s. When a block has no matching entries (a table cell parsed with DPT-3 Pro), the script uses the block’s own box. See Matches Inside a Block. - Merges the boxes on the range’s first page. The script combines the remaining boxes on the first page the range appears on into one box, and crops that region from the page rendered at 150 DPI. Page numbers are 1-indexed, so the script subtracts 1 when it opens a PDF page.
- Numbers and labels the location. Locations are numbered in the order of the field’s
ranges, starting at 1. The script saves the crop as<field>_<number>.pngand draws the box on a copy of the page with the label<field> #<number>, table cells included.
Next Steps
Now that you have a working script, you can:- Replace
pay-stub.pdfwith another PDF you want to parse, extract from, and ground. The Python script also accepts image files. - Modify the
schemato extract different fields. For guidance, see Extraction Schema (JSON). - Draw every block the Parse API found, not only the ones a field was quoted from. See Visualize Parsed Blocks.
- Read every field of the Ground response. See Ground Extracted Fields.