Claude's Files API: upload once, reuse the file_id
TL;DR
The Files API lets you upload once and use the file_id in every request, and download files created by skills or code execution. File operations are free; content bills as input tokens. Files belong to the workspace, so never accept file_ids from users and separate workspaces per tenant.
Your app answers questions about the same 200-page PDF dozens of times a day, re-sending the whole file as base64 each time. It wastes bandwidth and bloats requests. Claude's Files API lets you upload a file once, get a file_id, and reference it in every later request. It's also how you download files that skills or code execution create (charts, Excel files, slides).
The flow
uploaded = client.files.upload(
file=("contract.pdf", open("contract.pdf", "rb"), "application/pdf"))
client.messages.create(
model="claude-opus-5-5", max_tokens=1024,
messages=[{"role": "user", "content": [
{"type": "text", "text": "Summarise the penalty clauses."},
{"type": "document", "source": {"type": "file", "file_id": uploaded.id}},
]}])
The Files API is out of beta and needs no beta header (the old files-api-2025-04-14 header still works but returns the old response shapes).
File types and content blocks
| File type | Content block | Use |
|---|---|---|
| PDF, plain text | document (citations can be enabled) | Document analysis |
| JPEG, PNG, GIF, WebP | image | Image analysis |
| Datasets, other files | container_upload | Feed into code execution for analysis and charts |
.docx and .xlsx can't go directly into a document block: convert them to text, convert image-heavy .docx to PDF, or send them to code execution via container_upload.
Limits and lifecycle
- Up to 500 MB per file; 1 TB total per organisation.
- Files can't be modified or renamed; to change content, upload a new file and delete the old one.
- Files persist until you delete them, or until
expires_atif you setexpires_in_secondsat upload (1 hour to 90 days). - Only files created by skills or code execution are downloadable (
downloadable: true); files you upload aren't. - Upload, download, list and delete are free; file content used in requests is billed as input tokens. Roughly 500 requests per minute.
The biggest risk: workspace scope
Files are not scoped to an end user, conversation or session. Any API key with workspace access can read every file in it. So:
- Never accept a
file_idfrom users or untrusted sources: a user-supplied ID could let them read another user's file. Keep the user ↔ file mapping in your application. - Multi-tenant apps: the docs recommend one workspace per tenant (up to 100 workspaces per organisation), with workspace-scoped keys.
- Not ZDR-eligible: files are retained until deleted or expired.
How to apply it
- Dev: Upload frequently used documents once and store the
file_idalongside your own records; setexpires_in_secondsfor temporary files. - Tech Lead: Design per-tenant workspaces from the start if you're building a multi-customer product.
- PM: Combine the Files API with the xlsx/pptx skills for an "export report" feature users can download.
Sources & references
- Files API — Claude Docs