Files API
The Files API lets you store binary files such as images, PDFs, and video. Files are separate from public pastes, use presigned URLs for access, and remain tied to your API key.
Tier requirement: File endpoints require a Pro or Max account.
File size limit: 50 MB per file.
Supported content types: image/*, application/pdf, text/plain, text/csv, text/html, application/json, application/zip, video/mp4, video/webm, audio/mpeg, audio/wav, audio/ogg, application/octet-stream.
Storage limits and pricing
Section titled “Storage limits and pricing”| Free quota | 10 GB per account |
| Overage | $0.03 / GB above the free quota |
| Bandwidth | Free — no cost to serve files |
| Per-file max | 50 MB |
Storage is measured as the sum of all non-expired files in your account. When an upload would push you over 10 GB, the overage is billed in credits at $0.03 per GB. If your credit balance cannot cover the overage, the upload is rejected with a 400 error.
Files set with expiresAt or burnAfterDownload are excluded from your usage once they are removed.
Upload a file
Section titled “Upload a file”POST /api/dev/files/upload
Section titled “POST /api/dev/files/upload”Two upload modes are supported:
Mode 1: Server-side (base64)
Section titled “Mode 1: Server-side (base64)”Send the file as a base64-encoded string in the request body. Suitable for files up to 50 MB.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
fileName | string | yes | File name with extension |
contentType | string | yes | MIME type |
fileData | string | yes | Base64-encoded file contents |
tags | string[] | no | Up to 10 tags |
burnAfterDownload | boolean | no | Delete on first download (default false) |
expiresAt | string (ISO) | no | Auto-delete after this date |
curl
curl -X POST https://api.anonpaste.com/api/dev/files/upload \ -H "x-api-key: your_api_key" \ -H "Content-Type: application/json" \ -d '{ "fileName": "photo.jpg", "contentType": "image/jpeg", "fileData": "'$(base64 -i photo.jpg)'", "tags": ["photos"], "burnAfterDownload": false }'Response
{ "success": true, "fileId": "a1b2c3d4e5f6g7h8", "readUrl": "https://r2.example.com/data-05/a1b2c3d4.jpg?sig=...", "fileName": "photo.jpg", "fileSize": 45312, "tags": ["photos"], "burnAfterDownload": false, "expiresAt": null, "remaining": 99}SDK
import { readFileSync } from 'fs';
const { fileId, readUrl } = await anonpaste.files.upload({ fileName: 'photo.jpg', contentType: 'image/jpeg', fileData: readFileSync('./photo.jpg'), tags: ['photos'], burnAfterDownload: true, expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days});Mode 2: Presigned PUT
Section titled “Mode 2: Presigned PUT”Omit fileData and provide fileSize instead. The API returns a presigned PUT URL that you use to upload the file directly. This is ideal for large files or browser environments.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
fileName | string | yes | File name with extension |
contentType | string | yes | MIME type |
fileSize | number | yes | Declared file size in bytes |
tags | string[] | no | Up to 10 tags |
burnAfterDownload | boolean | no | Delete on first download |
expiresAt | string (ISO) | no | Auto-delete after this date |
curl (step 1 – get presigned URL)
curl -X POST https://api.anonpaste.com/api/dev/files/upload \ -H "x-api-key: your_api_key" \ -H "Content-Type: application/json" \ -d '{ "fileName": "video.mp4", "contentType": "video/mp4", "fileSize": 10000000 }'Response
{ "success": true, "fileId": "a1b2c3d4e5f6g7h8", "uploadUrl": "https://r2.example.com/...", "readUrl": "https://r2.example.com/...", "remaining": 99}curl (step 2 – PUT to uploadUrl)
curl -X PUT "https://r2.example.com/..." \ -H "Content-Type: video/mp4" \ --data-binary @video.mp4SDK
const { uploadUrl, readUrl, fileId } = await anonpaste.files.uploadPresigned({ fileName: 'video.mp4', contentType: 'video/mp4', fileSize: videoBlob.size,});
await fetch(uploadUrl, { method: 'PUT', body: videoBlob, headers: { 'Content-Type': 'video/mp4' },});Upload from URL (SDK only)
Section titled “Upload from URL (SDK only)”Download a remote file and store it on AnonPaste in one call.
const { fileId, readUrl } = await anonpaste.files.uploadFromUrl({ url: 'https://example.com/diagram.png', tags: ['diagrams'], expiresAt: '2026-12-31T23:59:59Z',});Get a file
Section titled “Get a file”GET /api/dev/files/get/:id
Section titled “GET /api/dev/files/get/:id”Returns file metadata and a presigned read URL. If burnAfterDownload was set, the file is deleted after this call.
curl
curl https://api.anonpaste.com/api/dev/files/get/a1b2c3d4e5f6g7h8 \ -H "x-api-key: your_api_key"Response
{ "success": true, "fileId": "a1b2c3d4e5f6g7h8", "fileName": "photo.jpg", "contentType": "image/jpeg", "fileSize": 45312, "tags": ["photos"], "readUrl": "https://r2.example.com/...", "createdAt": "2026-04-12T10:00:00.000Z", "burnAfterDownload": false, "expiresAt": null, "remaining": 499}SDK
const { readUrl, fileName, fileSize } = await anonpaste.files.get('a1b2c3d4e5f6g7h8');List files
Section titled “List files”GET /api/dev/files/list
Section titled “GET /api/dev/files/list”Query params
| Param | Type | Default | Description |
|---|---|---|---|
limit | number | 50 | Max results (max 100) |
offset | number | 0 | Pagination offset |
tag | string | – | Filter by a single tag |
curl
curl "https://api.anonpaste.com/api/dev/files/list?tag=photos&limit=20" \ -H "x-api-key: your_api_key"Response
{ "success": true, "files": [ { "fileId": "a1b2c3d4e5f6g7h8", "fileName": "photo.jpg", "contentType": "image/jpeg", "fileSize": 45312, "tags": ["photos"], "createdAt": "2026-04-12T10:00:00.000Z", "burnAfterDownload": false, "expiresAt": null } ], "totalCount": 42, "storageUsedBytes": 1073741824, "storageLimitBytes": 10737418240}SDK
const { files, totalCount, storageUsedBytes, storageLimitBytes } = await anonpaste.files.list({ tag: 'photos', limit: 20 });Delete a file
Section titled “Delete a file”DELETE /api/dev/files/delete/:id
Section titled “DELETE /api/dev/files/delete/:id”curl
curl -X DELETE https://api.anonpaste.com/api/dev/files/delete/a1b2c3d4e5f6g7h8 \ -H "x-api-key: your_api_key"Response
{ "success": true, "remaining": 199 }SDK
await anonpaste.files.delete('a1b2c3d4e5f6g7h8');Tags help you organise and filter files. Rules:
- Maximum 10 tags per file
- Each tag: lowercase alphanumeric characters and hyphens only
- Maximum 32 characters per tag
- Examples:
photos,user-uploads,2026-reports
Error codes
Section titled “Error codes”| Status | Reason | Description |
|---|---|---|
400 | fileName and contentType are required | Missing fields |
400 | Content type "..." is not allowed | Unsupported MIME type |
400 | Maximum 10 tags allowed | Too many tags |
400 | File size exceeds the 50MB limit | File too large |
400 | Invalid expiresAt date format | Malformed expiry date |
400 | Storage quota exceeded: ... insufficient credits | Over 10 GB and credit balance too low to cover overage |
403 | Access denied | File belongs to another account |
404 | File not found | File doesn’t exist or has expired/burned |