7.5 KiB
7.5 KiB
HTTP API Reference
Endpoints
GET /api/health
- Description: Health check endpoint.
- Auth: None
- Query params: None
- Response:
{"status":"ok"}
GET /api/content/:cxid
- Description: Get content metadata (files, view limits, password status, etc.).
- Auth:
- None if the content has no password.
- Password required if the content has a password. Provide via query param
scor cookiecgcx_pw.
- Path params:
cxid— Content ID string.
- Query params:
sc(optional) — Password as a query string parameter.
- Response formats:
200 OK— JSON metadata object:{ "cxid": "string", "files": [ { "idx": 0, "name": "string", "mime": "string", "size": 12345, "render_flags": 0 } ], "has_password": true, "max_views": 10, "current_views": 3, "allow_download": true, "created_at": "2024-01-01T00:00:00+00:00", "total_size": 1234567, "author": { "username": "@example", "user_id": 123456789 } }401 Unauthorized— Password required but missing or invalid.404 Not Found— Content does not exist or has been deleted/blacklisted.410 Gone— Content has reached its maximum view count.
- Notes:
total_sizeis the sum of all file sizes in bytes.authoris gated by the content'sshow_authorflag. It isnullwhenshow_author = false, when the uploader's user record is missing, or when the user has no Telegram username (usernamemay benulleven whenuser_idis present).- If authentication succeeds via the
scquery parameter, the server sets an HMAC-signedcgcx_pwcookie on the response (Max-Age=3600; SameSite=Strict; HttpOnly; Path=/).
GET /api/content/:cxid/file/:file_idx
- Description: Serve a decrypted file. Supports HTTP Range requests for video/audio streaming. Returns the file with
Content-Disposition: inlineby default, orattachmentwhen downloading. - Auth:
- None if the content has no password.
- Password required if the content has a password. Provide via query param
scor cookiecgcx_pw.
- Path params:
cxid— Content ID string.file_idx— Zero-based file index within the content bundle.
- Query params:
sc(optional) — Password as a query string parameter.download(optional) — If truthy (1,true,yes), requests a download (Content-Disposition: attachment). Ignored ifallow_downloadisfalsefor the content.
- Response formats:
200 OK— File stream with appropriateContent-Type.206 Partial Content— Byte-range response (ifRangeheader is present and valid).401 Unauthorized— Password required but missing or invalid.403 Forbidden— Download requested but not allowed, or path traversal blocked.404 Not Found— Content or file index does not exist, or content deleted/blacklisted.410 Gone— Content has reached its maximum view count.416 Range Not Satisfiable— InvalidRangeheader.
- Notes:
- The server increments the view counter on successful full-file responses. Range requests,
If-None-Match(ETag) matches, and HEAD requests do not increment the counter. - If the incremented view count reaches
max_views, the server may delete content files (depending onkeep_contentconfig) and mark the content asDeleted, returning410 Gone. Accept-Ranges: bytesis included forvideo/*andaudio/*MIME types.- Cache-Control is
private, max-age=60for unprotected content andprivate, no-store, max-age=0for password-protected content. - If authentication succeeds via the
scquery parameter, the server sets an HMAC-signedcgcx_pwcookie on the response.
- The server increments the view counter on successful full-file responses. Range requests,
GET /api/content/:cxid/file/:file_idx/raw
- Description: Serve the fully decrypted file as raw plain text (
text/plain; charset=utf-8). The entire file is decrypted into memory before being returned. No Range support. - Auth:
- None if the content has no password.
- Password required if the content has a password. Provide via query param
scor cookiecgcx_pw.
- Path params:
cxid— Content ID string.file_idx— Zero-based file index within the content bundle.
- Query params:
sc(optional) — Password as a query string parameter.
- Response formats:
200 OK— Plain text body.401 Unauthorized— Password required but missing or invalid.403 Forbidden— Path traversal blocked.404 Not Found— Content or file index does not exist, or content deleted/blacklisted.410 Gone— Content has reached its maximum view count.
- Notes:
- The server performs BLAKE3 integrity verification after full decryption.
- If authentication succeeds via the
scquery parameter, the server sets an HMAC-signedcgcx_pwcookie on the response.
POST /api/content/:cxid/report
- Description: Report content for review. Creates a report record and forwards a notification to all configured review groups via the Telegram Bot API.
- Auth: None
- Path params:
cxid— Content ID string.
- Body: JSON object:
{ "reason": "string" } - Response formats:
204 No Content— Report accepted.404 Not Found— Content does not exist or has been deleted/blacklisted.
- Notes:
- The report is recorded with
reporter_user_id = 0to indicate a web-based report. - Rate limiting is covered by the general API governor.
- The report is recorded with
POST /api/content/:cxid/verify-password
- Description: Explicitly verify a password for password-protected content and receive an authentication cookie.
- Auth: None (this is the endpoint used to obtain auth).
- Path params:
cxid— Content ID string.
- Body: JSON object:
{ "password": "string" } - Response formats:
204 No Content— Password is correct. The response includes aSet-Cookieheader withcgcx_pw.401 Unauthorized— Password is incorrect.404 Not Found— Content does not exist.
- Notes:
- If the content has no password, the endpoint returns
204 No Contentwithout setting a cookie. - This endpoint has a separate, stricter rate limit than the general API.
- If the content has no password, the endpoint returns
General Behavior
CORS
The server allows cross-origin requests from its configured base_url and common local development origins (http://127.0.0.1:5173, http://localhost:5173, http://127.0.0.1:8090, http://localhost:8090).
Rate Limiting
- General API routes (
/api/health,/api/content/...) share a per-IP rate limit configured byrequests_per_minuteandburst. POST /api/content/:cxid/verify-passwordhas its own rate limit with a burst of 3 and a separatepassword_attempts_per_minutesetting.
Password Flow
- The
scquery parameter is checked on both the metadata endpoint (GET /api/content/:cxid) and the file endpoints (GET /api/content/:cxid/file/:file_idx,GET /api/content/:cxid/file/:file_idx/raw). When valid, the server sets an HMAC-signedcgcx_pwcookie on the response. - Passwords can also be provided via the
cgcx_pwcookie. - For programmatic verification, use
POST /api/content/:cxid/verify-password.
Fallback / Static Assets
/assets/*— Serves static files fromfrontend/dist/assets.- All other non-
/apipaths — Servesfrontend/dist/index.html(SPA fallback). /api/*paths with no matching route — Return404 Not FoundJSON.