# Upload and reuse files with the Claude Files API

> Upload a PDF once with the Claude Files API, reference it by file_id across requests in Python, then list and delete it.

- Canonical: https://guides-ai.com/guides/claude-api-files-api/
- Plate 15.19 · Topic: Building with the API (https://guides-ai.com/topics/api/)
- Published: 21 Oct 2026 · 3 min read
- Source site: guides-ai — https://guides-ai.com/

The [Files API](https://platform.claude.com/docs/en/build-with-claude/files) lets you upload a document once and reference it by `file_id` in as many Messages requests as you want, instead of re-sending bytes every call. It is now GA, so no beta header is required. Files are scoped to your workspace, so never accept a `file_id` from an untrusted user.

## 1. Install the SDK and set ANTHROPIC_API_KEY

```bash
pip install -U anthropic
```

Installs the official SDK, which reads your key from the environment.

```bash
export ANTHROPIC_API_KEY="sk-ant-..."
```

Export the key once so `anthropic.Anthropic()` picks it up with no argument.

## 2. Upload a file and capture the file_id

```python
import anthropic

client = anthropic.Anthropic()  # reads ANTHROPIC_API_KEY

uploaded = client.files.upload(
    file=("policy.pdf", open("policy.pdf", "rb"), "application/pdf"),
)
print(uploaded.id)  # file_...
```

Uploads a local PDF and returns a `FileMetadata` object whose `id` you reuse everywhere.

## 3. Reference the file_id in a Messages request

```python
msg = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": [
        {"type": "text", "text": "Summarize the cancellation policy."},
        {"type": "document", "source": {"type": "file", "file_id": uploaded.id}},
    ]}],
)
print(msg.content[0].text)
```

A `document` block with `source.type: "file"` points at the stored PDF, no base64 in the payload.

## 4. List and delete files

```python
for f in client.files.list():
    print(f.id, f.filename, f.size_bytes)

client.files.delete(uploaded.id)
```

Lists every file in the workspace, then removes one by id; deletion cannot be undone.

## 5. Limits and when to inline instead

One file is capped at 500 MB and the organization total at 1 TB; uploads, lists, and deletes are free, while file content you reference is billed as input tokens. Images use an `image` block and datasets a `container_upload` block, both with the same `file_id`. For a one-off PDF you read once, the inline base64 approach in [send a PDF to the Claude API](/guides/claude-api-pdf-documents/) is simpler; reach for the Files API when the same document feeds many requests.

## Verify it worked

`client.files.list()` should show your upload, and the Messages call should answer from the document.

**If it fails:**

- **404 `File ... not found`** — the `file_id` is wrong, deleted, or from another workspace; files are workspace-scoped, so use a key for the same workspace.
- **400 invalid file type** — you put a PDF in an `image` block (or vice versa); match the block to the MIME type.
- **400 not downloadable** — you tried `client.files.download()` on a file you uploaded; only files produced by skills or the code execution tool are downloadable.

---

Next: [your first Claude API request](/guides/claude-api-first-request/) · [glossary: API key](/glossary/#api-key).
