API Docs
Upload, serve and delete files over plain HTTP. No account, no API key.
Quick start
Every file gets a permanent link at {{BASE}}/<id>.<ext>. Upload with one request, keep the returned url and deleteToken.
curl -X POST {{BASE}}/upload \
-F "file=@./photo.jpg"
/uploadUpload a file
One file per request, sent as multipart/form-data. To upload many files, send several requests (in parallel is fine).
| Field | Type | Description |
|---|---|---|
file required | file | The file to upload. The field name must be exactly file. |
batchTotal | number | Total size in bytes of all files in the same batch. If it is above the per-upload limit, the request is rejected. |
Response 200
{
"success": true,
"id": "aB3xY9zK1q",
"filename": "aB3xY9zK1q.jpg",
"originalName": "photo.jpg",
"size": 102400,
"mimeType": "image/jpeg",
"url": "{{BASE}}/aB3xY9zK1q.jpg",
"deleteToken": "…32 random characters…",
"createdAt": "2026-09-25T08:10:40.403Z"
}
deleteToken. It is returned only once and it is the only way to delete the file later./:filenameOpen or download a file
Public link, safe to embed in sites, bots and chats. Responses are cached for a year since file names are never reused. HTTP Range is supported, so video and audio can be scrubbed.
| Query | Description |
|---|---|
download=1 | Forces a download using the original file name. |
{{BASE}}/aB3xY9zK1q.jpg
{{BASE}}/aB3xY9zK1q.jpg?download=1
/api/files/:idGet file info
Metadata for one file, by its id. There is no endpoint that lists files.
{
"success": true,
"file": {
"id": "aB3xY9zK1q",
"filename": "aB3xY9zK1q.jpg",
"originalName": "photo.jpg",
"ext": "jpg",
"mimeType": "image/jpeg",
"size": 102400,
"url": "{{BASE}}/aB3xY9zK1q.jpg",
"createdAt": "2026-09-25T08:10:40.403Z"
}
}
/api/files/:idDelete a file
Send the deleteToken from the upload response in the x-delete-token header. A wrong or missing token returns 403.
curl -X DELETE {{BASE}}/api/files/aB3xY9zK1q \
-H "x-delete-token: YOUR_DELETE_TOKEN"
Response 200
{ "success": true, "message": "File berhasil dihapus" }
DELETE /i/:filename and old /i/… links still work for existing bots./api/statsSite statistics
Total number of files and total bytes stored. Numbers only, never file names.
{ "success": true, "totalFiles": 42, "totalSize": 123456789 }
/api/configUpload limits
Current limits and allowed extensions, so your client can validate before uploading.
{
"maxFileSizeMb": 50,
"maxTotalUploadSizeMb": 200,
"allowedExt": ["gif", "jpg", "mp4", "pdf", "png", "zip", "…"]
}
Errors
Failed JSON requests look like { "success": false, "error": "…" }.
| Status | Meaning |
|---|---|
| 400 | No file field, file too large, extension not allowed, or batch total too large. |
| 403 | Wrong or missing x-delete-token. |
| 404 | File or endpoint not found. |
| 416 | Invalid Range header. |
| 500 | Unexpected server or storage error. Safe to retry. |
| 502 | Could not read the file from storage. |
| 504 | Timeout. Safe to retry. |
Code examples
import { readFile } from "node:fs/promises";
const form = new FormData();
form.append("file", new Blob([await readFile("./photo.jpg")]), "photo.jpg");
const res = await fetch("{{BASE}}/upload", { method: "POST", body: form });
const data = await res.json();
if (!data.success) throw new Error(data.error);
console.log(data.url); // share this
console.log(data.deleteToken); // keep this
// later: delete it
await fetch(`{{BASE}}/api/files/${data.id}`, {
method: "DELETE",
headers: { "x-delete-token": data.deleteToken },
});
import requests
with open("photo.jpg", "rb") as f:
r = requests.post("{{BASE}}/upload", files={"file": f})
data = r.json()
if not data["success"]:
raise RuntimeError(data["error"])
print(data["url"]) # share this
print(data["deleteToken"]) # keep this
# later: delete it
requests.delete(
f"{{BASE}}/api/files/{data['id']}",
headers={"x-delete-token": data["deleteToken"]},
)
Limits & notes
- Max 50 MB per file and 200 MB per upload.
- Allowed extensions: images, video, audio, documents and archives
- Links are permanent. Files stay until deleted with their token.
- File ids are random, but every file is public: anyone with the link can open it.
- There is no endpoint to list files. Keep your own record of the links and delete tokens.