Saurus CDN logoSaurus CDN

API documentation

Base URL: https://cdn.saurus.qzz.io. Every API response is JSON. Uploads need no key. Responses use the same envelope everywhere.

Upload

Method and pathDescription
POST /api/uploadUpload with mode=permanent|temp (default permanent).
POST /api/upload/permanentAlways permanent.
POST /api/upload/tempAlways temporary. Optional expires in seconds (60 to 2592000; default is the server's TEMP_EXPIRATION).

Send multipart/form-data with one to three file fields. Content-Length is required. Success returns 201 for a new file and 200 when identical content already exists (duplicate: true).

{
  "success": true,
  "data": {
    "id": "aB91",
    "url": "https://cdn.saurus.qzz.io/image/aB91.png",
    "type": "image",
    "name": "photo.png",
    "mime": "image/png",
    "size": 48213,
    "sha256": "9f86d0…",
    "permanent": false,
    "createdAt": "2026-10-06T10:00:00.000Z",
    "expiresAt": "2026-10-07T10:00:00.000Z",
    "duplicate": false,
    "deleteToken": "c1f0…"
  }
}

With several files the response is {"success":true,"data":{"files":[…]}} and each entry has its own success. deleteToken is returned only for newly stored files. Keep it if you want to delete the file later.

Look up and delete

Method and pathDescription
GET /api/file/:idFile metadata. The id may include the extension.
GET /api/file/:type/:filenameThe file itself, same as the public URL. type is image, video, audio or file.
DELETE /api/file/:idDelete. Send X-Delete-Token from the upload response, or an admin Authorization: Bearer header.

Serving and streaming

Files live at /image/<id>.<ext>, /video/…, /audio/… and /file/…. Images, video, audio and PDFs render inline. Archives download. HTML, PHP, JS and other code files are always delivered as text/plain with nosniff and a sandbox policy, so nothing uploaded can run on this origin. Add ?download=1 to force a download.

All files support Range: bytes=start-end and answer with 206 Partial Content, Content-Range and Accept-Ranges: bytes, so video seeks without downloading the whole file. Permanent files are cached for a year; temporary files are cached no longer than they have left, and expired files return 410.

Health and status

GET /api/health returns {"success":true,"data":{"status":"ok"}}. GET /api/status returns size limits and the current rate limit.

Examples

cURL

curl -F "file=@photo.png" https://cdn.saurus.qzz.io/api/upload/permanent

curl -F "file=@build.zip" -F "expires=3600" https://cdn.saurus.qzz.io/api/upload/temp

curl -X DELETE -H "X-Delete-Token: $TOKEN" https://cdn.saurus.qzz.io/api/file/aB91

curl -H "Range: bytes=0-1023" -o part.bin https://cdn.saurus.qzz.io/video/dHay.mp4

JavaScript (fetch)

const form = new FormData();
form.append('file', fileInput.files[0]);
form.append('mode', 'temp');
form.append('expires', '86400');

const res = await fetch('https://cdn.saurus.qzz.io/api/upload', { method: 'POST', body: form });
const json = await res.json();
if (!json.success) throw new Error(json.error.code + ': ' + json.error.message);
console.log(json.data.url);

Python

import requests

with open("photo.png", "rb") as f:
    r = requests.post(
        "https://cdn.saurus.qzz.io/api/upload/permanent",
        files={"file": ("photo.png", f)},
        timeout=60,
    )
body = r.json()
if r.status_code == 429:
    print("retry after", r.headers.get("Retry-After"))
elif body["success"]:
    print(body["data"]["url"])
else:
    print(body["error"])

Errors

Failures use this shape with a matching HTTP status:

{ "success": false, "error": { "code": "RATE_LIMITED", "message": "Too many requests" } }
CodeStatusMeaning
RATE_LIMITED429Slow down; see the Retry-After header (seconds).
FILE_TOO_LARGE413Over the size limit.
INVALID_EXTENSION400Missing or malformed file extension.
INVALID_FILE_CONTENT415Content does not match the extension (for example a .png that is not a PNG).
UNSUPPORTED_MEDIA_TYPE415Request was not multipart/form-data.
NO_FILE, EMPTY_FILE, MALFORMED_REQUEST400Missing, empty or unreadable upload.
NOT_FOUND404No such file.
EXPIRED410Temporary file has expired.
UNAUTHORIZED401Wrong delete token or admin secret.
STORAGE_ERROR, STORAGE_BUSY502, 503Storage backend problem. Retry later.

Limits

Default: 25 MB per file, 10 image or video uploads per 20 seconds per IP (other file types get three times that), up to 3 files per request. Temporary files last between 1 minute and 30 days. Identical content is stored once and the existing URL is returned. Do not upload anything you are not allowed to share.