cf-share API

share.022025.xyz · Anonymous file sharing. Upload via presigned S3 URL, get a 4-char share link.

Endpoints

POST /api/upload/init — Reserve upload URL

FieldTypeDescription
filenamestringRequired. Max 500 chars.
sizeintegerRequired. 1 – 5,368,709,120 bytes.
contentTypestringRequired. MIME type.
ttlintegerOptional. 300–604800s. Default: 86400 (24h).
passwordstringOptional. Password-protect the share (1-256 chars).

Returns uploadId, key, url (presigned PUT, 10min valid), and mode ("single" for small files, "multipart" with parts array for large files).

PUT {url} — Upload to S3

Send file body bytes directly to S3 with the presigned URL. For single mode, set Content-Type from init response. Multipart parts need no headers. Capture the ETag response header.

POST /api/upload/complete — Mint share token

FieldDescription
uploadId, key, filename, size, contentType, ttl, passwordSame as init.
etagRequired for single mode. From S3 PUT response.
mode = "multipart", s3UploadId, partsRequired for multipart mode. Array of {partNumber, etag}.

Returns {shareToken, shareUrl, fullUrl, expiresAt}. Token is 4 chars [0-9A-Z] (extends to 5–6 on collision).

GET /api/download/:token — Download

Without query: 302 redirect to presigned S3 GET URL (valid 300s).
?info=1 — Returns JSON metadata (filename, size_bytes, expires_at, has_password).
?password=X — Provide password for protected shares.

POST /api/download/:token — Password verification

Body: {password: string}. Returns {verified: true, downloadUrl} on success, 401 on wrong password.

GET /api/health — Health check

Returns {status, db, s3, limits}.

Admin endpoints (HTTP Basic Auth, S3 credentials)

GET /d/:token — Download page (HTML)

Renders a human-friendly download page with filename, size, expiry countdown, and download button. Password-protected shares show a password prompt.


Limits

LimitValue
Max file size5 GB
TTL range5 min – 7 days
Default TTL24 hours
Per-IP daily upload10 GB total / 100 files
S3 pool total100 GB (all active shares)
Presigned PUT expiry10 min
Presigned GET expiry5 min
File typesAny (no restrictions)
Rate limits (per IP, 60s window)30 init / 30 complete / 60 download / 30 lookup

Quick start (cURL)

# 1. Init
INIT=$(curl -fsS -X POST "https://share.022025.xyz/api/upload/init" \
  -H "Content-Type: application/json" \
  -d '{"filename":"photo.jpg","size":1048576,"contentType":"image/jpeg","ttl":86400}')
URL=$(echo "$INIT" | sed -n 's/.*"url":"\([^"]*\)".*/\1/p')
KEY=$(echo "$INIT" | sed -n 's/.*"key":"\([^"]*\)".*/\1/p')
UID=$(echo "$INIT" | sed -n 's/.*"uploadId":"\([^"]*\)".*/\1/p')

# 2. PUT to S3 (capture ETag)
ETAG=$(curl -fsS -X PUT "$URL" -H "Content-Type: image/jpeg" --data-binary "@photo.jpg" \
  -D - | tr -d '\r' | awk 'tolower($1)=="etag:" {gsub(/"/,"",$2); print $2}')

# 3. Complete
curl -fsS -X POST "https://share.022025.xyz/api/upload/complete" \
  -H "Content-Type: application/json" \
  -d "{\"uploadId\":\"$UID\",\"key\":\"$KEY\",\"filename\":\"photo.jpg\",\"size\":1048576,\"contentType\":\"image/jpeg\",\"etag\":\"$ETAG\",\"ttl\":86400}"

# 4. Download
curl -fsSL "https://share.022025.xyz/d/ABCD" -o downloaded-file