Files API

Files API (Files API)

Files API는 매 요청마다 콘텐츠를 재업로드하지 않고 Claude API와 함께 사용할 파일을 업로드·관리할 수 있게 해 줘요. 특히 코드 실행 도구로 입력(예: 데이터셋과 문서)을 제공하고 출력(예: 차트)을 내려받을 때 유용해요. 업로드한 파일은 보안 저장소에 저장되고 고유한 file_id를 받아요.

출처: 문서

본문

Files API는 매 요청마다 콘텐츠를 재업로드하지 않고 Claude API와 함께 사용할 파일을 업로드·관리할 수 있게 해 줘요. 이는 특히 코드 실행 도구로 입력(예: 데이터셋과 문서)을 제공하고 출력(예: 차트)을 내려받을 때 유용해요. 이 가이드 외에 API 레퍼런스를 직접 탐색할 수 있어요.

파일 유형 지원 (File type support)

Messages 요청에서 file_id를 참조하는 것은 주어진 파일 유형을 지원하는 모든 모델에서 지원돼요. 이미지는 모든 현재 Claude 모델에서 지원돼요. PDF코드 실행 도구가 있는 다른 파일 유형에 대해서는 모델 지원을 위해 연결된 페이지를 참고하세요.

Files API가 동작하는 방식

Files API는 파일 작업을 위한 한 번 만들고 여러 번 사용하는(create-once, use-many-times) 접근을 제공해요:

  • 파일 업로드 Anthropic의 보안 저장소에 업로드하고 고유한 file_id 받기
  • 파일 내려받기 스킬이나 코드 실행 도구가 만든 파일 내려받기
  • 파일 참조 Messages 요청에서 콘텐츠를 재업로드하는 대신 file_id로 참조
  • 파일 관리 목록, 검색, 삭제 작업으로 파일 관리

경고 (워크스페이스 범위 접근): 업로드된 파일은 최종 사용자, 대화, 세션에 범위가 지정되지 않고 전체 워크스페이스에서 접근 가능해요. 워크스페이스에 접근할 수 있는 어떤 API 키든 그 워크스페이스에 업로드된 모든 파일에 접근할 수 있어요. 모든 서비스 계정과 조직 역할이 API 접근을 허용하는 모든 사용자는 추가된 워크스페이스 외에 Default Workspace도 사용할 수 있으므로, 분리해서 유지해야 하는 파일은 자체 워크스페이스에 두고 그 워크스페이스에 범위가 지정된 키로만 접근하세요. 최종 사용자나 다른 신뢰할 수 없는 소스의 file_id 값을 절대 수용하지 마세요. 사용자 제공 파일 ID는 한 사용자가 다른 사용자가 업로드한 콘텐츠를 읽게 만들 수 있어요. 파일 ID를 서버 측 참조로 취급하고, 사용자와 파일 사이의 매핑을 애플리케이션에 유지하세요.

Files API에서 멀티테넌트 애플리케이션을 만들고 있다면 테넌트마다 별도의 워크스페이스를 만드세요. 워크스페이스가 파일의 격리 경계이므로, 테넌트당 워크스페이스 하나가 각 테넌트의 데이터를 다른 모든 테넌트와 단단히 격리해 줘요. 각 조직은 최대 100개 워크스페이스를 가질 수 있어요. 더 필요하면 계정 팀에 문의하세요.

Files API 사용법

파일 업로드

향후 API 호출에서 참조할 파일을 업로드하세요:

```bash cURL FILE_ID=$(curl -X POST https://api.anthropic.com/v1/files \ -H "x-api-key: $ANTHR...KEY" \ -H "anthropic-version: 2023-06-01" \ -F "file=@/path/to/document.pdf" | jq -r '.id') echo "$FILE_ID" ```
FILE_ID=$(ant files upload \
  --file /path/to/document.pdf \
  --transform id \
  --raw-output)
echo "$FILE_ID"
uploaded = client.files.upload(
    file=("document.pdf", open("/path/to/document.pdf", "rb"), "application/pdf"),
)
file_id = uploaded.id
print(file_id)
const uploaded = await client.files.upload({
  file: await toFile(
    fs.createReadStream("/path/to/document.pdf"),
    undefined,
    { type: "application/pdf" },
  ),
});
console.log(uploaded.id);
var uploaded = await client.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);
f, err := os.Open("/path/to/document.pdf")
if err != nil {
	log.Fatal(err)
}
defer f.Close()

