api documentation
all endpoints are relative to the base url
/api/uploadupload a file. returns the file id.
body
multipart/form-data with a file field
query parameters
slug—optional. custom short url (alphanumeric only)captcha—turnstile token (required for files >100MB if configured)encrypted—set to 1 if file is client-side encryptedsalt—hex-encoded 16-byte encryption salt (required if encrypted)iv—hex-encoded 12-byte encryption IV (required if encrypted)response
{
"uploadedId": "uuid"
}errors
400 — missing file, invalid slug, or invalid encryption params
403 — captcha required or failed
413 — file exceeds 2GB limit
example
curl -X POST \ -F "file=@photo.jpg" \ "https://example.com/api/upload?slug=myphoto"
/api/download/:iddownload a file by its id. redirects to a presigned s3 url (1 hour expiry).
query parameters
raw—set to 1 to get the presigned url as json instead of a 302 redirectdefault response
302 redirect to presigned s3 url
raw response
{
"url": "https://s3.../presigned-url"
}errors
404 — file not found
410 — file has expired
example
# direct download (follows redirect) curl -L -o file.jpg \ "https://example.com/api/download/UUID" # get presigned url curl "https://example.com/api/download/UUID?raw=1"
/api/slug-checkcheck if a custom slug is available.
query parameters
slug—the slug to check (alphanumeric only)response
{
"available": true
}/:slugshort url redirect. resolves a slug to its file view page.
response
307 redirect to /viewfile/:id
/viewfile/:idfile info page. shows metadata, expiry, and download button. for encrypted files, prompts for password and decrypts in-browser.
notes
- — files expire after 24 hours
- — max file size is 2GB
- — uploads over 100MB may require captcha verification
- — rate limited to 5 uploads per 10 minutes
- — encryption is client-side (AES-256-GCM + PBKDF2). the server never sees the password or plaintext
- — presigned download urls expire after 1 hour