Source Intelligence
Sweep 28 Aug 2026 · 00:00Z Build v2.1.250 478 read Stable v2.1.236 Latest v2.1.250 Next v2.1.251 Feeds RSS JSON llms.txt
Reading a new release v2.1.251 Analysing changes · 2/5 Deeper second pass · 0/5 agents 427 findings $12.75 so far

DisclaimerUnofficial, and not affiliated with Anthropic. Nearly all of this is read straight out of what ships: npm bundles, captured prompts, published docs. Anthropic's own notes go in verbatim, marked as theirs. The rest is my reading, and every entry carries the strings behind it. If one looks wrong, vote it down and say why.

Page history

files

build-with-claude/files

7 recorded changes 1033 lines First seen Last changed Upstream

History

build-with-claude/files Changed · +2 / -2 lines

from line 25
 * **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>
from line 949
 
 ### 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

from line 123
   ```
 
   ```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;
from line 329
   ```
 
   ```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: [
           [
from line 340
                       '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
from line 691
   ```
 
   ```bash CLI
-  ant files list \
-    --max-items 10
+  ant files list --max-items 10
   ```
 
   ```python Python
from line 735
   ```
 
   ```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;
   ```
 
from line 798
   ```
 
   ```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;
   ```
 
from line 848
   ```
 
   ```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
from line 924
   ```
 
   ```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

from line 32
 
 ## 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:
from line 123
   ```
 
   ```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'),
   );
from line 330
   ```
 
   ```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: [
from line 739
   ```
 
   ```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();
from line 757
 
 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:
from line 804
   ```
 
   ```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;
   ```
from line 855
   ```
 
   ```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);
   ```
 
from line 932
   ```
 
   ```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

from line 9
 - 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
 
from line 33
 ## 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
from line 45
   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)
from line 58
   ```
 
   ```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
from line 66
   ```
 
   ```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,
from line 77
   ```
 
   ```csharp C#
-  var uploaded = await client.Beta.Files.Upload(
+  var uploaded = await client.Files.Upload(
       new FileUploadParams
       {
           File = new BinaryContent
from line 99
   }
   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 {
from line 112
   ```
 
   ```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")))
from line 136
   ```
 
   ```ruby Ruby
-  file = client.beta.files.upload(
+  file = client.files.upload(
     file: Anthropic::FilePart.new(
       Pathname("/path/to/document.pdf"),
       content_type: "application/pdf"
from line 174
   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
   {
from line 202
   ```
 
   ```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:
from line 218
   ```
 
   ```python Python
-  response = client.beta.messages.create(
+  response = client.messages.create(
       model="claude-opus-5",
       max_tokens=1024,
       messages=[
from line 236
               ],
           }
       ],
-      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: [
from line 262
         ],
       },
     ],
-    betas: ["files-api-2025-04-14"],
   });
 
   console.log(response);
from line 268
   ```
 
   ```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 }
                       }
                   }
               }
from line 294
   ```
 
   ```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,
   				}),
   			),
from line 317
   ```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);
   ```
 
from line 358
   ```
 
   ```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",
from line 686
 
 #### 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);
   ```
 
from line 715
   ```csharp C#
   AnthropicClient client = new();
 
-  var files = await client.Beta.Files.List();
+  var files = await client.Files.List();
   Console.WriteLine(files);
   ```
 
from line 722
   ```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)
   }
from line 730
   ```
 
   ```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);
   }
   ```
from line 750
   ```ruby Ruby
   client = Anthropic::Client.new
 
-  files = client.beta.files.list
+  files = client.files.list
   puts files
   ```
 </CodeGroup>
from line 757
 
 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
 
from line 767
   ```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)
   }
from line 800
   ```
 
   ```java Java
-  FileMetadata metadata = client.beta().files().retrieveMetadata(fileId);
+  FileMetadata metadata = client.files().retrieveMetadata(fileId);
 
   System.out.println(metadata);
   ```
from line 811
   ```
 
   ```ruby Ruby
-  file = client.beta.files.retrieve_metadata(file_id)
+  file = client.files.retrieve_metadata(file_id)
   puts file
   ```
 </CodeGroup>
from line 824
   ```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)
   }
from line 852
   ```
 
   ```java Java
-  client.beta().files().delete(fileId);
+  client.files().delete(fileId);
   ```
 
   ```php PHP
from line 860
   ```
 
   ```ruby Ruby
-  client.beta.files.delete(file_id)
+  client.files.delete(file_id)
   ```
 </CodeGroup>
 
from line 873
   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);
from line 896
   ```
 
   ```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);
from line 904
 
   ```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
   	}
from line 923
   ```
 
   ```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);
from line 938
   ```
 
   ```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

from line 5
 ---
 
 ## 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.
from line 33
 ## 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
from line 162
   "mime_type": "application/pdf",
   "size_bytes": 1024000,
   "created_at": "2025-01-01T00:00:00Z",
-  "downloadable": false
+  "downloadable": false,
+  "expires_at": null
 }
 ```
 
from line 699
 
 #### 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
from line 769
   ```
 </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:
from line 988
 
 * 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

from line 32
 
 <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
from line 980
 ### Storage limits
 
 * **Maximum file size:** 500 MB per file
-* **Total storage:** 500 GB per organization
+* **Total storage:** 1 TB per organization
 
 ### File lifecycle
 
from line 991
 * 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:
from line 1005
 * **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
 {
from line 1032
 
 ### 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.