response, err := client.Files.Upload(context.Background(),
	anthropic.FileUploadParams{
		File: anthropic.File(f, "document.pdf", "application/pdf"),
	})
if err != nil {
	log.Fatal(err)
}

fileID := response.ID
fmt.Println(fileID)
FileMetadata file = client.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);
$file = $client->files->upload(
    file: FileParam::fromResource(fopen('/path/to/document.pdf', 'rb'), contentType: 'application/pdf'),
);

$fileId = $file->id;
echo $fileId;
file = client.files.upload(
  file: Anthropic::FilePart.new(
    Pathname("/path/to/document.pdf"),
    content_type: "application/pdf"
  )
)

file_id = file.id
puts file_id

파일 업로드 응답에는 다음이 포함돼요:

{
  "id": "file_011CNha8iCJcU1wXNR6q4V8w",
  "type": "file",
  "filename": "document.pdf",
  "mime_type": "application/pdf",
  "size_bytes": 1024000,
  "created_at": "2025-01-01T00:00:00Z",
  "downloadable": false,
  "expires_at": null
}

downloadable은 업로드한 파일의 경우 false예요. 스킬이나 코드 실행 도구가 만든 파일만 내려받을 수 있어요. 파일 내려받기 참고.

메시지에서 파일 사용하기

업로드한 후에는 업로드 응답의 idfile_id로 전달해 파일을 참조하세요:

```bash cURL curl -X POST https://api.anthropic.com/v1/messages \ -H "x-api-key: $ANTHR...KEY" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d @- <ant messages create <<YAML model: claude-opus-5-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
response = client.messages.create(
    model="claude-opus-5-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,
                    },
                },
            ],
        }
    ],
)
print(response)
const response = await client.messages.create({
  model: "claude-opus-5-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,
          },
        },
      ],
    },
  ],
});

console.log(response);
var response = await client.Messages.Create(
    new MessageCreateParams
    {
        Model = Model.ClaudeOpus5_5,
        MaxTokens = 1024,
        Messages =
        [
            new MessageParam
            {
                Role = Role.User,
                Content = new List<ContentBlockParam>
                {
                    new TextBlockParam { Text = "Please summarize this document for me." },
                    new DocumentBlockParam
                    {
                        Source = new FileDocumentSource { FileID = fileId }
                    }
                }
            }
        ]
    });

Console.WriteLine(response);
msg, err := client.Messages.New(context.Background(),
	anthropic.MessageNewParams{
		Model:     anthropic.ModelClaudeOpus5_5,
		MaxTokens: 1024,
		Messages: []anthropic.MessageParam{
			anthropic.NewUserMessage(
				anthropic.NewTextBlock("Please summarize this document for me."),
				anthropic.NewDocumentBlock(anthropic.FileDocumentSourceParam{
					FileID: fileID,
				}),
			),
		},
	})
if err != nil {
	log.Fatal(err)
}

fmt.Println(msg)
MessageCreateParams params = MessageCreateParams.builder()
    .model(Model.CLAUDE_OPUS_5_5)
    .maxTokens(1024)
    .addUserMessageOfBlockParams(List.of(
        ContentBlockParam.ofText(TextBlockParam.builder()
            .text("Please summarize this document for me.")
            .build()),
        ContentBlockParam.ofDocument(DocumentBlockParam.builder()
            .fileSource(fileId)
            .build())
    ))
    .build();

Message message = client.messages().create(params);
System.out.println(message);
$response = $client->messages->create(
    maxTokens: 1024,
    messages: [
        [
            'role' => 'user',
            'content' => [
                ['type' => 'text', 'text' => 'Please summarize this document for me.'],
                [
                    'type' => 'document',
                    'source' => [
                        'type' => 'file',
                        'fileID' => $fileId,
                    ],
                ],
            ],
        ],
    ],
    model: 'claude-opus-5-5',
);

echo $response;
response = client.messages.create(
  model: "claude-opus-5-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
          }
        }
      ]
    }
  ]
)

puts response

파일 유형과 콘텐츠 블록

Files API는 서로 다른 콘텐츠 블록 유형에 대응하는 다양한 파일 유형을 지원해요:

파일 유형 MIME 유형 콘텐츠 블록 유형 사용 사례
PDF application/pdf document 텍스트 분석, 문서 처리
일반 텍스트 text/plain document 텍스트 분석, 처리
이미지 image/jpeg, image/png, image/gif, image/webp image 이미지 분석, 시각 작업
데이터셋, 기타 다양함 container_upload 데이터 분석, 시각화 생성

Document 블록

PDF와 텍스트 파일에는 document 콘텐츠 블록을 사용하세요:

{
  "type": "document",
  "source": {
    "type": "file",
    "file_id": "file_011CNha8iCJcU1wXNR6q4V8w"
  },
  "title": "Document Title", // Optional
  "context": "Context about the document", // Optional
  "citations": { "enabled": true } // Optional, enables citations
}

Image 블록

이미지에는 image 콘텐츠 블록을 사용하세요:

{
  "type": "image",
  "source": {
    "type": "file",
    "file_id": "file_011CPMxVD3fHLUhvTqtsQA5w"
  }
}

Container 업로드 블록

코드 실행 도구로 파일을 보내려면 container_upload 콘텐츠 블록을 사용하세요:

{
  "type": "container_upload",
  "file_id": "file_011CNha8iCJcU1wXNR6q4V8w"
}

다른 파일 형식 작업하기

document 블록이 지원하지 않는 파일 유형(예: .docx와 .xlsx)에는 파일을 일반 텍스트로 변환하고 콘텐츠를 메시지에 직접 포함하세요. .csv와 .md 파일처럼 이미 일반 텍스트인 파일은 이 방식으로 읽거나, 명시적 text/plain 콘텐츠 유형으로 Files API를 통해 업로드할 수 있어요. 텍스트로 읽는 대신 데이터셋을 분석하려면 container_upload 블록으로 코드 실행 도구에 업로드하세요.

다음 예시는 텍스트 파일을 읽고 그 내용을 일반 텍스트로 보내요:

```bash cURL # Read the text file # Note: For files with special characters, consider base64 encoding TEXT_CONTENT=$(cat document.txt)

