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

# Document classifiers

> Train or import deterministic machine-learning models that sort document pages into categories, and route each page in a workflow based on the predicted label.

A Document Classifier is a trained machine-learning model that sorts document pages into categories you define, such as `INVOICE`, `NATIONAL_ID`, or `BANK_STATEMENT`, so a workflow can route each page to the right handling. Classification is deterministic: the same page always gets the same result, and no large language model runs at inference time.

Document Classifiers live in your project under **Integrations** → **Document Classifiers**, alongside Data Sources, Workflows, and Proxy Connections.

***

## When to use a Document Classifier

FlowX offers two ways to classify documents. Pick based on how well-defined your document types are and how much labeled data you have:

| Approach | Best for |
| - | - |
| **Document Classifier** (this page) | Narrow, well-defined document types at scale. Deterministic results, low latency, low cost per page. Needs labeled example pages to train. |
| **LLM-based classification** with a [Custom Agent](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/custom-agent-node.md) | Standing something up fast without training data, or open-ended document types. Results vary between runs and cost more per page. |

> [!NOTE]
>
> Two other features have similar names but do different things: **Document Intelligence** ingests documents into a knowledge base for AI retrieval, and the **Extract Data from File** workflow node extracts field values from a document. A Document Classifier only answers one question per page: *which category is this?*

***

## Create a Document Classifier

**1. Open Document Classifiers**

In your project, go to **Integrations** → **Document Classifiers** and click **+**.

**2. Name the classifier**

Enter a **Name** and an optional **Description**.

**3. Choose how the model gets trained**

