6.0 KiB
6.0 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" }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:
- If authentication succeeds via the
scquery parameter, the server sets an HMAC-signedcgcx_pwcookie on the response (Max-Age=3600; SameSite=Strict; HttpOnly; Path=/).
- If authentication succeeds via the
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 and
If-None-Match(ETag) matches 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 and
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/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.
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.