curl https://api.anthropic.com/v1/messages
-H "content-type: application/json"
-H "x-api-key: $ANTHR...KEY"
-H "anthropic-version: 2023-06-01"
-d @- <<EOF { "model": "claude-opus-5-5", "max_tokens": 1024, "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Here's the document content:\n\n${TEXT_CONTENT}\n\nPlease summarize this document." } ] } ] } EOF


```bash CLI
# The "@./path" reference inlines the file contents directly into the field.
ant messages create \
  --model claude-opus-5-5 \
  --max-tokens 1024 \
  --transform 'content.#(type=="text").text' \
  --raw-output <<'YAML'
messages:
  - role: user
    content:
      - type: text
        text: "Here's the document content:"
      - type: text
        text: "@./document.txt"
      - type: text
        text: "Please summarize this document."
YAML
client = anthropic.Anthropic()

# Read the text file
with open("document.txt") as f:
    text_content = f.read()

response = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": f"Here's the document content:\n\n{text_content}\n\nPlease summarize this document.",
                }
            ],
        }
    ],
)

for block in response.content:
    if block.type == "text":
        print(block.text)
import fs from "node:fs/promises";
// ...
const client = new Anthropic();

// Read the text file
const textContent = await fs.readFile("document.txt", "utf-8");

const response = await client.messages.create({
  model: "claude-opus-5-5",
  max_tokens: 1024,
  messages: [
    {
      role: "user",
      content: [
        {
          type: "text",
          text: `Here's the document content:\n\n${textContent}\n\nPlease summarize this document.`
        }
      ]
    }
  ]
});

const textBlock = response.content.find(
  (block): block is Anthropic.TextBlock => block.type === "text"
);
console.log(textBlock?.text);
AnthropicClient client = new();

// Read the text file
string textContent = await File.ReadAllTextAsync("document.txt");

var parameters = new MessageCreateParams
{
    Model = Model.ClaudeOpus5_5,
    MaxTokens = 1024,
    Messages = [new()
    {
        Role = Role.User,
        Content = $"Here's the document content:\n\n{textContent}\n\nPlease summarize this document."
    }]
};

var message = await client.Messages.Create(parameters);
foreach (var block in message.Content)
{
    if (block.TryPickText(out var textBlock))
    {
        Console.WriteLine(textBlock.Text);
    }
}
client := anthropic.NewClient()

// Read the text file
textContent, err := os.ReadFile("document.txt")
if err != nil {
	log.Fatal(err)
}

