API Docs

Upload, serve and delete files over plain HTTP. No account, no API key.

Open uploader

Quick start

Every file gets a permanent link at {{BASE}}/<id>.<ext>. Upload with one request, keep the returned url and deleteToken.

Base URLhttps://your-domain
Max per file50 MB
Max per upload200 MB
AuthNone
curl
curl -X POST {{BASE}}/upload \
  -F "file=@./photo.jpg"
POST/upload

Upload a file

One file per request, sent as multipart/form-data. To upload many files, send several requests (in parallel is fine).

FieldTypeDescription
file requiredfileThe file to upload. The field name must be exactly file.
batchTotalnumberTotal size in bytes of all files in the same batch. If it is above the per-upload limit, the request is rejected.

Response 200

json
{
  "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"
}
Save the deleteToken. It is returned only once and it is the only way to delete the file later.
GET/:filename

Open 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.

QueryDescription
download=1Forces a download using the original file name.
url
{{BASE}}/aB3xY9zK1q.jpg
{{BASE}}/aB3xY9zK1q.jpg?download=1
GET/api/files/:id

Get file info

Metadata for one file, by its id. There is no endpoint that lists files.

json
{
  "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"
  }
}
DELETE/api/files/:id

Delete a file

Send the deleteToken from the upload response in the x-delete-token header. A wrong or missing token returns 403.

curl
curl -X DELETE {{BASE}}/api/files/aB3xY9zK1q \
  -H "x-delete-token: YOUR_DELETE_TOKEN"

Response 200

json
{ "success": true, "message": "File berhasil dihapus" }
The older DELETE /i/:filename and old /i/… links still work for existing bots.
GET/api/stats

Site statistics

Total number of files and total bytes stored. Numbers only, never file names.

json
{ "success": true, "totalFiles": 42, "totalSize": 123456789 }
GET/api/config

Upload limits

Current limits and allowed extensions, so your client can validate before uploading.

json
{
  "maxFileSizeMb": 50,
  "maxTotalUploadSizeMb": 200,
  "allowedExt": ["gif", "jpg", "mp4", "pdf", "png", "zip", "…"]
}

Errors

Failed JSON requests look like { "success": false, "error": "…" }.

StatusMeaning
400No file field, file too large, extension not allowed, or batch total too large.
403Wrong or missing x-delete-token.
404File or endpoint not found.
416Invalid Range header.
500Unexpected server or storage error. Safe to retry.
502Could not read the file from storage.
504Timeout. Safe to retry.

Code examples

Node.js 18+
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 },
});

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.