Every time you send a PDF to Claude through the Messages API, you base64-encode it and shove the whole thing into your request body. That works fine for one-off calls, but if you’re referencing the same document across multiple requests – or processing dozens of files in a pipeline – you’re wasting bandwidth and time re-uploading identical bytes.
The Files API fixes this. Upload a file once, get back a file_id, and reference that ID in any future Messages request. The file persists on Anthropic’s servers until you delete it. No more base64 encoding, no more bloated payloads.
The Files API is currently in beta, so all calls go through the client.beta namespace.
Upload a File
Install the SDK and set your API key:
| |
Upload a PDF:
| |
The response gives you a file object with an id field – that’s what you’ll use everywhere else. The upload supports PDFs (application/pdf), plain text (text/plain), and images (image/jpeg, image/png, image/gif, image/webp).
You can also upload from a pathlib.Path directly:
| |
Reference Files in Messages
Once a file is uploaded, pass its file_id in a document content block instead of base64 data:
| |
The source.type is "file" (not "base64" like the standard PDF approach). You can optionally add title and context fields to give Claude extra metadata about the document. Since the API is in beta, you must pass betas=["files-api-2025-04-14"] to client.beta.messages.create.
For images, use an image block instead of document:
| |
Process Multiple Documents in One Request
You can stack multiple file references in a single message. This is perfect for comparison tasks, multi-document summaries, or cross-referencing.
| |
The title field on each document block helps Claude distinguish between the files when generating its response. Always set it when sending multiple documents.
Extract Structured Data from Uploaded Documents
Combining the Files API with a structured extraction prompt gives you a clean pipeline for pulling data out of invoices, contracts, or any document with repeatable structure.
| |
Because the file is already uploaded, you can re-run extraction with different prompts without re-uploading. That’s the real win – iterate on your prompt without paying the upload cost each time.
Enable Citations on Uploaded Files
You can enable citations to get source references back to specific parts of the document:
| |
When citations are enabled, response content blocks will include references pointing back to the specific pages and text spans in the source document.
File Lifecycle Management
List All Files
| |
Get File Metadata
| |
Delete a File
| |
Deleted files cannot be recovered. Any in-progress Messages API calls using the file will still work, but new requests referencing that file_id will fail.
Download Files
You can download files that were created by the code execution tool or skills (not files you uploaded yourself):
| |
Storage Limits and Billing
A few things to keep in mind:
- Max file size: 500 MB per file
- Total storage: 100 GB per organization
- File operations are free – uploading, listing, deleting cost nothing
- Token billing applies when you reference files in Messages requests (charged as input tokens)
- Rate limit: roughly 100 file API requests per minute during the beta
- Files are scoped to your workspace – any API key in the same workspace can access them
Common Errors and Fixes
File not found (404) – The file_id doesn’t exist or belongs to a different workspace. Double-check the ID and make sure you’re using the same API key (or one in the same workspace) that uploaded the file.
Invalid file type (400) – You’re using the wrong content block type. PDFs and text files go in document blocks. Images go in image blocks. Mixing them up (putting a JPEG in a document block) triggers this error.
Exceeds context window size (400) – The file’s content is too large for the model’s context window. A 500 MB plain text file will blow past any model’s limit. Split large text files into chunks before uploading.
File too large (413) – File exceeds the 500 MB upload limit. Compress or split the file.
Storage limit exceeded (403) – Your organization hit the 100 GB cap. Delete old files with client.beta.files.delete() to free up space.
Missing beta header – If you call client.files.create() instead of client.beta.files.upload(), you’ll get an error. The Files API lives under the beta namespace. All file operations must go through client.beta.files.*, and messages referencing files must use client.beta.messages.create() with betas=["files-api-2025-04-14"].
Invalid filename (400) – Filenames must be 1-255 characters and can’t contain <, >, :, ", |, ?, *, \, /, or Unicode control characters (0-31). Rename the file before uploading.
Related Guides
- How to Use the Anthropic Token Counting API for Cost Estimation
- How to Use the Anthropic PDF Processing API for Document Analysis
- How to Use the Anthropic Python SDK for Claude
- How to Use the Anthropic Multi-Turn Conversation API with Tool Use
- How to Use Claude’s Model Context Protocol (MCP)
- How to Use the Anthropic Prompt Caching API with Context Blocks
- How to Use the Anthropic Tool Use API for Agentic Workflows
- How to Use the Cerebras API for Fast LLM Inference
- How to Use the Google Vertex AI Gemini API for Multimodal Tasks
- How to Use the Anthropic Claude Vision API for Image Understanding