Files
modelux proxies the Anthropic Files API (/v1/files/*) as an
authenticated thin passthrough. Upload PDFs / images / text once, then
reference them by file_id from /anthropic/v1/messages content
blocks instead of inlining base64 every turn.
POST /anthropic/v1/files multipart upload
GET /anthropic/v1/files list (limit / before_id / after_id)
GET /anthropic/v1/files/{id} metadata
GET /anthropic/v1/files/{id}/content download bytes (API-generated files only)
DELETE /anthropic/v1/files/{id}
Beta header
The Files API is currently a beta on Anthropic’s side. The proxy
forwards your anthropic-beta header verbatim — the SDK’s beta-tag
declaration reaches the upstream as-is, so the proxy doesn’t have to
track which tag is current:
curl https://api.modelux.ai/anthropic/v1/files \
-H "Authorization: Bearer mlx_sk_..." \
-H "anthropic-beta: files-api-2025-04-14" \
-F "file=@report.pdf"
The official Anthropic SDKs set this header automatically when you opt into the beta on the client.
Upload
multipart/form-data with a single file part. The proxy buffers
the body once before forwarding (Anthropic’s upload endpoint
requires Content-Length and doesn’t accept chunked transfer
encoding):
from anthropic import Anthropic
client = Anthropic(
base_url="https://api.modelux.ai/anthropic",
api_key="mlx_sk_...",
default_headers={"anthropic-beta": "files-api-2025-04-14"},
)
with open("report.pdf", "rb") as f:
file = client.beta.files.upload(file=f)
print(file.id) # file_011...
Response shape:
{
"id": "file_011...",
"type": "file",
"filename": "report.pdf",
"mime_type": "application/pdf",
"size_bytes": 102400,
"created_at": "2026-04-16T..."
}
Reference from messages
Once uploaded, use the file id in a content block. The standard
pattern is a document block on a user message:
{
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"messages": [{
"role": "user",
"content": [
{
"type": "document",
"source": {"type": "file", "file_id": "file_011..."}
},
{"type": "text", "text": "Summarize the executive summary section."}
]
}]
}
Same pattern for image inputs — {"type":"image","source":{"type":"file","file_id":"..."}}.
Retrieve / list / delete
Standard CRUD shapes:
# Metadata
curl https://api.modelux.ai/anthropic/v1/files/file_011... \
-H "Authorization: Bearer mlx_sk_..." \
-H "anthropic-beta: files-api-2025-04-14"
# List with pagination
curl "https://api.modelux.ai/anthropic/v1/files?limit=20&after_id=file_011..." \
-H "Authorization: Bearer mlx_sk_..." \
-H "anthropic-beta: files-api-2025-04-14"
# Delete
curl -X DELETE https://api.modelux.ai/anthropic/v1/files/file_011... \
-H "Authorization: Bearer mlx_sk_..." \
-H "anthropic-beta: files-api-2025-04-14"
Download
GET /anthropic/v1/files/{id}/content
The proxy streams the upstream body chunk-by-chunk via io.Copy
(Content-Type preserved) — works for arbitrarily large files without
buffering them in proxy memory.
Anthropic restriction: the download endpoint is limited to
API-GENERATED files — for example, files produced by computer-use
tool calls. User-uploaded files (the ones you POST’d) come back from
the upstream with 400 invalid_request_error: File is not downloadable. The proxy passes that error envelope through
verbatim. Use the file id for in-message references instead.
BYOK
X-Modelux-Provider-Key: sk-ant-... overrides the org’s stored
Anthropic credential for this call. Same precedence as messages /
batches.
Observability
Each endpoint logs to ClickHouse with a distinct request_type:
file_uploadfile_listfile_retrievefile_downloadfile_delete
Same dashboard breakdowns work for both Anthropic and OpenAI files (the request_type names are shared).
See also
- Messages (Anthropic shape) — referencing files from content blocks
- Message batches (Anthropic) — async batches of message requests
- Batches & files (OpenAI) — the OpenAI equivalent
- Capability matrix — what’s supported where