response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
	Model:     anthropic.ModelClaudeOpus5_5,
	MaxTokens: 1024,
	Messages: []anthropic.MessageParam{
		anthropic.NewUserMessage(anthropic.NewTextBlock(
			fmt.Sprintf("Here's the document content:\n\n%s\n\nPlease summarize this document.", string(textContent)),
		)),
	},
})
if err != nil {
	log.Fatal(err)
}

for _, block := range response.Content {
	if textBlock, ok := block.AsAny().(anthropic.TextBlock); ok {
		fmt.Println(textBlock.Text)
	}
}
AnthropicClient client = AnthropicOkHttpClient.fromEnv();

// Read the text file
String textContent = Files.readString(Path.of("document.txt"));

MessageCreateParams params = MessageCreateParams.builder()
    .model(Model.CLAUDE_OPUS_5_5)
    .maxTokens(1024L)
    .addUserMessage("Here's the document content:\n\n" + textContent + "\n\nPlease summarize this document.")
    .build();

Message response = client.messages().create(params);
response.content().stream()
    .flatMap(block -> block.text().stream())
    .forEach(textBlock -> System.out.println(textBlock.text()));
$client = new Client();

// Read the text file
$textContent = file_get_contents("document.txt");

$message = $client->messages->create(
    maxTokens: 1024,
    messages: [
        [
            'role' => 'user',
            'content' => [
                [
                    'type' => 'text',
                    'text' => "Here's the document content:\n\n{$textContent}\n\nPlease summarize this document."
                ]
            ]
        ]
    ],
    model: 'claude-opus-5-5',
);

foreach ($message->content as $block) {
    if ($block->type === 'text') {
        echo $block->text, PHP_EOL;
    }
}
client = Anthropic::Client.new

# Read the text file
text_content = File.read("document.txt")

message = client.messages.create(
  model: "claude-opus-5-5",
  max_tokens: 1024,
  messages: [
    {
      role: "user",
      content: [
        {
          type: "text",
          text: "Here's the document content:\n\n#{text_content}\n\nPlease summarize this document."
        }
      ]
    }
  ]
)

message.content.each do |block|
  puts block.text if block.type == :text
end

참고: 이미지가 포함된 .docx 파일은 먼저 PDF 형식으로 변환한 다음 PDF 지원을 사용해 내장 이미지 파싱을 활용하세요. 이렇게 하면 PDF 문서의 인용을 사용할 수 있어요.

파일 관리하기

파일 목록

업로드한 파일 목록을 검색해요. 엔드포인트는 페이지네이션돼요. 각 요청은 최대 limit(기본 20, 최대 1,000) 파일을 반환하고, 응답의 next_page 커서를 page 매개변수로 다시 전달하면 다음 페이지를 가져와요. 파일은 최신 순으로 정렬돼요. List Files API 레퍼런스 참고. SDK는 첫 페이지를 반환하고 자동 페이지네이션 헬퍼를 제공해요. CLI 예시는 --max-items로 총계를 제한해요:

```bash cURL curl https://api.anthropic.com/v1/files \ -H "x-api-key: $ANTHR...KEY" \ -H "anthropic-version: 2023-06-01" ```
ant files list --max-items 10
client = anthropic.Anthropic()
files = client.files.list()
print(files)
const client = new Anthropic();
const files = await client.files.list();
console.log(files);
AnthropicClient client = new();

var files = await client.Files.List();
Console.WriteLine(files);
client := anthropic.NewClient()

files, err := client.Files.List(context.TODO(), anthropic.FileListParams{})
if err != nil {
	log.Fatal(err)
}
fmt.Println(files)
import com.anthropic.models.files.FileListPage;
// ...
void main() {
    AnthropicClient client = AnthropicOkHttpClient.fromEnv();

    FileListPage files = client.files().list();
    System.out.println(files);
}
$client = new Client();

$files = $client->files->list();
echo $files;
client = Anthropic::Client.new

files = client.files.list
puts files

페이지네이션 대신 한 요청에서 알려진 파일 집합을 확인하려면 최대 100개 파일 ID를 ids[] 질의 매개변수로 전달하세요. ids[] 요청은 항상 단일 페이지를 반환하고(next_pagenull), 워크스페이스의 파일로 해석되지 않는 ID는 data에서 조용히 생략돼요. 반환된 ID를 요청된 ID와 비교해 누락을 감지하세요. ids[]pagelimit와 결합할 수 없어요.

