Files API (Anthropic Compatible)¶
Route Prefix & Base URL
By default, all Anthropic-compatible routes are prefixed with /anthropic. This means the Files API is available at /anthropic/v1/files instead of /v1/files. You can customize this prefix using the ANTHROPIC_ROUTES_PREFIX configuration variable documented in Operations Configuration.
The curl examples below use a $BASE variable that must include this prefix — set it to your scheme and host followed by ANTHROPIC_ROUTES_PREFIX:
export BASE="https://your-host/anthropic" # <scheme>://<host> + ANTHROPIC_ROUTES_PREFIX
Upload and manage files via an Anthropic-compatible interface. Files are stored in Amazon S3 and can be referenced directly in Messages requests as document or image sources.
-
Simple Upload
Upload any file with a singlemultipart/form-datarequest. Files are immediately available for use in inference. -
Bidirectional Pagination
Traverse your file list in both directions usingafter_idandbefore_idcursors, just like the Anthropic SDK'sPage<T>interface. -
Messages Integration
Reference uploaded files directly in Messages requests as document or image source blocks using"type": "file". -
Content Download
Download raw file bytes at any time via the/contentendpoint.
Available Endpoints¶
| Endpoint | Method | Description | MCP Tool |
|---|---|---|---|
/v1/files |
POST |
Upload a file | anthropic_file |
/v1/files |
GET |
List files with pagination | anthropic_file_list |
/v1/files/{file_id} |
GET |
Retrieve file metadata | anthropic_files_get |
/v1/files/{file_id} |
DELETE |
Delete a file | anthropic_files_delete |
/v1/files/{file_id}/content |
GET |
Download raw file bytes | anthropic_file_content |
Feature Compatibility¶
| Feature | Status | Notes |
|---|---|---|
| Upload | ||
file (multipart) |
Required binary form field | |
file (JSON body) |
Base64, data URI, HTTPS URL, or S3 URI — for MCP / AI agents | |
| Listing | ||
after_id cursor |
Forward cursor: returns files newer than the given ID | |
before_id cursor |
Backward cursor: returns files older than the given ID | |
limit |
1 – 1 000; default 20 | |
| File size cap | No artificial limit; S3 object limit (~5 TB) | |
| Messages integration | "source": {"type": "file", "file_id": "..."} in document/image |
|
downloadable field |
Always true; spec default is false for user-uploaded files |
Legend:
- Supported — Fully compatible with Anthropic API
- Partial — Implemented with minor deviations from spec
- Extra Feature — Enhanced capability beyond Anthropic API
Quick Start¶
Upload a File¶
curl -X POST "$BASE/v1/files" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-beta: files-api-2025-04-14" \
-F "file=@document.pdf;type=application/pdf"
Response:
{
"id": "file_0190c51c7de7455d9b8c2efe27dfbf67",
"type": "file",
"filename": "document.pdf",
"mime_type": "application/pdf",
"size_bytes": 102400,
"created_at": "2025-04-15T12:00:00Z",
"downloadable": true
}
Upload via JSON Body (MCP and AI Agents)¶
When using MCP tools or HTTP clients that cannot construct multipart/form-data requests, pass the file as a base64 string, data URI, HTTPS URL, or S3 URI in a JSON body instead.
Data URI (inline content):
curl -X POST "$BASE/v1/files" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-beta: files-api-2025-04-14" \
-H "Content-Type: application/json" \
-d '{"file": "data:text/plain;base64,SGVsbG8gV29ybGQ="}'
HTTPS URL (server fetches the file):
curl -X POST "$BASE/v1/files" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-beta: files-api-2025-04-14" \
-H "Content-Type: application/json" \
-d '{"file": "https://example.com/document.pdf"}'
All variants return the same FileMetadata response as a multipart upload.
Retrieve Metadata¶
curl "$BASE/v1/files/file_0190c51c7de7455d9b8c2efe27dfbf67" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-beta: files-api-2025-04-14"
List Files¶
# Default (oldest first, up to 20 files)
curl "$BASE/v1/files" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-beta: files-api-2025-04-14"
# Forward pagination: files after a given ID
curl "$BASE/v1/files?after_id=file_0190c51c7de7455d9b8c2efe27dfbf67&limit=20" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-beta: files-api-2025-04-14"
# Backward pagination: files before a given ID
curl "$BASE/v1/files?before_id=file_0190c51c7de7455d9b8c2efe27dfbf67" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-beta: files-api-2025-04-14"
Download Content¶
curl "$BASE/v1/files/file_0190c51c7de7455d9b8c2efe27dfbf67/content" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-beta: files-api-2025-04-14" \
-o downloaded.pdf
Delete a File¶
curl -X DELETE "$BASE/v1/files/file_0190c51c7de7455d9b8c2efe27dfbf67" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-beta: files-api-2025-04-14"
Response:
{
"id": "file_0190c51c7de7455d9b8c2efe27dfbf67",
"type": "file_deleted"
}
Messages Integration¶
Reference an uploaded file inside a POST /v1/messages request as a document or image source:
Document (PDF or other supported format):
curl -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-beta: files-api-2025-04-14" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic.claude-haiku-4-5-20251001-v1:0",
"max_tokens": 512,
"messages": [
{
"role": "user",
"content": [
{
"type": "document",
"source": {
"type": "file",
"file_id": "file_0190c51c7de7455d9b8c2efe27dfbf67"
}
},
{
"type": "text",
"text": "Summarise this document."
}
]
}
]
}'
Image:
curl -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-beta: files-api-2025-04-14" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic.claude-haiku-4-5-20251001-v1:0",
"max_tokens": 256,
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "file",
"file_id": "file_0190c51c7de7455d9b8c2efe27dfbf68"
}
},
{
"type": "text",
"text": "Describe this image."
}
]
}
]
}'
End-to-End Example¶
# 1. Upload a file
FILE_ID=$(curl -s -X POST "$BASE/v1/files" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-beta: files-api-2025-04-14" \
-F "file=@document.pdf;type=application/pdf" | jq -r .id)
echo "Uploaded: $FILE_ID"
# 2. Reference in a message
curl -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-beta: files-api-2025-04-14" \
-H "Content-Type: application/json" \
-d "{
\"model\": \"anthropic.claude-haiku-4-5-20251001-v1:0\",
\"max_tokens\": 512,
\"messages\": [{
\"role\": \"user\",
\"content\": [
{\"type\": \"document\", \"source\": {\"type\": \"file\", \"file_id\": \"$FILE_ID\"}},
{\"type\": \"text\", \"text\": \"What is the key finding in this document?\"}
]
}]
}"
# 3. Cleanup
curl -X DELETE "$BASE/v1/files/$FILE_ID" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-beta: files-api-2025-04-14"
Referencing Uploaded Files via the file-id: URI Scheme¶
The native {"type": "file", "file_id": "..."} source shown above is the Anthropic-compatible way to reference an uploaded file in Messages content blocks. For string-overloaded file fields that already accept URI schemes like s3://, https://, or data: — for example image and document content blocks with source.type url or base64 — this implementation defines an additional project-local URI scheme:
file-id:<file-id>
Project-local URI scheme — file-id:
file-id: is an extension beyond the original Anthropic API, parallel to the existing s3://, https://, and data: schemes already accepted on the same fields. It lets a client upload a file once and reuse it across Messages content blocks (image / document source.url and source.data), as well as the OpenAI-compatible routes — without re-uploading.
- Where accepted: any string-overloaded file field. For Anthropic Messages: image and document content blocks where
source.typeisurl(withsource.url: "file-id:<id>") orbase64(withsource.data: "file-id:<id>"). - Where unchanged: the typed
{"type": "file", "file_id": "..."}source already accepted by the Anthropic API stays exactly as-is — do not wrap those bare IDs infile-id:. - Where rejected: the Files API ingest endpoint (
POST /v1/files) returns 400 forfile-id:inputs, because resolving it there would silently clone an existing file. - Detection: match is case-sensitive (
file-id:, lowercase) with no whitespace stripping; the payload after the prefix must be a valid Files API ID, otherwise the request fails with400 invalid_request_error. A missing or expired file returns404 not_found.
Worked example — send an uploaded image in Messages¶
# 1. Upload the file once.
FILE_ID=$(curl -s -X POST "$BASE/v1/files" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-beta: files-api-2025-04-14" \
-F "file=@chart.png;type=image/png" | jq -r .id)
# 2. Reference it via file-id: in a Messages request.
curl -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"model\": \"anthropic.claude-haiku-4-5-20251001-v1:0\",
\"max_tokens\": 256,
\"messages\": [{
\"role\": \"user\",
\"content\": [
{\"type\": \"text\", \"text\": \"Describe this chart.\"},
{\"type\": \"image\", \"source\": {\"type\": \"url\", \"url\": \"file-id:${FILE_ID}\"}}
]
}]
}"
See the OpenAI Files API documentation for the full list of supported routes — the same scheme works identically across both API surfaces.
Error Reference¶
| HTTP | Cause |
|---|---|
| 400 | Invalid filename characters |
| 404 | File not found or already deleted |
| 503 | AWS_S3_BUCKET is not configured |
Configuration¶
Files are stored in S3 under the prefix configured by AWS_S3_FILES_PREFIX (default: files/). All file IDs are shared across the OpenAI and Anthropic endpoints — a file uploaded via one API can be downloaded or deleted via the other.
Use files across multiple requests without re-uploading. See OpenAI Files API for the OpenAI-compatible equivalent, including expires_after support.