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

# Extract

> Pulls the fields you define out of the parsed document, each with a value, a confidence and the evidence it came from.

**Extract** reads what [Parse](/guides/nodes/parse) produced and fills in a schema: the fields you name, typed, with a confidence score and the source text for each. It is the node most workflows exist for. It lives in the **Intelligence** section of the Studio palette.

The one thing an Extract node needs is its **schema**: the list of fields to pull out. Everything else is optional. The **tier** (`mode`) sets how much work to spend per page.

## The node

<CodeGroup>
  ```json API theme={null}
  {
    "id": "extract_1",
    "type": "extract",
    "extraction_schema": {
      "fields": [
        { "name": "invoice_number", "description": "The unique invoice identifier", "data_type": "string" },
        { "name": "total_amount",   "description": "Total invoice amount",          "data_type": "float" },
        { "name": "issue_date",     "description": "Date when the invoice was issued", "data_type": "date" }
      ]
    }
  }
  ```

  ```python Python theme={null}
  import os

  from anyformat.sdk import Client
  from anyformat.workflow import Schema

  client = Client(api_key=os.environ["ANYFORMAT_API_KEY"])

  workflow = (
      client.workflow("Invoice Processing")
      .parse()
      .extract([
          Schema.string("invoice_number", "The unique invoice identifier"),
          Schema.float("total_amount",    "Total invoice amount"),
          Schema.date("issue_date",       "Date when the invoice was issued"),
      ])
      .create()
  )
  ```

  ```typescript TypeScript theme={null}
  import { Anyformat, Schema } from "@anyformat/sdk";

  const af = new Anyformat({ apiKey: process.env.ANYFORMAT_API_KEY! });

  const workflow = await af
    .workflow("Invoice Processing")
    .parse()
    .extract([
      Schema.string("invoice_number", "The unique invoice identifier"),
      Schema.float("total_amount",    "Total invoice amount"),
      Schema.date("issue_date",       "Date when the invoice was issued"),
    ])
    .create();
  ```
</CodeGroup>

Each field has a name, a description the model reads, and a type. The types (`string`, `float`, `date`, `enum`, `object` and the rest) are on [Field types](/concepts/field-types). How to write a schema that extracts well is on [Schemas](/concepts/schemas).

The same node on the agentic tier, with a [Smart lookup](/guides/nodes/smart-lookup) field that resolves the supplier name against a reference CSV:

<CodeGroup>
  ```json API theme={null}
  {
    "id": "extract_1",
    "type": "extract",
    "mode": "agentic",
    "extraction_schema": {
      "fields": [
        { "name": "supplier_name", "description": "Supplier name as printed", "data_type": "string" },
        { "name": "supplier_code", "description": "Internal supplier code",   "data_type": "string", "source": "smart_lookup" }
      ]
    },
    "lookup_file_uploads": [{ "filename": "suppliers.csv", "content": "<base64>" }],
    "lookup_suggestion": "Match supplier names ignoring legal suffixes like GmbH or Ltd"
  }
  ```

  ```python Python theme={null}
  client.workflow("Invoices with supplier codes").parse().extract(
      [
          Schema.string("supplier_name", "Supplier name as printed"),
          Schema.string("supplier_code", "Internal supplier code", source="smart_lookup"),
      ],
      lookup_files=["suppliers.csv"],
      lookup_suggestion="Match supplier names ignoring legal suffixes like GmbH or Ltd",
  )
  ```

  ```typescript TypeScript theme={null}
  af.workflow("Invoices with supplier codes").parse().extract(
    [
      Schema.string("supplier_name", "Supplier name as printed"),
      Schema.string("supplier_code", "Internal supplier code", { source: "smart_lookup" }),
    ],
    {
      mode: "agentic",
      lookupFiles: ["suppliers.csv"],
      lookupSuggestion: "Match supplier names ignoring legal suffixes like GmbH or Ltd",
    },
  )
  ```
</CodeGroup>

The SDKs read each path in `lookup_files` from disk and send it as `lookup_file_uploads`. The API call sends the file content inline, base64-encoded.

<Note>
  The Python SDK's `extract()` does not take `mode` or `lookup_reasoning_effort` yet. Set them in the API JSON, in Studio, or from the TypeScript SDK.
</Note>

A workflow can hold several Extract nodes. After a [Classify](/guides/nodes/classify) or [Split](/guides/nodes/split) node, each Extract sits on one branch and gets its own schema. See those pages for the `branch` argument.

## In Studio

Click the Extract node on the canvas to open its panel. The **Schema** tab holds the fields. The **Config** tab holds the tier cards and the **Lookup files**, **Lookup suggestion** and **Lookup matching effort** controls.

<img src="https://mintcdn.com/anyformat/G2lOO-2_Ah2kKl9r/images/studio-extract-config.webp?fit=max&auto=format&n=G2lOO-2_Ah2kKl9r&q=85&s=d5d66a6348d92f9ff2af5d015c75d4a4" alt="Configuring the Extract node in Studio" width="512" height="523" data-path="images/studio-extract-config.webp" />

The **Config** tab holds the tier, the lookup files and matcher settings, and the per-field **Lookup** toggles.

<img src="https://mintcdn.com/anyformat/G2lOO-2_Ah2kKl9r/images/studio-extract-settings.webp?fit=max&auto=format&n=G2lOO-2_Ah2kKl9r&q=85&s=5fad19328c02d0f67908827f7d785546" alt="Smart lookup settings on the Extract node" width="512" height="986" data-path="images/studio-extract-settings.webp" />

## Tiers

| Tier | `mode` | What it does | When to use it | Credits / page |
| - | - | - | - | - |
| **Fast** (Beta) | `lite` | Standard extraction on a faster, cheaper model. | Simple documents at volume. Quality may vary on complex layouts. | 17 |
| **Standard** | `standard` | Single-pass extraction. The default. | Most documents and layouts. Start here. | 35 |
| **Agentic** | `agentic` | Multi-step extraction that maps every table to the schema and reasons across sections. | Dense or cross-page tables, values spread over several sections. | 150 |

<Tip>
  Start on Standard. Move down to Fast where it holds up, and up to Agentic only where Standard misses rows or mixes up columns.
</Tip>

## Options

`extraction_schema` is required. Every other field is optional. Omit a field and the default applies.

| Field | Type | Default | What it does |
| - | - | - | - |
| `extraction_schema` | object | required | `{ "fields": [...] }`. At least one field. Each field carries `name`, `description`, `data_type`, and optionally `source` and `persistent_id`. See [Field types](/concepts/field-types). |
| `mode` | `standard` \| `agentic` \| `lite` | `standard` | The tier. `lite` is shown as **Fast** in the app. |
| `use_images` | boolean | `false` | Retired. Accepted for compatibility and ignored: extraction reads the parsed text only. |
| `lookup_file_uploads` | array of `{ filename, content }` | `[]` | Reference files for [Smart lookup](/guides/nodes/smart-lookup), sent inline with `content` base64-encoded. Each one is uploaded and its new id is appended to `lookup_file_ids`. Create-input only: it is not stored on the node. |
| `lookup_file_ids` | array of string | `[]` | Ids of the reference files already attached to the workflow. Read this back from `GET` and send it back unchanged to keep them; write `lookup_file_uploads` to add files. |
| `lookup_suggestion` | string | `null` | Free-form hint shown to the lookup matcher, for example "Match supplier names ignoring legal suffixes like GmbH or Ltd". Applies to every lookup field in the node. |
| `lookup_reasoning_effort` | `minimal` \| `low` \| `medium` \| `high` | `null` | How hard the lookup matcher works on noisy or inexact keys. `null` is the model default. Higher effort improves match reliability at higher latency and cost. Only used when the node has at least one lookup field. |

A field's `source` decides where its value comes from: `extraction` (the document, the default), `smart_lookup` (the reference file, always) or `lookup_if_missing` (the document first, the reference file when extraction left it blank).

The schema the API accepts is generated from the same source: [Extract node schema](/api-reference-v3/node-schemas#extract).

## Connects to

<div className="af-flow" role="img" aria-label="Parse feeds Extract, which feeds Validate">
  <div className="af-flow-row">
    <a className="af-node" href="/guides/nodes/parse">Parse</a>

    <span className="af-link" />

    <a className="af-node af-node-on" href="/guides/nodes/extract">Extract</a>

    <span className="af-link" />

    <a className="af-node af-node-opt" href="/guides/nodes/validate">Validate</a>
  </div>

  <div className="af-flow-note">A <a href="/guides/nodes/classify">Classify</a> or a <a href="/guides/nodes/split">Split</a> node can feed Extract in place of Parse.</div>
</div>

An Extract node has one outgoing edge at most. Send it to [Validate](/guides/nodes/validate) to check the values, [If/Else](/guides/nodes/if-else) to branch on them, [Slack alert](/guides/nodes/slack-alert) to announce them, or [Knowledge](/guides/nodes/knowledge) to index the document.

## What it returns

Extract fills the `extractions` section of the [run results](/concepts/runs-and-results). A workflow with one Extract and no Split returns one entry, and every field in it carries a value, a confidence and the evidence it came from.

```json highlight={7,8} theme={null}
{
  "extractions": [
    {
      "split_name": null,
      "partition": null,
      "fields": {
        "invoice_number": { "value": "INV-2024-0847", "confidence": 97.0, "evidence": [{ "text": "Invoice #INV-2024-0847", "page_number": 1 }] },
        "total_amount":   { "value": "4087.50",      "confidence": 96.0, "evidence": [{ "text": "Total: $4,087.50", "page_number": 2 }] }
      }
    }
  ]
}
```

`split_name` and `partition` stay `null` unless a [Split](/guides/nodes/split) node ran. `fields` is keyed by the field name you gave on the node. `value` is a string on the wire whatever the field's `data_type`, and `null` when nothing was found. `confidence` is on a 0 to 100 scale. `evidence` lists the source snippets and the page each came from.

<Accordion title="Every key on a field">
  ```json theme={null}
  {
    "invoice_number": {
      "value": "INV-2024-0847",
      "value_override": null,
      "verification_status": "not_verified",
      "confidence": 97.0,
      "evidence": [{ "text": "Invoice #INV-2024-0847", "page_number": 1 }]
    }
  }
  ```

  `value_override` holds a human correction from review, or `null`. `verification_status` is the review state of the value, and starts at `not_verified`. Both come from [Verification and review](/guides/workflows/verification-review).
</Accordion>

**Value types on the wire.** Every `value` is a string or `null`, so parse it by the field's `data_type` on your side:

* A `boolean` field returns the string `"True"` or `"False"`.
* A `multi_select` field returns one comma-separated string, for example `"a, b, c"`, not a list.
* A field the model could not find returns `{ "value": null, "value_override": null, "verification_status": "not_verified", "confidence": null, "evidence": [] }`.
* An `object` field returns a list of rows. Each row is a dict from nested field name to the same `{ value, value_override, verification_status, confidence, evidence }` shape.

After a Split node, `extractions` holds one entry per split and partition. See [Split](/guides/nodes/split#what-it-returns). The whole run envelope is on [Runs & results](/concepts/runs-and-results#what-the-results-contain).

## Billing

Billed per page at the tier's rate (table above). A node with at least one lookup field adds 75 credits per page for Smart Lookup. Schema size and field count do not change the price. Full price list: [How credits work](/concepts/how-credits-work).

## Examples

* [Invoice processing](/examples/invoice-processing): the usual Parse to Extract shape, with line items as an object field.
* [Resume parsing](/examples/resume-parsing): nested fields and multi-select.
* [Contract analysis](/examples/contract-analysis): long documents, dates and enums.
* [Bank statement processing](/examples/bank-statement-processing): Split, then one Extract per statement.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.