Leave **Use preexisting model bundle** toggled **OFF** to create an empty classifier and train it in FlowX (the usual path). Toggle it **ON** to import a model bundle exported from another FlowX environment. See [Import a pre-trained bundle](#import-a-pre-trained-bundle).

The classifier detail page has three tabs (**Classes**, **Data**, and **Trained Models**) that mirror the three parts of a classifier: a label taxonomy, a labeled page corpus, and trained model versions.

***

## Define classes

Classes are the categories the model sorts pages into. Open the **Classes** tab and click **New class**.

**Class name** `string` *required*

Must be UPPER\_SNAKE\_CASE (letters, digits, underscores, starting with a letter, such as `NATIONAL_ID`) and unique within the classifier.

**Description** `string` *required*

Describe what differentiates this class from the others. The description guides automatic pre-labeling when you upload unlabeled documents.

**Positive examples** `list`

Snippets of text likely to appear verbatim in a document of this class.

**Negative examples** `list`

Snippets that look like this class but are not. They help the model separate near-misses.

Every classifier ships with a locked **UNKNOWN** class as the default catch-all. Pages that don't belong to any of your classes get labeled `UNKNOWN` instead of landing in a wrong category.

> [!TIP]
>
> Define at least two classes besides `UNKNOWN`, and make them mutually exclusive. If two classes overlap heavily, merge them and let a downstream step tell them apart.

***

## Build the corpus

The unit of classification is a **page**, not a file. The **Data** tab is where labeled pages accumulate into the training corpus. There are two ways to add pages:

* **Upload unlabeled batch**: drop ZIP, PDF, or Word files. Source files can be up to 20 MB each. The pages are pre-labeled automatically and queued for your review; each page needs review before it joins the corpus.&#x20;
* **Upload sorted by class**: drop files that are already sorted per class; the pages join the corpus directly, without review.

Added pages join the corpus with an automatic **80% train / 20% test** split, assigned per class when the page enters and never reshuffled, so test results stay comparable between training runs. Pages labeled `UNKNOWN` go entirely to the test pool. The corpus table shows every page with its class, split, and upload batch. You can remove pages, but not relabel them in place.

***

## Train a model

In the **Data** tab, select the training pages to use and click **Train model**. Training requires at least **10 training pages for every class**; the locked `UNKNOWN` class is exempt. A warning appears when the corpus is heavily imbalanced: when one class has far more pages than another, the model tends to over-predict the bigger one.&#x20;

Training runs asynchronously. Each successful run produces an immutable **model version** in the **Trained Models** tab, with its accuracy metrics, per-class results, and a confusion matrix. You can compare any two versions to see what changed between training runs.

The **main** version is the one workflows use. The first trained version becomes main automatically; promote a different version when it performs better.

> [!NOTE]
>
> Training and promotion work on the draft (WIP) version of your project. Committing a project version freezes the classifier's corpus and training for that version. Editing a committed classifier continues on a new draft.

### What travels between environments

When you export or build a project, the classifier's **class taxonomy travels with it** as part of the versioned configuration. The **corpus and trained models do not travel with a project export or build**: the target environment receives the classes and trains against its own data.&#x20;

The corpus itself can now move between environments: export a classifier's corpus and import it into the classifier in the target environment. An imported corpus appears in a **read-only view** in the classifier's **Data** tab, so you can inspect the pages it was trained on without editing them there. Exporting a corpus requires the ML models permission. To move a trained model, use the pre-trained bundle flow described below.

***

## Import a pre-trained bundle

If you already have a model trained in another FlowX environment, toggle **Use preexisting model bundle** ON when creating the classifier and upload the exported bundle: a ZIP with the model metadata and binary. FlowX validates the bundle on upload and adds it as an uploaded candidate version:

* It must define at least two classes, named in UPPER\_SNAKE\_CASE, without duplicates.
* Its training metrics must be present and consistent with the declared class set.
* FlowX rejects a bundle that fails validation; nothing is created. A bundle that uploads but fails processing leaves the classifier in a **Failed** state with a **Retry** option.

> [!WARNING]
>
> Bundles are produced by FlowX. Export them from an environment where the model was trained: hand-assembled bundles fail validation or produce meaningless predictions, because the model's features are tied to how it was trained.

***

## Classify pages in a workflow

Consume the trained model with the **Document Classification** node from the workflow node palette.  The node is a pure classifier: it labels pages and writes the result. Routing happens in a downstream condition node.

| Field | Description | Default |
| - | - | - |
| **Document Classifier** | The classifier whose main model version runs. A read-only **Classes** hint lists its labels so you can build the downstream condition. | N/A |
| **File Content** | An expression that resolves to an array of extracted page texts, one entry per page, such as `${extractedPages}`. | N/A |
| **Confidence Threshold** | Predictions below this probability get flagged `low_confidence`. | `0.7` |
| **Response Key** | The key the node writes the result JSON under. | `responseKey` |
| **Timeout** | Inference call timeout, in milliseconds. | `10000` |

> [!WARNING]
>
> The node classifies **text, not files**. Extract page text upstream, for example with the **Extract Data from File** node or your document processing flow, and pass the array of page texts to **File Content**.

### Output

The node classifies each page independently and writes one result object:

```json theme={"dark"}
{
  "pages": [
    {
      "page": 1,
      "predictedLabel": "NATIONAL_ID",
      "predictedProbability": 0.92,
      "low_confidence": false,
      "classes": [
        { "label": "NATIONAL_ID", "probability": 0.92 },
        { "label": "PASSPORT", "probability": 0.05 }
      ],
      "error": null
    }
  ],
  "confidenceThreshold": 0.7,
  "error": null
}
```

* `predictedLabel` is the highest-probability class; `classes` lists all class probabilities in descending order.
* `low_confidence` is `true` when `predictedProbability` is below the configured threshold. A low-confidence prediction is still a **successful** result. Use the condition node to route those pages to human review instead of treating them as failures.
* A single page failing to classify populates that page's `error` and the node still succeeds; the other pages classify normally.
* Whole-node failures set the top-level `error` and route to the node's error output. The error codes:

| Code | Meaning |
| - | - |
| `MODEL_NOT_FOUND` | The selected classifier or its main model version doesn't exist. |
| `MODEL_NOT_READY` | The classifier has no trained, ready model version yet. |
| `NO_DOCUMENT_TEXT` | The File Content expression resolved to nothing. |
| `EMPTY_INPUT` | The input resolved to an empty page list. |
| `INVALID_TIMEOUT` | The configured timeout value isn't usable. |
| `INFERENCE_UNAVAILABLE` | The classification service is unreachable. Retryable. |

### Route by label

Add a **Condition** node after the Document Classification node and branch on the result: typically iterating `pages` and switching on `predictedLabel`, with a separate branch for `low_confidence` pages.

***

## Related resources

> [card] [Integration Designer](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/integration-designer.md)
>
> Build workflows that combine classifiers with REST calls, data operations, and AI nodes

> [card] [Custom Agent node](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/custom-agent-node.md)
>
> LLM-based alternative for classification without training data


## Related topics

- [FlowX.AI 5.13.0 Release Notes](https://docs.flowx.ai/release-notes/v5.x/v5.13.0-september-2026/v5.13.0-september-2026.md)
- [FlowX.AI 5.11.0 Release Notes](https://docs.flowx.ai/release-notes/v5.x/v5.11.0-august-2026/v5.11.0-august-2026.md)
- [FlowX.AI 5.9.x to 6.0.0 changelog](https://docs.flowx.ai/release-notes/v6.x/5.9-to-6.0-changelog.md)
- [Deployment guidelines v6.0.0](https://docs.flowx.ai/release-notes/v6.x/v6.0.0-october-2026/deployment-guidelines-v6.0.md)
- [Deployment guidelines v5.11](https://docs.flowx.ai/release-notes/v5.x/v5.11.0-august-2026/deployment-guidelines-v5.11.md)


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