Extract Data from Documents
Use an extraction workflow when a document should return structured JSON. This guide creates a workflow from YAML, assigns it to a bucket, ingests a document, and reads the result with the GroundX Python SDK.
GroundX validates the YAML and creates the workflow settings. Send the YAML directly through the SDK instead of preparing workflow settings in your application.
1. Start With The JSON You Want
This guide creates the following output:
Group names and workflow_output_key values become names in the returned JSON.
2. Write The Workflow YAML
An extraction_policy_version: v1 workflow uses these settings:
workflow.custom_stepsnames the extraction passes.levelselects the document unit each pass processes:chunk,section, ordocument.kind: instructis for non-repeating fields,keysfor repeating rows such as charges, andsummaryfor repeating records such as meters. A document-level step cannot useinstruct.workflow.agent_chainassigns each group a built-in processing sequence. Use the sequence whose task names match the group’s role. Thereconcile,qa, andsavetasks combine candidate values, check them, and write the result.roleselects processing behavior, not the group’s output name or subject. Usestatementfor non-repeating values,metersfor repeating parent records, andchargesfor related child records.workflow_stepconnects a group to a named custom step.workflow_output_keynames a field in the returned JSON.
Declare a role and workflow_step for every routed group, and a
workflow_output_key for every routed field. GroundX does not infer a role from
a group name or data shape.
Each field prompt has four required settings:
Each chunk-level custom step runs once per chunk. For long documents, estimate
the request count before ingest. Use workflow.section_strategy: page with
level: section for broad statement passes when the estimate approaches 2,000
requests.
3. Create And Assign The Workflow
Install the extraction helpers:
Create the workflow from the YAML file, then assign it to a bucket:
Pass exactly one of path or yaml_text. The SDK sends the file contents
directly to GroundX. Use
client.workflows.add_to_account(...) when the workflow should be the account
default.
Update a workflow by sending the full YAML again:
Load the stored workflow definition when you need to inspect it:
4. Ingest A Document
Upload the document to the assigned bucket with full processing:
5. Read The Extracted JSON
Read the completed document from the final status response and call
get_extract:
documents.get_extract() returns the extracted JSON. X-Ray document
data is separate diagnostic
data; do not build application output from it.
6. Improve Accuracy
Compare the returned JSON with reviewed expected values, then change the
smallest prompt that explains each miss. Add the document’s exact labels to
identifiers, state formatting rules in instructions, and tell repeating
groups what to include or exclude. Change prompts without changing group names,
roles, or relationships.
Advanced: Repeating And Related Records
Use repeats: true for object arrays. unique_attrs names fields used to
identify the same record.
By default, all unique_attrs fields must match for two repeated records to be
treated as the same record. Optional identity_match settings refine that
comparison. They are separate from match_attrs, which links a child record to
a parent record.
GroundX Python 4.0.0 and later use one string comparison for record identity
and parent relationships. It ignores capitalization and every whitespace
character. It treats only 0 and o, 1, i, and l, and 8 and b as
equivalent. Punctuation, other characters, and remaining length still matter.
Matching never changes extracted, conflict, diagnostic, or returned values.
Every field referenced by identity_match must exist in the same group.
group_attrs and sort_attrs must also appear in unique_attrs. Each
equal_value_shortcuts key must appear in threshold_attrs.
Persisted workflows may contain identity_match.exact_attrs. GroundX Python
4.0.0 and later still read it, but it no longer changes string matching. Do not
add it to new workflows.
For example, place both settings inside a repeating group whose fields include
meter_number, service_address, and meter_type:
Here, meter_number uses universal string matching. Once both threshold fields
have values, at least one of them must also match.
On a child group, match_attrs lists every value used to find its parent.
passthrough.from names the parent group. Every match field must use the same
output name in both groups. GroundX:
- compares the extracted values, not their surrounding metadata;
- uses the same capitalization, whitespace, and OCR-confusable string comparison as repeated-record identity;
- compares integers and floats numerically;
- ignores blank or missing fields;
- requires both records to provide the same match fields;
- uses the first matching parent when more than one matches.
Matched children appear inside their parent. Unmatched children remain in the
top-level child group. unique_attrs does not add relationship fields.
For example, one matched child and one unmatched child produce:

