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

# PDF Input

> Attach PDFs in chat, coder, one-shot, the web UI, ACP editors and every gateway channel. Native document input where the model reads PDFs, extracted text everywhere else — no provider is left out.

ChatCLI reads PDFs on **every provider**. Attach one and the model answers from it: in **chat, `/coder`, one-shot (`-p`)**, the **web UI**, **ACP editors** and the **gateway channels** (Telegram, WhatsApp, Slack, Discord, webhook).

***

## How to attach

Point `@file` at a PDF. It is attached as a document, never pasted as raw bytes:

```text theme={"system"}
@file ~/Downloads/contract.pdf what are the termination clauses?
@file report-q3.pdf summarize the incidents and their cost
```

In `/coder`, the model can open a PDF on its own with `@view`, the same tool it uses for images:

```text theme={"system"}
@view docs/spec.pdf
```

The document joins the next turn, so the model reads it in full (scanned pages included, on models that read PDFs natively).

***

## How each provider receives it

The decision is made per provider and per model, when the message is sent:

| Provider | PDF input |
| - | - |
| Anthropic (Claude) | **Native** — every model |
| OpenAI | **Native** — GPT-4o, GPT-4.1, GPT-5 and later |
| Google (Gemini) | **Native** — every Gemini model |
| OpenRouter | **Native** — any model (OpenRouter parses it for models that cannot) |
| AWS Bedrock | **Native** — Claude models and Amazon Nova Lite/Pro/Premier; **text** for the rest |
| Z.AI | **Native** — GLM-5.3-Flash; **text** for the other GLM models |
| xAI, Moonshot, MiniMax, Ollama, Copilot, Devin, StackSpot, OpenAI Assistants, provider plugins | **Extracted text** |

* **Native**: the model gets the PDF itself: text, tables, charts and scanned pages.
* **Extracted text**: ChatCLI extracts the text locally (pure Go, no external tool), page by page with `--- page N ---` markers, so the model can cite pages.

A PDF above a provider's native limit is sent as text instead: 32 MB for Anthropic, 20 MB for Bedrock InvokeModel, 4.5 MB for Bedrock Converse (up to 5 documents), 50 MB for the others, and at most 100 pages natively.

### Scanned PDFs on a text-only model

A scanned PDF has no text layer, so there is nothing to extract. When one goes to a model without native PDF input, ChatCLI asks a configured model that **does** read PDFs to transcribe it first (the current provider, then any other configured one). That pass includes figures and diagrams, described briefly. The transcription is what the current model receives:

```text theme={"system"}
  PDF scan.pdf is a scanned document; transcribed by claudeai/claude-sonnet-4-5 for the current model.
```

If no configured model can read it, you are told, and the model is instructed not to guess the content.

<Tip>
  `CHATCLI_VISION_PROVIDER` / `CHATCLI_VISION_MODEL` also pick the model used for this transcription, when that model reads PDFs.
</Tip>

***

## Everywhere else PDFs are read

| Where | What happens |
| - | - |
| `@read` / `@coder read` | Returns the PDF's text, page-marked (`--- page N ---`). The base64 read still returns the bytes. |
| `/context`, `@file <dir>` | PDFs in a directory are included as their text, knowledge mode included. |
| [`@docs-flatten`](/context/knowledge-base) | PDFs become chunks with `## Page N` headings; a URL crawl follows PDF links. |
| Web UI | The attach button accepts PDFs (shown as a chip). |
| ACP editors | Embedded PDF resources and `resource_link`s to local PDFs reach the model as text. |
| Gateway | Telegram, WhatsApp, Slack and Discord accept PDF files; the webhook accepts `document_b64` / `document_url` (see [Webhook](/gateway/webhook)). A PDF without a caption gets a default "read this document" instruction. |

A PDF that arrives from the web UI or an RPC client is also saved under ChatCLI's private state directory, and its path goes to the model, which can read it again later with `@read`.

***

## Configuration

| Variable | Description | Default |
| - | - | - |
| `CHATCLI_PDF_INPUT` | `auto` (per provider/model, as in the table above), `native` (always send the document, for example to an off-catalog model that reads PDFs), `text` (always send extracted text), `off` (ignore attached PDFs). | `auto` |
| `CHATCLI_GATEWAY_MAX_DOCUMENT_BYTES` | Largest PDF a gateway channel downloads or accepts. | `52428800` (50 MB) |

A model can also be marked in the catalog with the capability `pdf` (force native) or `no_pdf` (force text).

Limits on extraction: 50 MB per attached PDF, up to 500 pages and 2 million characters of text, 60 seconds. Password-protected PDFs are still attached for native models, which may open them; text extraction cannot read them.

<CardGroup cols={2}>
  <Card title="Image Input (Vision)" icon="eye" href="/usage/vision-input">
    Attach images: the same per-provider approach.
  </Card>

  <Card title="Environment variables" icon="sliders" href="/reference/environment-variables">
    Every setting in one place.
  </Card>
</CardGroup>


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