The Files API allows you to upload, manage, and download files for use with Claude. Files can be referenced in messages for document analysis, image processing, and other file-based operations.
The Files API enables:
Beta Feature: Requires betas: ['files-api-2025-04-14']
class Files extends APIResource {
upload(params: FileUploadParams): APIPromise<FileMetadata>;
list(params?: FileListParams): FileMetadataPage;
retrieveMetadata(fileID: string, params?: FileRetrieveMetadataParams): APIPromise<FileMetadata>;
download(fileID: string, params?: FileDownloadParams): APIPromise<Response>;
delete(fileID: string, params?: FileDeleteParams): APIPromise<DeletedFile>;
}Access via:
client.beta.files.*interface FileMetadata {
id: string;
type: 'file';
filename: string;
size: number; // Bytes
created_at: string; // ISO 8601
}
interface DeletedFile {
id: string;
type: 'file';
deleted: boolean;
}client.beta.files.upload(
params: FileUploadParams
): APIPromise<FileMetadata>;
interface FileUploadParams {
file: File | Blob | ReadStream;
betas: ['files-api-2025-04-14'];
}Example - Node.js:
import Anthropic, { toFile } from '@anthropic-ai/sdk';
import fs from 'fs';
const client = new Anthropic();
// Upload from file system
const file = await client.beta.files.upload({
file: await toFile(
fs.createReadStream('/path/to/document.pdf'),
'document.pdf',
{ type: 'application/pdf' }
),
betas: ['files-api-2025-04-14'],
});
console.log('File ID:', file.id);
console.log('Filename:', file.filename);
console.log('Size:', file.size, 'bytes');Example - Browser:
// Upload from File input
const fileInput = document.querySelector('input[type="file"]');
const uploadedFile = fileInput.files[0];
const file = await client.beta.files.upload({
file: uploadedFile,
betas: ['files-api-2025-04-14'],
});Example - Buffer:
import { toFile } from '@anthropic-ai/sdk';
const buffer = Buffer.from('PDF content here...');
const file = await client.beta.files.upload({
file: await toFile(buffer, 'document.pdf', { type: 'application/pdf' }),
betas: ['files-api-2025-04-14'],
});Example - Fetch Response:
const response = await fetch('https://example.com/document.pdf');
const file = await client.beta.files.upload({
file: response,
betas: ['files-api-2025-04-14'],
});Reference uploaded files in messages:
// Upload file first
const file = await client.beta.files.upload({
file: await toFile(fs.createReadStream('report.pdf'), 'report.pdf', { type: 'application/pdf' }),
betas: ['files-api-2025-04-14'],
});
// Use file in message
const message = await client.beta.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 2048,
betas: ['files-api-2025-04-14'],
messages: [
{
role: 'user',
content: [
{
type: 'document',
source: {
type: 'file',
file_id: file.id, // Reference uploaded file
},
},
{
type: 'text',
text: 'Summarize this document.',
},
],
},
],
});For images:
const image = await client.beta.files.upload({
file: await toFile(fs.createReadStream('photo.jpg'), 'photo.jpg', { type: 'image/jpeg' }),
betas: ['files-api-2025-04-14'],
});
const message = await client.beta.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
betas: ['files-api-2025-04-14'],
messages: [
{
role: 'user',
content: [
{
type: 'image',
source: {
type: 'file',
file_id: image.id,
},
},
{
type: 'text',
text: 'What is in this image?',
},
],
},
],
});client.beta.files.list(
params?: FileListParams
): FileMetadataPage;
interface FileListParams {
before_id?: string;
after_id?: string;
limit?: number; // Default: 20
betas: ['files-api-2025-04-14'];
}Example:
const files = await client.beta.files.list({
limit: 50,
betas: ['files-api-2025-04-14'],
});
for (const file of files.data) {
console.log(`${file.filename} - ${file.size} bytes - ${file.created_at}`);
}
// Auto-pagination
for await (const file of client.beta.files.list({ betas: ['files-api-2025-04-14'] })) {
console.log(file.id);
}client.beta.files.retrieveMetadata(
fileID: string,
params?: FileRetrieveMetadataParams
): APIPromise<FileMetadata>;
interface FileRetrieveMetadataParams {
betas: ['files-api-2025-04-14'];
}Example:
const metadata = await client.beta.files.retrieveMetadata('file_abc123', {
betas: ['files-api-2025-04-14'],
});
console.log('Filename:', metadata.filename);
console.log('Size:', metadata.size);
console.log('Created:', metadata.created_at);client.beta.files.download(
fileID: string,
params?: FileDownloadParams
): APIPromise<Response>;
interface FileDownloadParams {
betas: ['files-api-2025-04-14'];
}Example:
import fs from 'fs';
import { pipeline } from 'stream/promises';
const response = await client.beta.files.download('file_abc123', {
betas: ['files-api-2025-04-14'],
});
// Save to file system (Node.js)
await pipeline(
response.body,
fs.createWriteStream('/path/to/downloaded-file.pdf')
);
// Or get as buffer
const buffer = Buffer.from(await response.arrayBuffer());
// Browser: Trigger download
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'file.pdf';
a.click();client.beta.files.delete(
fileID: string,
params?: FileDeleteParams
): APIPromise<DeletedFile>;
interface FileDeleteParams {
betas: ['files-api-2025-04-14'];
}Example:
const deleted = await client.beta.files.delete('file_abc123', {
betas: ['files-api-2025-04-14'],
});
console.log('Deleted:', deleted.deleted); // trueimport Anthropic, { toFile } from '@anthropic-ai/sdk';
import fs from 'fs';
const client = new Anthropic();
// 1. Upload file
console.log('Uploading file...');
const file = await client.beta.files.upload({
file: await toFile(
fs.createReadStream('document.pdf'),
'document.pdf',
{ type: 'application/pdf' }
),
betas: ['files-api-2025-04-14'],
});
console.log('Uploaded:', file.id);
// 2. Use in message
console.log('Creating message...');
const message = await client.beta.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 2048,
betas: ['files-api-2025-04-14'],
messages: [
{
role: 'user',
content: [
{
type: 'document',
source: {
type: 'file',
file_id: file.id,
},
},
{
type: 'text',
text: 'Extract the key points from this document.',
},
],
},
],
});
console.log('Response:', message.content[0].text);
// 3. Cleanup
console.log('Cleaning up...');
await client.beta.files.delete(file.id, {
betas: ['files-api-2025-04-14'],
});
console.log('Done!');Files can be referenced multiple times:
const file = await client.beta.files.upload({ /* ... */ });
// Use in multiple messages
const message1 = await client.beta.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
betas: ['files-api-2025-04-14'],
messages: [{
role: 'user',
content: [
{ type: 'document', source: { type: 'file', file_id: file.id } },
{ type: 'text', text: 'Summarize this.' },
],
}],
});
const message2 = await client.beta.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
betas: ['files-api-2025-04-14'],
messages: [{
role: 'user',
content: [
{ type: 'document', source: { type: 'file', file_id: file.id } },
{ type: 'text', text: 'What are the main topics?' },
],
}],
});
// Cleanup when done
await client.beta.files.delete(file.id, { betas: ['files-api-2025-04-14'] });application/pdftext/plainimage/jpegimage/pngimage/gifimage/webp// ✅ Good: Clean up after use
const file = await client.beta.files.upload({ /* ... */ });
try {
const message = await client.beta.messages.create({ /* ... */ });
// Use message
} finally {
await client.beta.files.delete(file.id, { betas: ['files-api-2025-04-14'] });
}
// ❌ Bad: Leaving files around
const file = await client.beta.files.upload({ /* ... */ });
const message = await client.beta.messages.create({ /* ... */ });
// File never deletedtry {
const file = await client.beta.files.upload({ /* ... */ });
} catch (error) {
if (error instanceof Anthropic.BadRequestError) {
console.error('Invalid file:', error.message);
} else if (error instanceof Anthropic.RateLimitError) {
console.error('Rate limited, retry later');
}
throw error;
}// ✅ Good: Validate before upload
async function uploadFile(filePath: string) {
const stats = await fs.promises.stat(filePath);
if (stats.size > 10 * 1024 * 1024) { // 10MB
throw new Error('File too large');
}
const ext = path.extname(filePath);
if (!['.pdf', '.jpg', '.png'].includes(ext)) {
throw new Error('Unsupported file type');
}
return client.beta.files.upload({ /* ... */ });
}