파일 메타데이터 가져오기

특정 파일에 대한 정보를 검색해요:

```bash cURL curl "https://api.anthropic.com/v1/files/$FILE_ID" \ -H "x-api-key: $ANTHR...KEY" \ -H "anthropic-version: 2023-06-01" ```
ant files retrieve-metadata \
  --file-id "$FILE_ID"
file = client.files.retrieve_metadata(file_id)
print(file)
const file = await client.files.retrieveMetadata(uploaded.id);
console.log(file);
var file = await client.Files.RetrieveMetadata(fileId);
Console.WriteLine(file);
metadata, err := client.Files.GetMetadata(context.TODO(), fileID, anthropic.FileGetMetadataParams{})
if err != nil {
	log.Fatal(err)
}

fmt.Println(metadata)
FileMetadata metadata = client.files().retrieveMetadata(fileId);

System.out.println(metadata);
$file = $client->files->retrieveMetadata($fileId);
echo $file;
file = client.files.retrieve_metadata(file_id)
puts file

파일 삭제

워크스페이스에서 파일을 제거해요:

```bash cURL curl -X DELETE "https://api.anthropic.com/v1/files/$FILE_ID" \ -H "x-api-key: $ANTHR...KEY" \ -H "anthropic-version: 2023-06-01" ```
ant files delete \
  --file-id "$FILE_ID"
client.files.delete(file_id)
await client.files.delete(uploaded.id);
await client.Files.Delete(fileId);
_, err = client.Files.Delete(context.TODO(), fileID, anthropic.FileDeleteParams{})
if err != nil {
	log.Fatal(err)
}
client.files().delete(fileId);
$client->files->delete($fileId);
client.files.delete(file_id)

파일 내려받기

스킬이나 코드 실행 도구가 만든 파일을 내려받으세요. 업로드한 파일은 내려받을 수 없어요. 생성된 파일의 file_id는 이를 만든 Messages 응답의 bash_code_execution_tool_result 콘텐츠 블록에 나타나요:

```bash cURL curl -X GET "https://api.anthropic.com/v1/files/$FILE_ID/content" \ -H "x-api-key: $ANTHR...KEY" \ -H "anthropic-version: 2023-06-01" \ --output downloaded_file.txt ```
ant files download \
  --file-id "$FILE_ID" \
  --output downloaded_file.txt
file_content = client.files.download(file_id)

file_content.write_to_file("downloaded_file.txt")
const content = await client.files.download(uploaded.id);

const bytes = Buffer.from(await content.arrayBuffer());
await fsp.writeFile("downloaded_file.txt", bytes);
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);
func downloadFile(client anthropic.Client, fileID string) error {
	resp, err := client.Files.Download(context.TODO(), fileID, anthropic.FileDownloadParams{})
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	out, err := os.Create("downloaded_file.txt")
	if err != nil {
		return err
	}
	defer out.Close()

	_, err = io.Copy(out, resp.Body)
	return err
}

try (HttpResponse response = client.files().download(fileId)) {
    try (InputStream body = response.body()) {
        Files.copy(body, Path.of("downloaded_file.txt"),
            StandardCopyOption.REPLACE_EXISTING);
    }
}
$fileContent = $client->files->download($fileId);

file_put_contents('downloaded_file.txt', $fileContent);
file_content = client.files.download(file_id)

File.binwrite("downloaded_file.txt", file_content.read)

참고: 파일의 메타데이터가 "downloadable": true를 보여줄 때만 내려받을 수 있어요. 이는 스킬이나 코드 실행 도구가 만든 파일의 경우예요. 업로드한 파일을 내려받으면 400 오류를 반환해요.

Claude API에서 코드 실행 도구가 만든 지원 이미지·비디오·오디오 파일(스킬이 만든 파일 포함)은 내려받을 때 서명된 C2PA Content Credentials를 지녀요. 자격 증명이 포함하는 것과 검증 방법은 생성된 파일의 Content Credentials를 참고하세요.

파일 저장과 한도 (File storage and limits)

저장 한도 (Storage limits)

  • 최대 파일 크기: 파일당 500 MB
  • 총 저장: 조직당 1 TB

