# Document extraction and field definitions

> Collect documents and, when you opt in, extract structured fields described by rich field definitions.

Source: https://docs.okyc.stream/concepts/documents

The `documents` step (KYB: `business_documents`) collects files. Each entry is either a document type string
(required, no extraction) or an object:

```json
{
  "key": "docs",
  "capability": "documents",
  "documents": [
    "salary_slip",
    { "type": "utility_bill", "label": "Electricity bill", "required": true, "extract": true,
      "fields": ["due_date", { "key": "account_number", "required": true }] }
  ]
}
```

| Field      |                                                                                                                      |
| ---------- | -------------------------------------------------------------------------------------------------------------------- |
| `type`     | A catalog type (for example `utility_bill`, `bank_statement`, `gst_certificate`) or your own key.                    |
| `label`    | Shown to the applicant.                                                                                              |
| `required` | Default `true`.                                                                                                      |
| `extract`  | Opt in to extraction (default `false`).                                                                              |
| `fields`   | Catalog field names, overrides of catalog fields, or full custom fields (up to 30). All catalog fields when omitted. |
| `accept`   | `image`, `pdf`.                                                                                                      |

`GET /v1/document-types?country=IN` returns the catalog with each type's fields.

## Field definitions

Extraction is driven by field definitions that say exactly what to read. The same definitions guide today's
rule-based extractor and will be the prompt and JSON schema for an AI extractor.

| Property                                  |                                                                                                                                            |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `label`, `description`                    | Required. Describe what the field is — and what it is not.                                                                                 |
| `type`                                    | `string`, `person_name`, `company_name`, `date`, `month`, `amount`, `number`, `address`, `identifier`, `enum`, `boolean`, `list`, `object` |
| `format`, `pattern`, `enum`, `properties` | Shape of the value (`properties` for `object` fields).                                                                                     |
| `examples`                                | Up to 10 sample values.                                                                                                                    |
| `hints`                                   | Printed `labels`, capture `patterns`, `location` (`header`, `body`, `footer`).                                                             |
| `required`                                | Whether the field must be found.                                                                                                           |
| `normalize`                               | `uppercase`, `trim`, `digits`, `iso_date`, `amount_2dp`                                                                                    |
| `validator`, `mask`, `sensitivity`        | Country validator; masking (`last4`, `pan`); `public`, `pii`, `financial`, `government_id`.                                                |
| `match_with`                              | `name`, `dob`, `address` — feeds the profile and cross-source matching.                                                                    |

Custom document types must define all their fields. On publish, the full definitions are frozen into the
workflow version.

## What you get

Each extracted field comes back as `{ value, confidence, extractor, evidence: { page, text } }`, encrypted at
rest. Whatever the extractor, the API validates (type, pattern, country validator), normalises and masks every
value, scrubs masked values from evidence text, and masks Aadhaar numbers. Values that fail validation are
listed under `rejected`; unreadable documents are `inconclusive`.

Reviewers can fix extracted values before the decision — see [reviewer corrections](https://docs.okyc.stream/concepts/reviewer-corrections.md).
