Skip to content

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.


Free quota10 GB per account
Overage$0.03 / GB above the free quota
BandwidthFree — no cost to serve files
Per-file max50 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.


Two upload modes are supported:

Send the file as a base64-encoded string in the request body. Suitable for files up to 50 MB.

Request body

FieldTypeRequiredDescription
fileNamestringyesFile name with extension
contentTypestringyesMIME type
fileDatastringyesBase64-encoded file contents
tagsstring[]noUp to 10 tags
burnAfterDownloadbooleannoDelete on first download (default false)
expiresAtstring (ISO)noAuto-delete after this date

curl

Terminal window
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
});

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

FieldTypeRequiredDescription
fileNamestringyesFile name with extension
contentTypestringyesMIME type
fileSizenumberyesDeclared file size in bytes
tagsstring[]noUp to 10 tags
burnAfterDownloadbooleannoDelete on first download
expiresAtstring (ISO)noAuto-delete after this date

curl (step 1 – get presigned URL)

Terminal window
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)

Terminal window
curl -X PUT "https://r2.example.com/..." \
-H "Content-Type: video/mp4" \
--data-binary @video.mp4

SDK

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' },
});

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',
});

Returns file metadata and a presigned read URL. If burnAfterDownload was set, the file is deleted after this call.

curl

Terminal window
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');

Query params

ParamTypeDefaultDescription
limitnumber50Max results (max 100)
offsetnumber0Pagination offset
tagstringFilter by a single tag

curl

Terminal window
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 });

curl

Terminal window
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

StatusReasonDescription
400fileName and contentType are requiredMissing fields
400Content type "..." is not allowedUnsupported MIME type
400Maximum 10 tags allowedToo many tags
400File size exceeds the 50MB limitFile too large
400Invalid expiresAt date formatMalformed expiry date
400Storage quota exceeded: ... insufficient creditsOver 10 GB and credit balance too low to cover overage
403Access deniedFile belongs to another account
404File not foundFile doesn’t exist or has expired/burned