Skip to main content

Export to JSON

A JSON export profile turns a finished transaction into a single structured document: the extracted fields with their confidence and review state, per-field bounding boxes, a per-page block that carries everything needed to place coordinates back onto the original page, and the transaction's metadata. It is the recommended way to feed results into another system, including a custom review (human-in-the-loop) client.

To produce it, add an Export activity to your workflow with a JSON profile, then retrieve the output (see Accessing OCR & Field Data for the API calls).

Schema versions​

A JSON profile has a Schema Version, which selects the arrangement of the file.

  • Version 2 (recommended) groups the export into transaction, pages and states. Pages are written once for the whole transaction instead of being repeated inside every document, and every business rule issue is reported in a single list. New profiles are created at version 2. See Export Schema Version 2.
  • Version 1 (legacy) is the older flat structure documented on this page. Existing profiles keep it and are not changed.

Every option below means the same thing in both versions. The rest of this page describes version 1; the coordinate contract and field filtering apply equally to both.

Options​

Configured on the JSON profile (see the Export activity for the full table):

  • Schema Version (default version 2 for new profiles): the arrangement of the file, as above.
  • Field Filter (default all fields): export all fields, or only an included set, or everything except an excluded set. Fields are named by their display path with / for nesting: Supplier/Name for a group child, Line Items/Description for a repeating-group column. See Filtering fields.
  • Include Field Details (default on): keeps confidence, reasoning, confirmation state, and bounding boxes alongside each value. Turn off to keep just the value, the simplest way to shrink the file.
  • Include Reasoning (default on): the model's written explanations for the classification, the split, and each extracted value. This is often the largest text in the file, so turning it off shrinks the export substantially without losing any data values.
  • Include Source Files (default on): one entry per uploaded file with its name, order, split policy, size, type, upload time, and which pages came from it.
  • Include Processing Steps (default off, version 2 only): the workflow timeline, with each step's status and duration.
  • Include Page Full Text (default off): each page's OCR text.
  • Include Page OCR Data (default off): word-level OCR layout.
  • Image orientation (Corrected for new profiles; profiles created before the option existed stay on Original): the page frame every coordinate is expressed in. See The coordinate contract.
  • Pretty Print (default on): indented, readable JSON. Turn off for a compact, single-line file.
  • Exclude JSON Paths (advanced): strip specific branches from the finished file by path. See Reducing file size.

The per-page block and the transaction metadata are always included and have no toggle.

The coordinate contract​

Every bounding box in the export, both field boxes and OCR word boxes, is expressed in the rasterized page-image pixel space with a top-left origin. You can export that page image as a JPG profile alongside the JSON, and a box drops directly onto it with no conversion, provided both profiles use the same Image orientation.

A page is stored exactly as it was scanned. When the OCR engine finds that a page is sideways (or a reviewer rotates it), the platform records the clockwise rotation needed to view it upright rather than rewriting the image. Image orientation decides which frame the export uses:

  • Corrected (the default for new profiles): the export describes the upright page. Every bounding box and the page dimensions are on the page after rotation, image_transform.rotation reports what was applied, and image_transform.orientation is corrected. A JPG profile on the same setting emits the same upright page.
  • Original: the export describes the page as stored. Bounding boxes and page dimensions are on the un-rotated page and image_transform.rotation tells you what you still have to apply. Profiles created before this option existed keep this behaviour, so an existing integration sees no change.

Pages that needed no rotation are identical under both settings.

To place a coordinate onto the original page instead (for example the source PDF), use the page's image_transform block:

original_coordinate = rasterized_coordinate / render_scale

Output structure​

{
"transaction_id": "…",
"tenant_id": "…",
"project_id": "…",
"transaction": {
"exported_at": "…",
"status": "…",
"created_at": "…",
"source_file_names": ["invoice.pdf"],
"metadata": { "customer_ref": "ACME-42", "cost_center": "EU-1" }
},
"documents": [
{
"document_id": "…",
"document_type": "invoice",
"classification_confidence": 0.97,
"fields": {
"invoice_number": {
"value": "INV-1001",
"confidence": 0.99,
"reasoning": "Found under INVOICE NO. label",
"is_confirmed": true,
"bounding_boxes": [
{ "coordinates": [10, 10, 100, 30], "page_index": 1 }
]
}
},
"pages": [
{
"page_number": 1,
"transaction_page_number": 1,
"source_filename": "invoice.pdf",
"source_file_page_number": 1,
"image_transform": {
"rasterized_width": 2480,
"rasterized_height": 3508,
"source_width": 595.32,
"source_height": 841.92,
"source_unit": "point",
"render_scale": 4.166,
"effective_dpi": 300.0,
"coordinate_system": "top-left-origin",
"rotation": 0
}
}
]
}
]
}

