> This page is for version v2026-02-09 (default).
> For other versions, use one of these documentation indexes:
> - v2026-02-09 (default): https://docs.extend.ai/2026-02-09/llms.txt
> - v2025-04-21: https://docs.extend.ai/2025-04-21/llms.txt
> - v2024-12-23: https://docs.extend.ai/2024-12-23/llms.txt

> ## Documentation Index
> Fetch the complete documentation index at: https://docs.extend.ai/llms.txt
> Use this file to discover all available pages before exploring further.
>
> ## API version
> The current API version is `2026-02-09`, served at the site root (no version prefix in URLs).
> If this page URL contains `/2025-04-21/` or `/2024-12-23/`, you are reading an older API version.
> Prefer the current docs at https://docs.extend.ai/llms.txt unless the user explicitly needs that older version.
> Do not treat older-version pages as the source of truth for new integrations.

# Classification Overview

> Classify sorts a document into one of the categories you define, returning the matched type with a confidence score and reasoning. Learn how it works, then run it in minutes.

**Classification** assigns a document to exactly one of the categories you define and returns the match as structured JSON. You describe the possible document types with `classifications`, and Extend returns the matched `type`, a `confidence` score, and reasoning behind the decision. Use it to route incoming documents (invoices vs. bills of lading vs. purchase orders), gate downstream processing, or branch a workflow based on document type.

Classify runs [Parse](/parsing/overview) under the hood, parsing the file first if it hasn't been parsed already and reusing the existing parsed output if it has.

## Quick start

We'll classify a freight invoice into one of several logistics document types. For this quick start we've uploaded the file [here.](https://extend-public-files.s3.us-east-2.amazonaws.com/freight-invoice.pdf)

![A freight invoice document](/_fern-img/0c4d187d2cfa5b209caee4606e669032424a088ec1d3b7bb06fe603af7861720.webp)

Grab a key from the [Developers](https://dashboard.extend.ai/developers) page and store it as the `EXTEND_API_KEY` environment variable. If you're using an SDK, see the [installation instructions](/sdks).

```bash
export EXTEND_API_KEY="your_api_key_here"
```

The `/classify` endpoint takes a `file` and a `config` with the `classifications` you want to choose between.

#### Python

```python
from extend_ai import Extend

client = Extend()

result = client.classify(
    file={
        "url": "https://extend-public-files.s3.us-east-2.amazonaws.com/freight-invoice.pdf",
    },
    config={
        "classifications": [
            {
                "id": "invoice",
                "type": "invoice",
                "description": "An invoice or bill requesting payment for goods or services.",
            },
            {
                "id": "bill_of_lading",
                "type": "bill_of_lading",
                "description": "A bill of lading documenting a shipment of goods.",
            },
            {
                "id": "purchase_order",
                "type": "purchase_order",
                "description": "A purchase order authorizing a purchase.",
            },
            {
                "id": "other",
                "type": "other",
                "description": "Any other document type.",
            },
        ],
    },
)

print(result)
```

#### TypeScript

```typescript
import { ExtendClient } from "extend-ai";

const client = new ExtendClient();

const result = await client.classify({
  file: {
    url: "https://extend-public-files.s3.us-east-2.amazonaws.com/freight-invoice.pdf",
  },
  config: {
    classifications: [
      {
        id: "invoice",
        type: "invoice",
        description: "An invoice or bill requesting payment for goods or services.",
      },
      {
        id: "bill_of_lading",
        type: "bill_of_lading",
        description: "A bill of lading documenting a shipment of goods.",
      },
      {
        id: "purchase_order",
        type: "purchase_order",
        description: "A purchase order authorizing a purchase.",
      },
      {
        id: "other",
        type: "other",
        description: "Any other document type.",
      },
    ],
  },
});

console.log(result);
```

#### Java

```java
import ai.extend.ExtendClient;
import ai.extend.requests.ClassifyRequest;
import ai.extend.types.Classification;
import ai.extend.types.ClassifyConfig;
import ai.extend.types.ClassifyRequestFile;
import ai.extend.types.ClassifyRun;
import ai.extend.types.FileFromUrl;
import java.util.List;

ExtendClient client = ExtendClient.builder().build();

ClassifyConfig config = ClassifyConfig.builder()
    .classifications(List.of(
        Classification.builder()
            .id("invoice")
            .type("invoice")
            .description("An invoice or bill requesting payment for goods or services.")
            .build(),
        Classification.builder()
            .id("bill_of_lading")
            .type("bill_of_lading")
            .description("A bill of lading documenting a shipment of goods.")
            .build(),
        Classification.builder()
            .id("purchase_order")
            .type("purchase_order")
            .description("A purchase order authorizing a purchase.")
            .build(),
        Classification.builder()
            .id("other")
            .type("other")
            .description("Any other document type.")
            .build()))
    .build();

ClassifyRun result = client.classify(ClassifyRequest.builder()
    .file(ClassifyRequestFile.of(FileFromUrl.builder()
        .url("https://extend-public-files.s3.us-east-2.amazonaws.com/freight-invoice.pdf")
        .build()))
    .config(config)
    .build());

System.out.println(result);
```

#### Go

```go
package main

import (
	"context"
	"fmt"
	"log"

	extend "github.com/extend-hq/extend-go-sdk"
	client "github.com/extend-hq/extend-go-sdk/client"
)

func main() {
	c := client.NewClient()

	config := &extend.ClassifyConfig{
		Classifications: []*extend.Classification{
			{ID: "invoice", Type: "invoice", Description: "An invoice or bill requesting payment for goods or services."},
			{ID: "bill_of_lading", Type: "bill_of_lading", Description: "A bill of lading documenting a shipment of goods."},
			{ID: "purchase_order", Type: "purchase_order", Description: "A purchase order authorizing a purchase."},
			{ID: "other", Type: "other", Description: "Any other document type."},
		},
	}

	result, err := c.Classify(context.TODO(), &extend.ClassifyRequest{
		File: &extend.ClassifyRequestFile{
			FileFromURL: &extend.FileFromURL{
				URL: "https://extend-public-files.s3.us-east-2.amazonaws.com/freight-invoice.pdf",
			},
		},
		Config: config,
	})
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(result)
}
```

#### cURL

```bash
curl -X POST https://api.extend.ai/classify \
  -H "x-extend-api-version: 2026-02-09" \
  -H "Authorization: Bearer $EXTEND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "file": {
      "url": "https://extend-public-files.s3.us-east-2.amazonaws.com/freight-invoice.pdf"
    },
    "config": {
      "classifications": [
        { "id": "invoice", "type": "invoice", "description": "An invoice or bill requesting payment for goods or services." },
        { "id": "bill_of_lading", "type": "bill_of_lading", "description": "A bill of lading documenting a shipment of goods." },
        { "id": "purchase_order", "type": "purchase_order", "description": "A purchase order authorizing a purchase." },
        { "id": "other", "type": "other", "description": "Any other document type." }
      ]
    }
  }'
```

> **Tip**
>
> Want to classify your own document? [Upload it](/api-reference/endpoints/file/upload-file) first, then pass the returned file `id` instead of a `url` (reusing the same `config`).
>
> #### Python
>
> ```python
> with open("freight_invoice.pdf", "rb") as f:
>     uploaded = client.files.upload(file=f)
>
> result = client.classify(file={"id": uploaded.id}, config=config)
> ```
>
> #### TypeScript
>
> ```typescript
> import { createReadStream } from "fs";
>
> const uploaded = await client.files.upload(createReadStream("freight_invoice.pdf"), {});
>
> const result = await client.classify({ file: { id: uploaded.id }, config });
> ```
>
> #### Java
>
> ```java
> import ai.extend.requests.FilesUploadRequest;
> import ai.extend.types.File;
> import ai.extend.types.FileFromId;
>
> File uploaded = client.files().upload(
>     new java.io.File("freight_invoice.pdf"),
>     FilesUploadRequest.builder().build());
>
> ClassifyRun result = client.classify(ClassifyRequest.builder()
>     .file(ClassifyRequestFile.of(FileFromId.builder().id(uploaded.getId()).build()))
>     .config(config) // the ClassifyConfig from above
>     .build());
> ```
>
> #### Go
>
> ```go
> f, err := os.Open("freight_invoice.pdf")
> if err != nil {
> 	log.Fatal(err)
> }
> defer f.Close()
>
> uploaded, err := c.Files.Upload(context.TODO(), f, &extend.FilesUploadRequest{})
> if err != nil {
> 	log.Fatal(err)
> }
>
> result, err := c.Classify(context.TODO(), &extend.ClassifyRequest{
> 	File:   &extend.ClassifyRequestFile{FileFromID: &extend.FileFromID{ID: uploaded.ID}},
> 	Config: config, // the *extend.ClassifyConfig from above
> })
> ```
>
> #### cURL
>
> ```bash
> # Upload the file to get an id
> curl -X POST https://api.extend.ai/files/upload \
>   -H "Authorization: Bearer $EXTEND_API_KEY" \
>   -H "x-extend-api-version: 2026-02-09" \
>   -F "file=@freight_invoice.pdf"
>
> # Then classify using the returned id
> curl -X POST https://api.extend.ai/classify \
>   -H "Authorization: Bearer $EXTEND_API_KEY" \
>   -H "x-extend-api-version: 2026-02-09" \
>   -H "Content-Type: application/json" \
>   -d '{ "file": { "id": "file_xK9mLPqRtN3vS8wF5hB2cQ" }, "config": { "classifications": [ { "id": "other", "type": "other", "description": "Any other document type." } ] } }'
> ```

### Example response

After you run the code snippet above, you'll see a response like this. Extend parses the document, picks the best-matching category, and returns an `output` with the matched classification, a `confidence` score, and `insights` explaining the decision.

```json
{
  "object": "classify_run",
  "id": "clr_Xj8mK2pL9nR4vT7qY5wZ",
  "status": "PROCESSED",
  "output": {
    "id": "invoice",
    "type": "invoice",
    "confidence": 0.97,
    "insights": [
      {
        "type": "reasoning",
        "content": "The document is titled \"Freight Invoice\" and lists line items, amounts, and payment terms."
      }
    ]
  }
}
```

### Key fields

| Field               | What it contains                                                                                                       |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `output.id`         | The `id` of the matched classification, as defined in your `classifications`. Branch your logic on this — it's stable. |
| `output.type`       | The `type` of the matched classification.                                                                              |
| `output.confidence` | The model's confidence in the match, from `0` to `1`.                                                                  |
| `output.insights`   | Reasoning behind the classification decision.                                                                          |

For full request/response details, see the [Create Classify Run API reference](/api-reference/endpoints/classify/create-classify-run).

### Use the output

Branch your logic on the returned `id`, and use `confidence` to decide when to route a document to manual review. Match on `id` rather than `type`: the `id` is a stable identifier you control, while `type` and `description` are part of the prompt that steers the classification decision and may change as you tune accuracy.

#### Python

```python
output = result.output

if output.confidence < 0.8:
    print(f"Low confidence ({output.confidence}) — route to review")
elif output.id == "invoice":
    print("Send to the invoice extractor")
```

#### TypeScript

```typescript
const output = result.output;

if (output && output.confidence < 0.8) {
  console.log(`Low confidence (${output.confidence}) — route to review`);
} else if (output?.id === "invoice") {
  console.log("Send to the invoice extractor");
}
```

#### Java

```java
import ai.extend.types.ClassifyOutput;

ClassifyOutput output = result.getOutput().get();

if (output.getConfidence() < 0.8) {
    System.out.println("Low confidence (" + output.getConfidence() + ") — route to review");
} else if (output.getId().equals("invoice")) {
    System.out.println("Send to the invoice extractor");
}
```

#### Go

```go
output := result.Output

if output.Confidence < 0.8 {
	fmt.Printf("Low confidence (%v) — route to review\n", output.Confidence)
} else if output.ID == "invoice" {
	fmt.Println("Send to the invoice extractor")
}
```

For the full output shape and shared types, see [Response Format](/classification/response-format).

## Sync vs async

The example above calls the synchronous `/classify` endpoint. We also have an asynchronous `/classify_runs` endpoint that should be used for large files and high volume use cases.

See [Async Processing](/general/async-processing) for the full comparison, polling options, and webhook setup.

## Save it as a processor

The quick start runs with an inline `config`, which is perfect for getting started. To reuse a configuration across runs — and to version it, measure its accuracy, and optimize it — save it as a **classifier**, a kind of [processor](/evaluation/processors). Processors are the saved entities you iterate on in the dashboard, run [evaluation sets](/evaluation/overview) against, and improve with [Composer](/optimization/composer).

## Configuration

The quick start sends just `file` and `config.classifications`. To control how classification runs, pass more options inside `config`. Here are the most commonly used ones; for the full reference, see [Configuration](/classification/configuration).

### Classifications

The `classifications` array is the heart of every classifier — the set of categories the model chooses from. Each entry needs a unique `id`, a `type` returned in the output, and a `description` (your biggest lever on accuracy). At least one classification must have the type `"other"` as a catch-all.

```json
{
  "config": {
    "classifications": [
      { "id": "invoice", "type": "invoice", "description": "An invoice or bill requesting payment." },
      { "id": "other", "type": "other", "description": "Any other document type." }
    ]
  }
}
```

### Base processor

Choose the processor based on your accuracy and latency needs.

```json
{ "config": { "baseProcessor": "classification_performance" } }
```

| Processor                    | When to use                     |
| ---------------------------- | ------------------------------- |
| `classification_performance` | Highest accuracy (default).     |
| `classification_light`       | Faster, cheaper classification. |

### Classification rules

Steer the model with plain-language rules — useful for disambiguating categories that look similar.

```json
{
  "config": {
    "classificationRules": "When differentiating invoices from purchase orders, the most important signal is whether payment is being requested."
  }
}
```

### Parse config

Because Classify runs Parse under the hood, you can tune how the document is parsed before classification with `parseConfig`.

```json
{
  "config": {
    "parseConfig": {
      "target": "markdown",
      "chunkingStrategy": { "type": "page" }
    }
  }
}
```

> **Note**
>
> For every option, including advanced options like context, multimodal processing, and memory, see the [Configuration](/classification/configuration) reference.

---

## Next steps

#### [Configuration](/classification/configuration)

Classifications, rules, base processor, and advanced options.

#### [Response Format](/classification/response-format)

The full shape of the classify run and output.

#### [Workflows](/workflows/overview)

Branch a document pipeline based on the classified type.

#### [API Reference](/api-reference/endpoints/classify/classify-file)

Full request and response schema for the classify endpoint.