파일 수명 주기 (File lifecycle)

  • 파일은 업로드된 워크스페이스에 범위가 지정돼요. 같은 워크스페이스의 어떤 요청이든 참조할 수 있어요. 신뢰할 수 없는 소스의 파일 ID는 절대 수용하지 마세요(워크스페이스 접근 경고 참고)
  • 파일은 업로드 후 수정하거나 이름을 바꿀 수 없어요. 파일의 콘텐츠를 바꾸려면 새 파일을 업로드하고 옛 파일을 삭제하세요
  • 파일은 DELETE /v1/files/{file_id} 엔드포인트로 삭제하거나 expires_at에 도달할 때까지 유지돼요
  • 삭제된 파일은 복구할 수 없어요
  • 파일은 삭제 후 잠시 후 API를 통해 접근할 수 없지만, 활성 Messages API 호출과 관련 도구 사용에서 잠시 유지될 수 있어요
  • 사용자가 삭제한 파일은 Anthropic의 데이터 보존 정책에 따라 삭제돼요. 모든 기능의 ZDR 자격은 API와 데이터 보존을 참고하세요

파일 만료 (File expiration)

파일이 자동으로 만료되게 하려면 업로드할 때 expires_in_seconds 폼 필드를 포함하세요. 값은 3,600(1시간)과 7,776,000(90일) 사이의 초 단위 정수예요. 결과 expires_at 타임스탬프(RFC 3339)는 모든 파일 응답에 나타나고, 만료 없이 업로드된 파일은 null이에요. 만료는 업로드 시 한 번 설정되며 변경할 수 없어요.

파일이 expires_at에 도달하면:

  • 콘텐츠 내려받기(GET /v1/files/{file_id}/content)는 404 오류를 반환해요
  • 파일을 참조하는 Messages 요청은 추론 전에 실패해요
  • 메타데이터(GET /v1/files/{file_id})는 최대 30일 동안 읽을 수 있고, expires_at은 과거예요
  • 그 창 동안 목록 응답에 계속 나타나요. expires_at을 현재 시간과 비교해 만료된 파일을 필터링하세요

만료된 파일을 DELETE /v1/files/{file_id}로 삭제하면 30일 창이 경과하는 것을 기다리지 않고 메타데이터가 즉시 제거돼요.

참고: 만료는 수명 주기 기능이지 보장된 삭제 컨트롤이 아니에요. expires_at 이후 파일 콘텐츠는 API를 통해 더 이상 검색할 수 없고 저장 할당량에서 해제돼요. 기본 콘텐츠는 안전 검토를 위해 영구 삭제 전 제한된 기간 동안 유지될 수 있고, 파일 메타데이터는 만료 후 최대 30일 동안 보일 수 있어요. 예정 만료 전에 파일을 제거하려면 DELETE /v1/files/{file_id}를 사용하세요.

감사 로깅 (Audit logging)

조직에 Compliance API가 활성화되어 있으면 그 Activity Feed가 Claude API 키나 Claude Console로 이루어진 Files API 작업을 기록해요. 각 업로드(POST /v1/files), 콘텐츠 내려받기(GET /v1/files/{file_id}/content), 삭제(DELETE /v1/files/{file_id})가 platform_file_uploaded, platform_file_content_downloaded, platform_file_deleted 활동으로 나타나요. 파일 목록과 파일 메타데이터 검색은 기록되지 않아요. Compliance API가 꺼져 있는 동안 발생한 작업은 기록되지 않고 나중에 복구할 수 없으므로, 이 감사 추적에 의존하기 전에 Compliance API를 설정하세요. Claude Platform on AWS에서는 대신 AWS CloudTrail 데이터 이벤트로 파일 작업을 감사하세요.

files-api-2025-04-14에서 마이그레이션

Files API는 베타를 벗어났고 베타 헤더가 필요 없어요. files-api-2025-04-14에서 벗어나는 것은 선택 사항이에요. 여전히 보내는 요청은 계속 작동하고 베타 응답 모양을 계속 반환하므로, 기존 통합은 변경할 때까지 계속 작동해요. 헤더를 제거하면 해당 요청이 이 페이지에 문서화된 모양으로 전환돼요:

files-api-2025-04-14 포함 헤더 없이
목록 응답 { data, has_more, first_id, last_id } { data, next_page }; next_pagepage 질의 매개변수로 다시 전달
목록 커서 before_id, after_id page, 또는 최대 100개 ids[](before_idafter_id는 400 오류 반환)
파일 객체의 expires_at 반환되지 않음 항상 존재; 만료 없는 파일은 null
업로드된 파일 부분의 Content-Type 필수 선택; 생략 시 유형 감지