Fields​

Each field carries its value and, when Include Field Details is on, confidence, reasoning, is_confirmed, original_text, and a bounding_boxes list of where the value was found. Groups and repeating groups nest the same shape under value.

  • original_text: the text on the page the value came from, before normalization: "03/04/26" for a date exported as "2026-04-03". Documents processed before it was kept on every field carry it only where the model reformatted the value; read value when it is absent.

  • bounding_boxes[].coordinates: [x1, y1, x2, y2] in rasterized pixels (top-left, bottom-right).

  • bounding_boxes[].page_index: the 1-based page number the box belongs to, matching page_number in the pages array.

Pages​

Each page records how it maps to its source file and, in image_transform, the frame for mapping coordinates:

FieldMeaning
rasterized_width / rasterized_heightPixel size of the OCR'd image. This is the coordinate space of every bounding box.
source_width / source_heightOriginal page size. For PDF sources this is in points (1/72 inch); for image sources it is the source image's pixels.
source_unitpoint (PDF source) or pixel (image source).
render_scaleRasterized pixels per source unit, the same on both axes. Divide a coordinate by this to reach the source page.
effective_dpirender_scale x 72 for PDF sources, or null for image sources. This is the true scale, and is more reliable than any nominal DPI because pages are normalized during rasterization.
coordinate_systemAlways top-left-origin.
rotationRotation in degrees clockwise recorded for the page by OCR orientation detection or a reviewer. With Image orientation set to Original, the coordinates are on the un-rotated page and you apply this yourself to render the upright view; with Corrected, it reports the rotation already applied to the exported frame.
orientationPresent, with the value corrected, only when the profile's Image orientation is Corrected and the page was rotated. Absent otherwise.

Page OCR (optional)​

With Include Page Full Text, each page gains a full_text string. With Include Page OCR Data, each page gains an ocr block:

"ocr": {
"language": "en",
"detected_language": "en",
"words": [
{ "text": "INV-1001", "bounding_box": [10, 10, 100, 30], "confidence": 0.99 }
]
}

OCR word boxes use the key bounding_box and, like field boxes, are in rasterized pixel coordinates.

Transaction​

The transaction block is always present. Alongside exported_at and status, it carries the transaction's own record: created_at, source_file_names, a timing summary, and a metadata object. The metadata object holds the key-value pairs supplied when the transaction was created (through the upload form or the API), so any reference your system attached, such as an order number or a customer id, comes back with the results. Platform-internal keys are filtered out.

Filtering fields​

By default every extracted field is exported. The Field Filter narrows that set:

  • Include only exports just the listed fields and drops the rest.
  • Exclude exports everything except the listed fields.

Fields are named by their display path, using / for nested fields. This is the same filter used by every format (JSON, XML, CSV, Excel):

PathSelects
Invoice NumberA top-level field.
Supplier/NameThe Name child inside the Supplier group.
Line Items/DescriptionThe Description column of the Line Items repeating group, in every row.
SupplierThe whole Supplier group and all of its children.

Matching is case-insensitive, and a field's id also matches (so older profiles that listed field ids keep working). Naming a parent includes or excludes its entire subtree. Naming only children keeps the parent as a container holding just those children.

Reducing file size​

Large exports are usually dominated by per-field metadata and OCR layout. In order of impact:

  1. Turn off Include Reasoning removes the model's written explanations, which are usually the largest text in the file, and costs you no data values.

  2. Turn off Include Field Details removes confidence, reasoning, confirmation state, and bounding boxes from every field, leaving just values.

  3. Field Filter drops fields you do not need at all.

  4. Turn off Include Page OCR Data and Include Page Full Text if you do not use the word-level layout or page text.

  5. Exclude JSON Paths removes specific branches from the finished file by path, one per line, with * as a wildcard. It runs last, after every other option, so it can reach anything in the output:

    documents.*.fields.*.reasoning
    documents.*.pages.*.ocr
    transaction.timing

    A path that matches nothing is ignored, so it is safe to keep a standard list across profiles.

Next steps​