files
build-with-claude/files
History
build-with-claude/files Changed · +2 / -2 lines
* **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. + **Uploaded files are accessible to your entire workspace, not scoped to an end user, conversation, or session.** Any API key with access to a workspace can access any files uploaded to that workspace. Every service account, and every user whose organization role allows API access, can use the Default Workspace in addition to any workspace you add them to, so keep files that must stay separate in their own [workspace](https://platform.claude.com/docs/en/manage-claude/workspaces#api-keys-and-resource-scoping) and access them only with keys scoped to that workspace. 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. If you are building a multi-tenant application on the Files API, create a separate [workspace](https://platform.claude.com/docs/en/manage-claude/workspaces) for each tenant. The workspace is the isolation boundary for files, so a workspace per tenant gives each tenant's data hard isolation from every other tenant. Each organization can have up to 100 workspaces; contact your account team if you need more. </Warning>
### File lifecycle -* Files are scoped to the workspace of the API key that uploaded them. Any API key in the same workspace can reference them; never accept file IDs from untrusted sources (see the [workspace access warning](https://platform.claude.com/docs/en/build-with-claude/files#workspace-scoped-access)) +* Files are scoped to the workspace they were uploaded in. Any request in the same workspace can reference them; never accept file IDs from untrusted sources (see the [workspace access warning](https://platform.claude.com/docs/en/build-with-claude/files#workspace-scoped-access)) * Files cannot be modified or renamed after upload. To change a file's content, upload a new file and delete the old one * Files persist until you delete them with the `DELETE /v1/files/{file_id}` endpoint or they reach their `expires_at` * Deleted files cannot be recovered
build-with-claude/files Changed · +16 / -25 lines
``` ```php PHP - // The PHP SDK exposes the Files API under the beta namespace; field names can differ from other SDKs. - $file = $client->beta->files->upload( - FileParam::fromResource(fopen('/path/to/document.pdf', 'rb'), contentType: 'application/pdf'), + $file = $client->files->upload( + file: FileParam::fromResource(fopen('/path/to/document.pdf', 'rb'), contentType: 'application/pdf'), ); $fileId = $file->id;
``` ```php PHP - // The PHP SDK supports file_id document and image sources only through $client->beta->messages with the files beta. - $response = $client->beta->messages->create( + $response = $client->messages->create( maxTokens: 1024, messages: [ [
'type' => 'document', 'source' => [ 'type' => 'file', - 'file_id' => $fileId - ] - ] - ] - ] + 'fileID' => $fileId, + ], + ], + ], + ], ], model: 'claude-opus-5', - betas: ['files-api-2025-04-14'], ); - print_r($response); + echo $response; ``` ```ruby Ruby
``` ```bash CLI - ant files list \ - --max-items 10 + ant files list --max-items 10 ``` ```python Python
``` ```php PHP - // The PHP SDK exposes the Files API under the beta namespace; field names can differ from other SDKs. - // list() paginates with afterID, beforeID, and limit; page and ids[] are not parameters here. $client = new Client(); - $files = $client->beta->files->list(); + $files = $client->files->list(); echo $files; ```
``` ```php PHP - // The PHP SDK exposes the Files API under the beta namespace; field names can differ from other SDKs. - $file = $client->beta->files->retrieveMetadata($fileId); + $file = $client->files->retrieveMetadata($fileId); echo $file; ```
``` ```php PHP - // The PHP SDK exposes the Files API under the beta namespace; field names can differ from other SDKs. - $client->beta->files->delete($fileId); + $client->files->delete($fileId); ``` ```ruby Ruby
``` ```php PHP - // The PHP SDK exposes the Files API under the beta namespace; field names can differ from other SDKs. - $fileContent = $client->beta->files->download($fileId); + $fileContent = $client->files->download($fileId); - file_put_contents("downloaded_file.txt", $fileContent); + file_put_contents('downloaded_file.txt', $fileContent); ``` ```ruby Ruby
build-with-claude/files Changed · +7 / -6 lines
## How to use the Files API -<Note> - Requests to the Files API endpoints (`/v1/files`) don't need a beta header. Neither do Messages or Message Batches requests that reference an uploaded file as a `document` or `image` source, or in a `container_upload` block for the code execution tool. Requests that still send the `anthropic-beta: files-api-2025-04-14` header keep working. On Files API requests, that header also selects the earlier response format: the list endpoint paginates with `before_id` and `after_id`, returns `has_more`, `first_id`, and `last_id` instead of `next_page`, and rejects the `page` and `ids[]` parameters as unknown fields. File objects returned under the header omit `expires_at` instead of returning `null` when no expiration is set. To use `page` and `ids[]` as described under [List files](https://platform.claude.com/docs/en/build-with-claude/files#list-files), send the request without the header. The PHP tabs on this page still call the SDK's `beta` namespace, which sends the header, so their list output uses the earlier format. -</Note> - ### Uploading a file Upload a file to be referenced in future API calls:
``` ```php PHP + // The PHP SDK exposes the Files API under the beta namespace; field names can differ from other SDKs. $file = $client->beta->files->upload( FileParam::fromResource(fopen('/path/to/document.pdf', 'rb'), contentType: 'application/pdf'), );
``` ```php PHP + // The PHP SDK supports file_id document and image sources only through $client->beta->messages with the files beta. $response = $client->beta->messages->create( maxTokens: 1024, messages: [
``` ```php PHP + // The PHP SDK exposes the Files API under the beta namespace; field names can differ from other SDKs. + // list() paginates with afterID, beforeID, and limit; page and ids[] are not parameters here. $client = new Client(); $files = $client->beta->files->list();
To check a known set of files in one request instead of paging, pass up to 100 file IDs as `ids[]` query parameters. An `ids[]` request always returns a single page (`next_page` is `null`), and any ID that does not resolve to a file in your workspace is silently omitted from `data`; compare the returned IDs against the requested IDs to detect misses. `ids[]` cannot be combined with `page` or `limit`. -The `page` parameter, the `next_page` cursor, and the `ids[]` filter apply to requests sent without the `anthropic-beta: files-api-2025-04-14` header. Requests that send the header receive the earlier list format described in the note under [How to use the Files API](https://platform.claude.com/docs/en/build-with-claude/files#how-to-use-the-files-api). - #### Get file metadata Retrieve information about a specific file:
``` ```php PHP + // The PHP SDK exposes the Files API under the beta namespace; field names can differ from other SDKs. $file = $client->beta->files->retrieveMetadata($fileId); echo $file; ```
``` ```php PHP + // The PHP SDK exposes the Files API under the beta namespace; field names can differ from other SDKs. $client->beta->files->delete($fileId); ```
``` ```php PHP + // The PHP SDK exposes the Files API under the beta namespace; field names can differ from other SDKs. $fileContent = $client->beta->files->download($fileId); file_put_contents("downloaded_file.txt", $fileContent);
build-with-claude/files Changed · +66 / -95 lines
- Platforms: Claude API, 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. +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/files/upload), in addition to this guide. ## File type support
## How to use the Files API <Note> - Requests to the Files API endpoints (`/v1/files`) don't need a beta header, and neither do Messages or Message Batches requests that reference an uploaded file. Two things to know about the `anthropic-beta: files-api-2025-04-14` header the examples on this page still send: - - * **Referencing a file from the Messages API.** Requests that use an uploaded file as a `document` or `image` source, or in a `container_upload` block for the code execution tool, work with or without the header. The SDK examples on this page still pass it through their `betas` parameter, which continues to work. - * **Sending the header on Files API requests.** The SDK `beta.files` methods and the CLI `ant beta:files` commands add the header automatically, and the cURL examples on this page include it. Those requests keep working and return the earlier response format: the list endpoint paginates with `before_id` and `after_id`, returns `has_more`, `first_id`, and `last_id` instead of `next_page`, and rejects the `page` and `ids[]` parameters as unknown fields. File objects returned under the header omit `expires_at` instead of returning `null` when no expiration is set. To use `page` and `ids[]` as described under [List files](https://platform.claude.com/docs/en/build-with-claude/files#list-files), send the request without the beta header. + Requests to the Files API endpoints (`/v1/files`) don't need a beta header. Neither do Messages or Message Batches requests that reference an uploaded file as a `document` or `image` source, or in a `container_upload` block for the code execution tool. Requests that still send the `anthropic-beta: files-api-2025-04-14` header keep working. On Files API requests, that header also selects the earlier response format: the list endpoint paginates with `before_id` and `after_id`, returns `has_more`, `first_id`, and `last_id` instead of `next_page`, and rejects the `page` and `ids[]` parameters as unknown fields. File objects returned under the header omit `expires_at` instead of returning `null` when no expiration is set. To use `page` and `ids[]` as described under [List files](https://platform.claude.com/docs/en/build-with-claude/files#list-files), send the request without the header. The PHP tabs on this page still call the SDK's `beta` namespace, which sends the header, so their list output uses the earlier format. </Note> ### Uploading a file
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_ID=$(ant files upload \ --file /path/to/document.pdf \ --transform id \ --raw-output)
``` ```python Python - uploaded = client.beta.files.upload( + uploaded = client.files.upload( file=("document.pdf", open("/path/to/document.pdf", "rb"), "application/pdf"), ) file_id = uploaded.id
``` ```typescript TypeScript - const uploaded = await client.beta.files.upload({ + const uploaded = await client.files.upload({ file: await toFile( fs.createReadStream("/path/to/document.pdf"), undefined,
``` ```csharp C# - var uploaded = await client.Beta.Files.Upload( + var uploaded = await client.Files.Upload( new FileUploadParams { File = new BinaryContent
} defer f.Close() - response, err := client.Beta.Files.Upload(context.Background(), - anthropic.BetaFileUploadParams{ + response, err := client.Files.Upload(context.Background(), + anthropic.FileUploadParams{ File: anthropic.File(f, "document.pdf", "application/pdf"), }) if err != nil {
``` ```java Java - FileMetadata file = client.beta().files().upload( + FileMetadata file = client.files().upload( FileUploadParams.builder() .file(MultipartField.<InputStream>builder() .value(Files.newInputStream(Path.of("/path/to/document.pdf")))
``` ```ruby Ruby - file = client.beta.files.upload( + file = client.files.upload( file: Anthropic::FilePart.new( Pathname("/path/to/document.pdf"), content_type: "application/pdf"
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 {
``` ```bash CLI - ant beta:messages create --beta files-api-2025-04-14 <<YAML + ant messages create <<YAML model: claude-opus-5 max_tokens: 1024 messages:
``` ```python Python - response = client.beta.messages.create( + response = client.messages.create( model="claude-opus-5", max_tokens=1024, messages=[
], } ], - betas=["files-api-2025-04-14"], ) print(response) ``` ```typescript TypeScript - const response = await client.beta.messages.create({ + const response = await client.messages.create({ model: "claude-opus-5", max_tokens: 1024, messages: [
], }, ], - betas: ["files-api-2025-04-14"], }); console.log(response);
``` ```csharp C# - var response = await client.Beta.Messages.Create( + var response = await client.Messages.Create( new MessageCreateParams { - Model = Messages::Model.ClaudeOpus5, + Model = Model.ClaudeOpus5, MaxTokens = 1024, - Betas = [AnthropicBeta.FilesApi2025_04_14], Messages = [ - new BetaMessageParam + new MessageParam { Role = Role.User, - Content = new List<BetaContentBlockParam> + Content = new List<ContentBlockParam> { - new BetaTextBlockParam { Text = "Please summarize this document for me." }, - new BetaRequestDocumentBlock + new TextBlockParam { Text = "Please summarize this document for me." }, + new DocumentBlockParam { - Source = new BetaFileDocumentSource { FileID = fileId } + Source = new FileDocumentSource { FileID = fileId } } } }
``` ```go Go - msg, err := client.Beta.Messages.New(context.Background(), - anthropic.BetaMessageNewParams{ + msg, err := client.Messages.New(context.Background(), + anthropic.MessageNewParams{ Model: anthropic.ModelClaudeOpus5, MaxTokens: 1024, - Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaFilesAPI2025_04_14}, - Messages: []anthropic.BetaMessageParam{ - anthropic.NewBetaUserMessage( - anthropic.NewBetaTextBlock("Please summarize this document for me."), - anthropic.NewBetaDocumentBlock(anthropic.BetaFileDocumentSourceParam{ + Messages: []anthropic.MessageParam{ + anthropic.NewUserMessage( + anthropic.NewTextBlock("Please summarize this document for me."), + anthropic.NewDocumentBlock(anthropic.FileDocumentSourceParam{ FileID: fileID, }), ),
```java Java MessageCreateParams params = MessageCreateParams.builder() .model(Model.CLAUDE_OPUS_5) - .addBeta("files-api-2025-04-14") .maxTokens(1024) - .addUserMessageOfBetaContentBlockParams(List.of( - BetaContentBlockParam.ofText(BetaTextBlockParam.builder() + .addUserMessageOfBlockParams(List.of( + ContentBlockParam.ofText(TextBlockParam.builder() .text("Please summarize this document for me.") .build()), - BetaContentBlockParam.ofDocument(BetaRequestDocumentBlock.builder() - .source(BetaFileDocumentSource.builder() - .fileId(fileId) - .build()) + ContentBlockParam.ofDocument(DocumentBlockParam.builder() + .fileSource(fileId) .build()) )) .build(); - BetaMessage message = client.beta().messages().create(params); + Message message = client.messages().create(params); System.out.println(message); ```
``` ```ruby Ruby - response = client.beta.messages.create( + response = client.messages.create( model: "claude-opus-5", max_tokens: 1024, - betas: ["files-api-2025-04-14"], messages: [ { role: "user",
#### List files -Retrieve a list of your uploaded files. The endpoint is paginated: each request returns up to `limit` files (20 by default, and at most 1,000), and the response's `next_page` cursor fetches the next page when passed back as the `page` parameter. Files are ordered newest first. See the [List Files API reference](https://platform.claude.com/docs/en/api/beta/files/list). The SDKs return the first page and provide auto-pagination helpers. The CLI example bounds the total with `--max-items`: +Retrieve a list of your uploaded files. The endpoint is paginated: each request returns up to `limit` files (20 by default, and at most 1,000), and the response's `next_page` cursor fetches the next page when passed back as the `page` parameter. Files are ordered newest first. See the [List Files API reference](https://platform.claude.com/docs/en/api/files/list). The SDKs return the first page and provide auto-pagination helpers. The CLI example bounds the total with `--max-items`: <CodeGroup> ```bash cURL curl 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" + -H "anthropic-version: 2023-06-01" ``` ```bash CLI - ant beta:files list \ + ant files list \ --max-items 10 ``` ```python Python client = anthropic.Anthropic() - files = client.beta.files.list() + files = client.files.list() print(files) ``` ```typescript TypeScript const client = new Anthropic(); - const files = await client.beta.files.list(); + const files = await client.files.list(); console.log(files); ```
```csharp C# AnthropicClient client = new(); - var files = await client.Beta.Files.List(); + var files = await client.Files.List(); Console.WriteLine(files); ```
```go Go client := anthropic.NewClient() - files, err := client.Beta.Files.List(context.TODO(), anthropic.BetaFileListParams{}) + files, err := client.Files.List(context.TODO(), anthropic.FileListParams{}) if err != nil { log.Fatal(err) }
``` ```java Java - import com.anthropic.models.beta.files.FileListPage; + import com.anthropic.models.files.FileListPage; // ... void main() { AnthropicClient client = AnthropicOkHttpClient.fromEnv(); - FileListPage files = client.beta().files().list(); + FileListPage files = client.files().list(); System.out.println(files); } ```
```ruby Ruby client = Anthropic::Client.new - files = client.beta.files.list + files = client.files.list puts files ``` </CodeGroup>
To check a known set of files in one request instead of paging, pass up to 100 file IDs as `ids[]` query parameters. An `ids[]` request always returns a single page (`next_page` is `null`), and any ID that does not resolve to a file in your workspace is silently omitted from `data`; compare the returned IDs against the requested IDs to detect misses. `ids[]` cannot be combined with `page` or `limit`. -The `page` parameter, the `next_page` cursor, and the `ids[]` filter apply to requests sent without the `anthropic-beta: files-api-2025-04-14` header. The preceding examples send it (the SDKs and CLI add it for `beta.files` calls), so they receive the earlier list format described in the note under [How to use the Files API](https://platform.claude.com/docs/en/build-with-claude/files#how-to-use-the-files-api). +The `page` parameter, the `next_page` cursor, and the `ids[]` filter apply to requests sent without the `anthropic-beta: files-api-2025-04-14` header. Requests that send the header receive the earlier list format described in the note under [How to use the Files API](https://platform.claude.com/docs/en/build-with-claude/files#how-to-use-the-files-api). #### Get file metadata
```bash cURL curl "https://api.anthropic.com/v1/files/$FILE_ID" \ -H "x-api-key: $ANTHROPIC_API_KEY" \ - -H "anthropic-version: 2023-06-01" \ - -H "anthropic-beta: files-api-2025-04-14" + -H "anthropic-version: 2023-06-01" ``` ```bash CLI - ant beta:files retrieve-metadata \ + ant files retrieve-metadata \ --file-id "$FILE_ID" ``` ```python Python - file = client.beta.files.retrieve_metadata(file_id) + file = client.files.retrieve_metadata(file_id) print(file) ``` ```typescript TypeScript - const file = await client.beta.files.retrieveMetadata(uploaded.id); + const file = await client.files.retrieveMetadata(uploaded.id); console.log(file); ``` ```csharp C# - var file = await client.Beta.Files.RetrieveMetadata(fileId); + var file = await client.Files.RetrieveMetadata(fileId); Console.WriteLine(file); ``` ```go Go - metadata, err := client.Beta.Files.GetMetadata( - context.TODO(), - fileID, - anthropic.BetaFileGetMetadataParams{}, - ) + metadata, err := client.Files.GetMetadata(context.TODO(), fileID) if err != nil { log.Fatal(err) }
``` ```java Java - FileMetadata metadata = client.beta().files().retrieveMetadata(fileId); + FileMetadata metadata = client.files().retrieveMetadata(fileId); System.out.println(metadata); ```
``` ```ruby Ruby - file = client.beta.files.retrieve_metadata(file_id) + file = client.files.retrieve_metadata(file_id) puts file ``` </CodeGroup>
```bash cURL curl -X DELETE "https://api.anthropic.com/v1/files/$FILE_ID" \ -H "x-api-key: $ANTHROPIC_API_KEY" \ - -H "anthropic-version: 2023-06-01" \ - -H "anthropic-beta: files-api-2025-04-14" + -H "anthropic-version: 2023-06-01" ``` ```bash CLI - ant beta:files delete \ + ant files delete \ --file-id "$FILE_ID" ``` ```python Python - client.beta.files.delete(file_id) + client.files.delete(file_id) ``` ```typescript TypeScript - await client.beta.files.delete(uploaded.id); + await client.files.delete(uploaded.id); ``` ```csharp C# - await client.Beta.Files.Delete(fileId); + await client.Files.Delete(fileId); ``` ```go Go - _, err = client.Beta.Files.Delete( - context.TODO(), - fileID, - anthropic.BetaFileDeleteParams{}, - ) + _, err = client.Files.Delete(context.TODO(), fileID) if err != nil { log.Fatal(err) }
``` ```java Java - client.beta().files().delete(fileId); + client.files().delete(fileId); ``` ```php PHP
``` ```ruby Ruby - client.beta.files.delete(file_id) + client.files.delete(file_id) ``` </CodeGroup>
curl -X GET "https://api.anthropic.com/v1/files/$FILE_ID/content" \ -H "x-api-key: $ANTHROPIC_API_KEY" \ -H "anthropic-version: 2023-06-01" \ - -H "anthropic-beta: files-api-2025-04-14" \ --output downloaded_file.txt ``` ```bash CLI - ant beta:files download \ + ant files download \ --file-id "$FILE_ID" \ --output downloaded_file.txt ``` ```python Python - file_content = client.beta.files.download(file_id) + file_content = client.files.download(file_id) file_content.write_to_file("downloaded_file.txt") ``` ```typescript TypeScript - const content = await client.beta.files.download(uploaded.id); + const content = await client.files.download(uploaded.id); const bytes = Buffer.from(await content.arrayBuffer()); await fsp.writeFile("downloaded_file.txt", bytes);
``` ```csharp C# - using var fileContent = await client.Beta.Files.Download(fileId); + using var fileContent = await client.Files.Download(fileId); await using var source = await fileContent.ReadAsStream(); await using var destination = File.Create("downloaded_file.txt"); await source.CopyToAsync(destination);
```go Go func downloadFile(client anthropic.Client, fileID string) error { - resp, err := client.Beta.Files.Download( - context.TODO(), - fileID, - anthropic.BetaFileDownloadParams{}, - ) + resp, err := client.Files.Download(context.TODO(), fileID) if err != nil { return err }
``` ```java Java - try (HttpResponse response = client.beta().files().download(fileId)) { + try (HttpResponse response = client.files().download(fileId)) { try (InputStream body = response.body()) { Files.copy(body, Path.of("downloaded_file.txt"), StandardCopyOption.REPLACE_EXISTING);
``` ```ruby Ruby - file_content = client.beta.files.download(file_id) + file_content = client.files.download(file_id) File.binwrite("downloaded_file.txt", file_content.read) ```
build-with-claude/files Changed · +30 / -11 lines
### File expiration
--- ## 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 +- Platforms: Claude API, 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 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. + Requests to the Files API endpoints (`/v1/files`) don't need a beta header, and neither do Messages or Message Batches requests that reference an uploaded file. Two things to know about the `anthropic-beta: files-api-2025-04-14` header the examples on this page still send: + + * **Referencing a file from the Messages API.** Requests that use an uploaded file as a `document` or `image` source, or in a `container_upload` block for the code execution tool, work with or without the header. The SDK examples on this page still pass it through their `betas` parameter, which continues to work. + * **Sending the header on Files API requests.** The SDK `beta.files` methods and the CLI `ant beta:files` commands add the header automatically, and the cURL examples on this page include it. Those requests keep working and return the earlier response format: the list endpoint paginates with `before_id` and `after_id`, returns `has_more`, `first_id`, and `last_id` instead of `next_page`, and rejects the `page` and `ids[]` parameters as unknown fields. File objects returned under the header omit `expires_at` instead of returning `null` when no expiration is set. To use `page` and `ids[]` as described under [List files](https://platform.claude.com/docs/en/build-with-claude/files#list-files), send the request without the beta header. </Note> ### Uploading a file
"mime_type": "application/pdf", "size_bytes": 1024000, "created_at": "2025-01-01T00:00:00Z", - "downloadable": false + "downloadable": false, + "expires_at": null } ```
#### List files -Retrieve a list of your uploaded files. The endpoint is paginated: each request returns up to `limit` files (20 by default), and the `before_id` and `after_id` parameters fetch the adjacent page. See the [List Files API reference](https://platform.claude.com/docs/en/api/beta/files/list). The SDKs return the first page and provide auto-pagination helpers. The CLI example bounds the total with `--max-items`: +Retrieve a list of your uploaded files. The endpoint is paginated: each request returns up to `limit` files (20 by default, and at most 1,000), and the response's `next_page` cursor fetches the next page when passed back as the `page` parameter. Files are ordered newest first. See the [List Files API reference](https://platform.claude.com/docs/en/api/beta/files/list). The SDKs return the first page and provide auto-pagination helpers. The CLI example bounds the total with `--max-items`: <CodeGroup> ```bash cURL
``` </CodeGroup> +To check a known set of files in one request instead of paging, pass up to 100 file IDs as `ids[]` query parameters. An `ids[]` request always returns a single page (`next_page` is `null`), and any ID that does not resolve to a file in your workspace is silently omitted from `data`; compare the returned IDs against the requested IDs to detect misses. `ids[]` cannot be combined with `page` or `limit`. + +The `page` parameter, the `next_page` cursor, and the `ids[]` filter apply to requests sent without the `anthropic-beta: files-api-2025-04-14` header. The preceding examples send it (the SDKs and CLI add it for `beta.files` calls), so they receive the earlier list format described in the note under [How to use the Files API](https://platform.claude.com/docs/en/build-with-claude/files#how-to-use-the-files-api). + #### Get file metadata Retrieve information about a specific file:
* Files are scoped to the workspace of the API key that uploaded them. Any API key in the same workspace can reference them; never accept file IDs from untrusted sources (see the [workspace access warning](https://platform.claude.com/docs/en/build-with-claude/files#workspace-scoped-access)) * Files cannot be modified or renamed after upload. To change a file's content, upload a new file and delete the old one -* Files persist until you delete them with the `DELETE /v1/files/{file_id}` endpoint +* Files persist until you delete them with the `DELETE /v1/files/{file_id}` endpoint or they reach their `expires_at` * Deleted files cannot be recovered * Files are inaccessible through the API shortly after deletion, but they may persist in active Messages API calls and associated tool uses * Files that users delete will be deleted in accordance with Anthropic's [data retention policy](https://privacy.claude.com/en/articles/7996866-how-long-do-you-store-my-organization-s-data). For ZDR eligibility across all features, see [API and data retention](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention) + +### File expiration + +To have a file expire automatically, include an `expires_in_seconds` form field when you upload it. The value is an integer number of seconds between 3,600 (1 hour) and 7,776,000 (90 days). The resulting `expires_at` timestamp (RFC 3339) appears on every file response and is `null` for files uploaded without an expiration. Expiration is set once at upload and cannot be changed. + +When a file reaches its `expires_at`: + +* Downloading its content (`GET /v1/files/{file_id}/content`) returns a 404 error +* A Messages request that references the file fails before inference +* Its metadata (`GET /v1/files/{file_id}`) remains readable for up to 30 days, with `expires_at` in the past +* It continues to appear in list responses during that window; compare `expires_at` to the current time to filter expired files + +Deleting an expired file with `DELETE /v1/files/{file_id}` removes its metadata immediately instead of waiting for the 30-day window to elapse. + +<Note> + Expiration is a lifecycle feature, not a guaranteed-deletion control. After `expires_at`, file content is no longer retrievable through the API and is released from your storage quota; the underlying content may be retained for a limited period thereafter for safety review before permanent deletion, and file metadata remains visible for up to 30 days after expiration. To remove a file before its scheduled expiration, use `DELETE /v1/files/{file_id}`. +</Note> ### Audit logging
build-with-claude/files Changed · +9 / -6 lines
### Audit logging
<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. + + If you are building a multi-tenant application on the Files API, create a separate [workspace](https://platform.claude.com/docs/en/manage-claude/workspaces) for each tenant. The workspace is the isolation boundary for files, so a workspace per tenant gives each tenant's data hard isolation from every other tenant. Each organization can have up to 100 workspaces; contact your account team if you need more. </Warning> ## How to use the Files API
### Storage limits * **Maximum file size:** 500 MB per file -* **Total storage:** 500 GB per organization +* **Total storage:** 1 TB per organization ### File lifecycle
* Files are inaccessible through the API shortly after deletion, but they may persist in active Messages API calls and associated tool uses * Files that users delete will be deleted in accordance with Anthropic's [data retention policy](https://privacy.claude.com/en/articles/7996866-how-long-do-you-store-my-organization-s-data). For ZDR eligibility across all features, see [API and data retention](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention) +### Audit logging + +If your organization has the [Compliance API](https://platform.claude.com/docs/en/manage-claude/compliance-api) enabled, its [Activity Feed](https://platform.claude.com/docs/en/manage-claude/compliance-activity-feed) records Files API operations made with a Claude API key or from the Claude Console: each upload (`POST /v1/files`), content download (`GET /v1/files/{file_id}/content`), and deletion (`DELETE /v1/files/{file_id}`) appears as a `platform_file_uploaded`, `platform_file_content_downloaded`, or `platform_file_deleted` activity. Listing files and retrieving file metadata are not recorded. Operations that occur while the Compliance API is off are not recorded and cannot be recovered later, so [set up the Compliance API](https://platform.claude.com/docs/en/manage-claude/compliance-api-access) before you rely on this audit trail. On [Claude Platform on AWS](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#monitoring-and-logging), audit file operations with AWS CloudTrail data events instead. + ## Error handling Common errors when using the Files API include:
* **Exceeds context window size (400):** The file is larger than the context window size (for example, using a 500 MB plain text file in a `/v1/messages` request) * **Invalid filename (400):** The file name doesn't meet the length requirements (1-255 characters) or contains forbidden characters (`<`, `>`, `:`, `"`, `|`, `?`, `*`, `\`, `/`, or Unicode characters 0-31) * **File too large (413):** File exceeds the 500 MB limit -* **Storage limit exceeded (400):** Your organization has reached the 500 GB storage limit +* **Storage limit exceeded (400):** Your organization has reached the 1 TB storage limit ```json Output {
### Rate limits -During the beta period: - -* File-related API calls are limited to approximately 100 requests per minute -* [Contact us](mailto:[email protected]) if you need higher limits for your use case +File-related API calls are limited to approximately 500 requests per minute. To request a higher limit, [contact sales](mailto:[email protected]). ## Next steps
build-with-claude/files First recorded · 1048 lines, first recorded
## 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 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.