> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Document AI report

> Parse Document AI results: the upload endpoint, per-document extracted fields keyed by your configuration, status, and where the feature appears in the decision.

## Overview

Document AI accepts up to 3 documents per step (PDF or image — PDF, JPG, JPEG, PNG, TIFF, WebP). Each document is classified by its configured `document_key`, read by a vision-language model using a schema built from your field definitions, and run through PDF/EXIF forensics. For every document it stores:

* The **extracted fields** — a map keyed by your configured field `key`, with values typed as you declared them (`text` → string, `number` → number, `date` → `YYYY-MM-DD`). Fields that could not be read are `null`.
* The **document status** — `Approved`, `In Review`, `Declined`, or `Not Finished`.
* **Document metadata** — file forensics including any overlay/manipulation evidence.
* **Cross-check results** — the outcome of name matching against the verified identity and of any custom field cross-references.

## Uploading documents

Documents are uploaded one at a time to the Document AI endpoint. In a hosted session or SDK flow this is handled for you; the contract is:

```text theme={null}
POST https://verification.didit.me/v3/document-ai/documents/
multipart/form-data — Session-Token: <session token>
```

| Field          | Required | Description                                            |
| -------------- | -------- | ------------------------------------------------------ |
| `document_key` | yes      | The configured document this file fulfills             |
| `document`     | yes      | The file to upload                                     |
| `locale`       | no       | Locale used to resolve the on-screen title/description |

The response advances the flow:

```json theme={null}
{
  "valid": true,
  "next_step": "DOCUMENT_AI",
  "document_ai_status": "In Progress",
  "uploaded_document_keys": ["proof_of_funds"],
  "required_document_keys": ["proof_of_funds", "payslip"]
}
```

The step completes (`next_step` moves past `DOCUMENT_AI`) once every entry in `required_document_keys` appears in `uploaded_document_keys` and no document is left unfinished.

## Where it appears in API responses

`GET /v3/session/{sessionId}/decision/` surfaces Document AI in two places:

* **`features[]`** — a summary entry per Document AI node, used to enumerate which features ran:

  ```json theme={null}
  { "features": [ { "feature": "DOCUMENT_AI", "node_id": "feature_document_ai_1" } ] }
  ```

* **`document_ai_documents[]`** — the full result, one group per Document AI node. Each group carries the node's combined `status`, the list of uploaded `items`, and any `warnings`. Every uploaded document is an item with the fields you configured (under `extracted_data`), its own `status`, the field definitions, forensic `document_metadata`, and `cross_check_result`.

Each node's per-document statuses combine into the node status using the precedence **Declined > In Review > Approved**.

## Decision example

For a **Proof of Funds** document configured with `account_holder` (text), `balance` (number), `currency` (text), and `statement_date` (date):

```json theme={null}
{
  "document_ai_documents": [
    {
      "node_id": "feature_document_ai_1",
      "status": "Approved",
      "items": [
        {
          "uuid": "5c1f0a2e-9b3d-4c7a-8f21-0a4e8e7d6c12",
          "document_key": "proof_of_funds",
          "status": "Approved",
          "original_filename": "statement.pdf",
          "extracted_data": {
            "account_holder": "Sophia Martinez",
            "balance": 18450.75,
            "currency": "EUR",
            "statement_date": "2026-05-31"
          },
          "fields": [
            { "key": "account_holder", "name": "Account holder", "type": "text", "required": true },
            { "key": "balance", "name": "Balance", "type": "number", "required": false },
            { "key": "currency", "name": "Currency", "type": "text", "required": false },
            { "key": "statement_date", "name": "Statement date", "type": "date", "required": false }
          ],
          "document_metadata": { "is_tampered": false },
          "cross_check_result": null,
          "created_at": "2026-05-31T10:12:00Z"
        }
      ],
      "warnings": []
    }
  ]
}
```

Because every field is addressable as `document_ai.<field_key>`, you can drive branching and [custom status rules](/core-technology/document-ai/warnings-document-ai) directly from the `extracted_data` values — including cross-references against other steps such as `kyc.full_name` or questionnaire answers.
