files changedbuild-with-claude/files
Nearest release: v2.1.232, published 7 hours before this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
## Compatibility ## File type support ## How the Files API works ## How to use the Files API ### Uploading a file ### Using a file in messages ### File types and content blocks #### Document blocks #### Image blocks #### Container upload blocks ### Working with other file formats ### Managing files #### List files #### Get file metadata #### Delete a file ### Downloading a file ## File storage and limits ### Storage limits ### File lifecycle ## Error handling ## Usage and billing ### Rate limits ## Next steps
The whole hunk
1048 lines, first recordedThe first capture of this source. The page was already there, and this is what it said.
---
title: Files API
url: https://platform.claude.com/docs/en/build-with-claude/files
description: Upload files once, reference them by file_id in Messages requests, and download outputs created by skills or the code execution tool.
---
## Compatibility
- Status: Beta
- [Beta header](https://platform.claude.com/docs/en/api/beta-headers): `files-api-2025-04-14`
- [ZDR](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention): not eligible
- Platforms: Claude API (beta), Claude Platform on AWS (beta), Microsoft Foundry (beta) [1]; not available on Amazon Bedrock, Google Cloud
1. On [Microsoft Foundry](https://platform.claude.com/docs/en/build-with-claude/claude-in-microsoft-foundry), the Files API requires a [Hosted on Anthropic deployment](https://platform.claude.com/docs/en/build-with-claude/claude-in-microsoft-foundry#additional-features-not-supported-when-hosted-on-azure).
The Files API lets you upload and manage files to use with the Claude API without re-uploading content with each request. This is particularly useful when using the [code execution tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool) to provide inputs (for example, datasets and documents) and then download outputs (for example, charts). You can [explore the API reference directly](https://platform.claude.com/docs/en/api/beta/files/upload), in addition to this guide.
<Note>
Reach out through the [feedback form](https://forms.gle/tisHyierGwgN4DUE9) to share your experience with the Files API.
</Note>
## File type support
Referencing a `file_id` in a Messages request is supported on all models that support the given file type. [Images](https://platform.claude.com/docs/en/build-with-claude/vision) are supported on all current Claude models. For [PDFs](https://platform.claude.com/docs/en/build-with-claude/pdf-support) and [other file types with the code execution tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#model-compatibility), see the linked pages for model support.
## How the Files API works
The Files API provides a create-once, use-many-times approach for working with files:
* **Upload files** to Anthropic's secure storage and receive a unique `file_id`
* **Download files** that are created by skills or the code execution tool
* **Reference files** in [Messages](https://platform.claude.com/docs/en/api/messages/create) requests using the `file_id` instead of re-uploading content
* **Manage your files** with list, retrieve, and delete operations
<Warning id="workspace-scoped-access">
**Uploaded files are accessible to your entire workspace, not scoped to an end user, conversation, or session.** Any API key in the same workspace can access any file uploaded there, and all of your keys share your organization's Default Workspace unless you have assigned them to separate [workspaces](https://platform.claude.com/docs/en/manage-claude/workspaces#api-keys-and-resource-scoping). Never accept `file_id` values from end users or other untrusted sources: a user-supplied file ID would let one user of your application read content that another user uploaded. Treat file IDs as server-side references, and keep the mapping between your users and their files in your application.
</Warning>
## How to use the Files API
<Note>
To use the Files API, you'll need to include the beta feature header: `anthropic-beta: files-api-2025-04-14`. The SDKs add this header automatically when you call methods on the `beta.files` namespace, so the SDK examples on this page don't pass it explicitly for file operations. Messages requests that reference a file do need it, which the SDK examples pass through their `betas` parameter.
</Note>
### Uploading a file
Upload a file to be referenced in future API calls:
<CodeGroup>
```bash cURL
FILE_ID=$(curl -X POST https://api.anthropic.com/v1/files \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: files-api-2025-04-14" \
-F "file=@/path/to/document.pdf" | jq -r '.id')
echo "$FILE_ID"
```
```bash CLI
FILE_ID=$(ant beta:files upload \
--file /path/to/document.pdf \
--transform id \
--raw-output)
echo "$FILE_ID"
```
```python Python
uploaded = client.beta.files.upload(
file=("document.pdf", open("/path/to/document.pdf", "rb"), "application/pdf"),
)
file_id = uploaded.id
print(file_id)
```
```typescript TypeScript
const uploaded = await client.beta.files.upload({
file: await toFile(
fs.createReadStream("/path/to/document.pdf"),
undefined,
{ type: "application/pdf" },
),
});
console.log(uploaded.id);
```
```csharp C#
var uploaded = await client.Beta.Files.Upload(
new FileUploadParams
{
File = new BinaryContent
{
Stream = File.OpenRead("/path/to/document.pdf"),
FileName = "document.pdf",
ContentType = new("application/pdf")
}
});
var fileId = uploaded.ID;
Console.WriteLine(fileId);
```
```go Go
f, err := os.Open("/path/to/document.pdf")
if err != nil {
log.Fatal(err)
}
defer f.Close()
response, err := client.Beta.Files.Upload(context.Background(),
anthropic.BetaFileUploadParams{
File: anthropic.File(f, "document.pdf", "application/pdf"),
})
if err != nil {
log.Fatal(err)
}
fileID := response.ID
fmt.Println(fileID)
```
```java Java
FileMetadata file = client.beta().files().upload(
FileUploadParams.builder()
.file(MultipartField.<InputStream>builder()
.value(Files.newInputStream(Path.of("/path/to/document.pdf")))
.filename("document.pdf")
.contentType("application/pdf")
.build())
.build()
);
String fileId = file.id();
System.out.println(fileId);
```
```php PHP
$file = $client->beta->files->upload(
FileParam::fromResource(fopen('/path/to/document.pdf', 'rb'), contentType: 'application/pdf'),
);
$fileId = $file->id;
echo $fileId;
```
```ruby Ruby
file = client.beta.files.upload(
file: Anthropic::FilePart.new(
Pathname("/path/to/document.pdf"),
content_type: "application/pdf"
)
)
file_id = file.id
puts file_id
```
</CodeGroup>
The response from uploading a file includes:
```json Response
{
"id": "file_011CNha8iCJcU1wXNR6q4V8w",
"type": "file",
"filename": "document.pdf",
"mime_type": "application/pdf",
"size_bytes": 1024000,
"created_at": "2025-01-01T00:00:00Z",
"downloadable": false
}
```
`downloadable` is `false` for files you upload. Only files created by [skills](https://platform.claude.com/docs/en/build-with-claude/skills-guide) or the [code execution tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool) can be downloaded. See [Downloading a file](https://platform.claude.com/docs/en/build-with-claude/files#downloading-a-file).
### Using a file in messages
Once uploaded, reference the file by passing the `id` from the upload response as `file_id`:
<CodeGroup>
```bash cURL
curl -X POST https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: files-api-2025-04-14" \
-H "content-type: application/json" \
-d @- <<EOF
{
"model": "claude-opus-5",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "Please summarize this document for me."
},
{
"type": "document",
"source": {
"type": "file",
"file_id": "$FILE_ID"
}
}
]
}
]
}
EOF
```
```bash CLI
ant beta:messages create --beta files-api-2025-04-14 <<YAML
model: claude-opus-5
max_tokens: 1024
messages:
- role: user
content:
- type: text
text: Please summarize this document for me.
- type: document
source:
type: file
file_id: $FILE_ID
YAML
```
```python Python
response = client.beta.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Please summarize this document for me."},
{
"type": "document",
"source": {
"type": "file",
"file_id": file_id,
},
},
],
}
],
betas=["files-api-2025-04-14"],
)
print(response)
```
```typescript TypeScript
const response = await client.beta.messages.create({
model: "claude-opus-5",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{
type: "text",
text: "Please summarize this document for me.",
},
{
type: "document",
source: {
type: "file",
file_id: uploaded.id,
},
},
],
},
],
betas: ["files-api-2025-04-14"],
});
console.log(response);
```
```csharp C#
var response = await client.Beta.Messages.Create(
new MessageCreateParams
{
Model = Messages::Model.ClaudeOpus5,
MaxTokens = 1024,
Betas = [AnthropicBeta.FilesApi2025_04_14],
Messages =
[
new BetaMessageParam
{
Role = Role.User,
Content = new List<BetaContentBlockParam>
{
new BetaTextBlockParam { Text = "Please summarize this document for me." },
new BetaRequestDocumentBlock
{
Source = new BetaFileDocumentSource { FileID = fileId }
}
}
}
]
});
Cut at 300 lines. The page has the rest.
No line in this hunk matches that.