마이그레이션하려면:

  1. 베타 헤더 제거. 요청에서 anthropic-beta: files-api-2025-04-14를 빼세요. SDK에서는 client.beta.files 대신 client.files를 호출하세요. client.beta.files를 유지하는 것은 더 이상 헤더를 보내지 않는 SDK 릴리스에서만 작동해요. 이전 릴리스는 betas 인자 없이도 client.beta.files에서 그 헤더를 보내요.
  2. 페이지네이션 업데이트. after_id/before_id 루프를 page/next_page 커서로 바꾸거나, 파일 관리하기에 표시된 SDK 자동 페이지네이션 헬퍼를 사용하세요.
  3. expires_at 읽기. 이 필드는 헤더 없이만 나타나요. null은 파일에 만료가 없단 뜻이에요(파일 만료 참고).

SDK 베타 네임스페이스

Python SDK 1.2.0, TypeScript SDK 0.122.0, Go SDK 1.68.0, Java SDK 2.59.0, Ruby SDK 1.67.0, C# SDK 12.44.0부터 client.beta.files는 더 이상 files-api-2025-04-14를 보내지 않고 client.files와 같은 모양(Beta 접두사 유형 이름)을 반환해요. 아직 베타인 Files 기능(예: Managed Agents 베타 헤더 아래의 scope_id 필터링)을 위해 betas 인자를 수용해요. 이전 SDK 릴리스는 베타 모양으로 타이핑돼요. 그 유형에 의존한다면 마이그레이션할 때까지 이전 릴리스에 머물러 있으세요.

files-api-2025-04-14 없이 anthropic-beta: managed-agents-2026-04-01을 운반하는 요청은 이 페이지의 모양을 받되 GET /v1/files에 하나의 호환 편의가 적용돼요. before_idafter_id는 여전히 수용되고(pageids[]와 결합할 수 없음), 목록 응답은 next_page와 함께 has_more, first_id, last_id를 포함해요. 이후 Managed Agents 베타 버전은 일반 모양을 받아요.

오류 처리 (Error handling)

Files API 사용 시의 흔한 오류:

  • 파일을 찾을 수 없음 (404): 지정된 file_id가 존재하지 않거나 접근 권한이 없음
  • 잘못된 파일 유형 (400): 파일 유형이 콘텐츠 블록 유형과 일치하지 않음(예: document 블록에 이미지 파일 사용)
  • 내려받을 수 없음 (400): 업로드한 파일은 "downloadable": false이고 내려받을 수 없음. 스킬이나 코드 실행 도구가 만든 파일만 내려받을 수 있음
  • 컨텍스트 창 크기 초과 (400): 파일이 컨텍스트 창 크기보다 큼(예: /v1/messages 요청에 500 MB 일반 텍스트 파일 사용)
  • 잘못된 파일명 (400): 파일 이름이 길이 요구 사항(1-255자)을 충족하지 않거나 금지 문자(<, >, :, ", |, ?, *, \, /, 또는 Unicode 문자 0-31)를 포함
  • 파일 너무 큼 (413): 파일이 500 MB 한도를 초과
  • 저장 한도 초과 (400): 조직이 1 TB 저장 한도에 도달
{
  "type": "error",
  "error": {
    "type": "not_found_error",
    "message": "File `file_011CNha8iCJcU1wXNR6q4V8w` not found."
  },
  "request_id": "req_011CQFYcrRp7mCHLDsAYT8Qt"
}

사용 및 청구 (Usage and billing)

Files API 작업은 무료예요:

  • 파일 업로드
  • 파일 내려받기
  • 파일 목록
  • 파일 메타데이터 가져오기
  • 파일 삭제

Messages 요청에서 사용된 파일 콘텐츠는 입력 토큰으로 청구돼요.

속도 제한 (Rate limits)

파일 관련 API 호출은 분당 약 500회로 제한돼요. 더 높은 한도를 요청하려면 영업팀에 문의하세요.

다음 단계 (Next steps)

Process PDFs with Claude. Extract text, analyze charts, and understand visual content from your documents. Run Python and bash code in a sandboxed container to analyze data, generate files, and iterate on solutions. Process and analyze visual input and generate text and code from images.

더 알아보기 (Learn more)