Document Data (Flat)
Retrieve a document's extracted data in a flat, slug-keyed structure
/api/v1/deployments/{deploymentId}/documents/{fileId}/dataReturns a document's extracted data in the flattest available structure: tables keyed by table slug, rows keyed by column slug, child tables nested inline. No column types, descriptions, or metadata objects — this is the recommended endpoint for consuming extraction results. For the full metadata-rich shape, use Get File Data. To fetch several documents in one call, use Documents Data (Flat, Bulk).
Parameters
| Name | Type | In | Required | Description |
|---|---|---|---|---|
deploymentId | string | path | Yes | The model or deployment the document belongs to. |
fileId | string | path | Yes | The file ID from the upload response or webhook event payload. |
include | string | query | No | Comma-separated list of optional enrichments: confidence, boundingBoxes, grounding, validations, metadata. |
Shape rules
- Every key that is not
$-prefixed is your data, keyed by slug. Everything$-prefixed is system-provided. - Tables are always arrays of rows — a single-row table is a one-element array.
- Every row carries
$id(the row id, stable for corrections and cross-references) and$index(its position). - Every cell is always an object with a
valuekey, sorow["total_amount"].valueworks regardless of what you include. Enrichments only ever add keys next tovalue:include=confidence→confidence: the overall score (0–1,nullwhen not computed).include=boundingBoxes→boundingBoxes: array of{"page": "2", "bbox": [yMin, xMin, yMax, xMax]}in normalized 0–1000 coordinates, ornullwhen never computed.include=grounding→grounding: where the value was found in the document's text, as{status, part, partName, span, valueSpan, text, source}, ornullwhen nothing was recorded for the cell.include=validations→validations: one entry per check that touched the cell, plus a top-levelvalidationsobject carrying the document's status, every rule result and every custom check. See Validations.
- Child tables appear inside their parent row under the child table's slug, as an array of rows with the same rules.
include=metadatais the one enrichment that touches no cell: it adds a top-level_metablock describing the document, besidefileIdandstatus. See Metadata.
Requires slugs on every table and column, unique within their scope. Schemas predating the slug backfill, or schemas where two tables or columns resolve to the same slug, return 422 with a message naming the offending table or column.
Note: documents processed through the synchronous process-file endpoint skip the confidence and bounding-box stages, so those fields stay null for such files even when requested.
Request
const response = await fetch(
`https://app.limai.io/api/v1/deployments/${deploymentId}/documents/${fileId}/data?include=confidence,validations`,
{
headers: { "Authorization": `Bearer ${API_TOKEN}` }
}
)
const data = await response.json()Response
The status reflects the document's latest extraction job. COMPLETED guarantees the flat data is present in the same response (an empty-but-successful extraction still reports COMPLETED). A document whose latest job is still queued reports PROCESSING, and a stalled job reports FAILED with an error message — never a partial COMPLETED.
Every response carries modelId and viaDeploymentId beside fileId and status, whatever the status: the model that served the request, and the deployment it arrived through or null when the model was addressed directly.
Plain call (no include):
{
"fileId": "file_9k2mx4",
"status": "COMPLETED",
"jobId": "job_5tr8n1",
"data": {
"invoices": [
{
"$id": "row_h1",
"$index": "0",
"invoice_number": {
"value": "INV-2041"
},
"total_amount": {
"value": "1250.00"
},
"line_items": [
{
"$id": "row_li1",
"$index": "0",
"description": {
"value": "Solar panel mounting kit"
},
"amount": {
"value": "740.00"
}
}
]
}
]
}
}With include=confidence,validations:
{
"fileId": "file_9k2mx4",
"status": "COMPLETED",
"data": {
"invoices": [
{
"$id": "row_h1",
"$index": "0",
"invoice_number": {
"value": "INV-2041",
"confidence": 0.947,
"validations": [
{
"check": "vrule_2a8",
"source": "RULE",
"passed": true,
"message": null,
"expected": "non-empty value",
"actual": "INV-2041",
"name": "Invoice Number is not empty",
"scope": "FIELD",
"operator": "IS_NOT_EMPTY",
"amended": false,
"previousValue": null,
"amendedValue": null
}
]
},
"total_amount": {
"value": "1250.00",
"confidence": 0.882,
"validations": [
{
"check": "vrule_5f3",
"source": "RULE",
"passed": false,
"message": "Total within approval limit: expected between 0 and 1000, got 1250",
"expected": "between 0 and 1000",
"actual": "1250",
"name": "Total within approval limit",
"scope": "FIELD",
"operator": "IS_BETWEEN",
"amended": false,
"previousValue": null,
"amendedValue": null
},
{
"check": "line-item-reconciliation",
"source": "SCRIPT",
"passed": false,
"message": "Line items sum to 1180.00, total reads 1250.00",
"expected": null,
"actual": null,
"name": null,
"scope": null,
"operator": null,
"amended": false,
"previousValue": null,
"amendedValue": null
}
]
},
"line_items": [
{
"$id": "row_li1",
"$index": "0",
"description": {
"value": "Solar panel mounting kit",
"confidence": 0.931,
"validations": []
},
"amount": {
"value": "1180.00",
"confidence": 0.904,
"validations": []
}
}
]
}
]
},
"validations": {
"status": "failed",
"failCount": 3,
"checks": [
{
"key": "line-item-reconciliation",
"source": "STATIC",
"status": "RESEND_FAILED",
"passed": false,
"message": "Line items sum to 1180.00, total reads 1250.00"
}
],
"rules": [
{
"check": "vrule_2a8",
"name": "Invoice Number is not empty",
"scope": "FIELD",
"operator": "IS_NOT_EMPTY",
"passed": true,
"message": null,
"failures": []
},
{
"check": "vrule_5f3",
"name": "Total within approval limit",
"scope": "FIELD",
"operator": "IS_BETWEEN",
"passed": false,
"message": "Total within approval limit: expected between 0 and 1000, got 1250",
"failures": [
{
"table": "invoices",
"rowId": "row_h1",
"column": "total_amount",
"expected": "between 0 and 1000",
"actual": "1250"
}
]
},
{
"check": "vrule_9k1",
"name": "Line items reconcile",
"scope": "DOCUMENT",
"operator": "EQUALS",
"passed": false,
"message": "Line items reconcile: expected 1250.00, got 1180",
"expected": "1250.00",
"actual": "1180",
"failures": []
}
]
}
}While processing, and on failure:
{
"fileId": "file_9k2mx4",
"status": "PROCESSING",
"jobId": "job_5tr8n1"
}{
"error": "Column \"Invoice Number\" (col_8s3k1) has no slug. Run the slug backfill for this schema."
}Validations
include=validations reports both kinds of check the platform runs — the model's validation rules and its custom validations. Validations explains the difference, how a rule's name and message are built, and what the status values mean.
Per-cell entries
Each cell's validations array has one entry per check that touched that cell. A rule that applies to a column produces one entry per cell of that column.
| Field | Type | Description |
|---|---|---|
check | string | null | The rule's id for RULE entries, the script's key for SCRIPT and AGENT entries |
source | RULE | SCRIPT | AGENT | Which system produced the entry |
passed | boolean | Whether the check held for this cell |
message | string | null | For rules, the composed failure detail, null when the rule passed. For scripts and agents, the finding's own message |
expected / actual | string | null | What the check required and what it saw. Always present for rules; null for custom checks that report neither |
name | string | null | The rule's name or generated label. null for SCRIPT and AGENT entries — their name is on the matching checks[] entry |
scope | string | null | FIELD, COLUMN, CROSS_FIELD, ROW or DOCUMENT for rules; null for custom checks and for rules that no longer exist |
operator | string | null | The rule's operator; null for custom checks |
amended | boolean | true once a RESEND check has corrected this cell's value. Always false for rules |
previousValue / amendedValue | any | null | The value before and after a RESEND correction. null unless amended is true |
Only cross-field, row and document rules produce no cell entries; their results are document-level.
The document-level object
| Field | Type | Description |
|---|---|---|
status | pending | passed | failed | error | null | The document's validation status across rules and custom validations |
failCount | number | null | Failing checks on the document, rules and custom checks together. null before anything has been evaluated |
checks | array | One entry per custom validation: key, source (STATIC or AGENT), status, passed, and a message — the first failing finding, or the error a check that could not run reported |
rules | array | One entry per rule that has a result on this document, pass or fail, every scope |
Each rules[] entry carries check, name, scope, operator, passed and message, plus:
failures— one{table, rowId, column, expected, actual}per failing cell or row, keyed by the same table and column slugs thedataobject uses.columnis omitted for row rules, which fail as a row rather than as a cell. Empty for a passing rule.expectedandactualon the entry itself, for cross-field and document rules, which produce a single result for the whole document.
A rule deleted since its results were written is still listed, with scope and operator set to null and a name derived from the stored result.
rules is empty when the model has no validation rules, when the document was extracted before its model had any, and when rule evaluation failed — in that last case status is error.
Metadata
include=metadata adds a reserved _meta key to the response envelope, beside fileId, status and data. It describes the document itself, not its cells, so the flat data under data is unchanged.
{
"fileId": "file_9k2mx4",
"status": "COMPLETED",
"jobId": "job_5tr8n1",
"data": {
"invoices": [
{
"$id": "row_h1",
"$index": "0",
"invoice_number": {
"value": "INV-2041"
}
}
]
},
"_meta": {
"documentId": "cmm3k7r2v0007",
"fileName": "broker-quote-2026-09.pdf",
"submittedAt": "2026-09-01T10:12:33.000Z",
"submittedBy": {
"id": "usr_8a2f",
"name": "Jane Doe",
"email": "jane@acme.com"
},
"extractedAt": "2026-09-01T10:14:02.000Z"
}
}Fields of _meta:
| Field | Description |
|---|---|
documentId | The file's ID. |
fileName | The uploaded file name. |
submittedAt | When the file was uploaded, shown as "Date Added" in the grid. |
submittedBy | The user who uploaded the document, as { id, name, email }. null when the uploader is unknown. |
extractedAt | When the latest extraction run completed. null when no run has completed. |
_meta is present whenever the document was found and accessible, whatever its status — a PROCESSING or FAILED response carries it too. A file that does not exist or does not belong to the deployment returns no _meta at all.
An unrecognized include value returns a 400 naming the allowed values, metadata among them.
Backwards compatibility
Without metadata in include, the response shape is exactly the one documented under Response.