API Worker¶
workers/api/ in the platform repo, deployed at https://api.freedocstore.online/. It backs the creator console: sign-in, per-user workspace storage, BYOK secrets, and an authenticated proxy to GitHub and OpenAI. It serves no KB content — published pages come from Cloudflare Pages.
Sessions are cookie-based (HttpOnly, Secure), stored in FDS_API_KV with a 30-day TTL. CORS is restricted to the console origins and local dev hosts.
Endpoints¶
Service¶
| Method | Path | Description |
|---|---|---|
| GET | / |
Service info: name, public and editor base URLs |
| GET | /api/health |
Health check |
| GET | /api/me |
Current session: { authenticated, user } |
| GET | /api/billing |
Static free-plan descriptor (billingEnabled: false) |
Auth¶
| Method | Path | Description |
|---|---|---|
| GET | /auth/github/start |
Redirect to GitHub OAuth (read:user public_repo workflow scope, so publish and edits — including the deploy workflow file — run as the user). ?next= returns the user to the console after sign-in |
| GET | /auth/github/callback |
Exchanges the code, creates the session. The GitHub access token is kept in the session for the proxy |
| GET | /auth/google/start |
Redirect to Google OAuth (openid email profile) |
| GET | /auth/google/callback |
Exchanges the code, creates the session |
| POST | /api/logout |
Delete the session, clear the cookie |
| DELETE | /api/account |
Delete the user's workspace keys, stored secrets, and session |
Workspace KV¶
Per-user key-value storage; keys are namespaced per user (user_kv:<userId>:<key>), so users only ever see their own data. The console stores its workspace here: fds:config:v1 (settings), fds:kbs:v1 (KB drafts), fds:active-kb:v1 (active KB id). The MCP worker reads the same keys, which is why MCP workspace_summary matches what the console shows.
| Method | Path | Description |
|---|---|---|
| GET | /api/kv/<key> |
Read a value: { key, value } |
| PUT | /api/kv/<key> |
Write { value } |
| DELETE | /api/kv/<key> |
Delete the key |
Secrets (BYOK key vault)¶
Bring-your-own-key secrets are envelope-encrypted before landing in KV: a fresh per-key AES-256-GCM data key (DEK) encrypts the value, and the DEK is itself wrapped under the master KEK (FDS_KEY_ENCRYPTION_KEY). A DB read alone yields only ciphertext; reads return a redacted label, never the value. The envelope scheme is vendored from the FreeAppStore vault so both stores share one audited implementation.
Supported providers: OpenAI and Anthropic. Keys are resolved server-side inside the proxy — the plaintext key only ever exists on the worker during the upstream call.
| Method | Path | Description |
|---|---|---|
| GET | /api/secrets |
Which provider keys are configured (redacted labels), all providers |
| PUT | /api/secrets/:provider |
Store the user's key (openai or anthropic; format-validated) |
| DELETE | /api/secrets/:provider |
Remove it |
Publish¶
| Method | Path | Description |
|---|---|---|
| POST | /api/publish |
Server-side idempotent publish: create the KB repo (as the signed-in user), commit all source files in one commit, and register the KB in the public registry. Body: { title, slug, owner?, customDomain?, description?, files }; files must include .github/workflows/deploy.yml. Returns per-step results (repo, files, registry) so partial failures are visible and re-runs converge. Private visibility is rejected — private KBs belong in ProDocStore |
| POST | /api/edit |
Edit one file in a KB repo as the signed-in user. Body: { repo, path, content, message?, mode, branch? }; mode is pr (reviewable pull request) or direct (commit to branch). Backs the console's one-click Apply |
The Cloudflare Pages project is not created by the endpoint: the committed deploy workflow ensures its own Pages project on first run using the org-level Actions secrets, so the platform workers hold no Cloudflare credentials.
Proxy¶
| Method | Path | Description |
|---|---|---|
| ANY | /api/proxy?target=<url> |
Authenticated pass-through. Allowed targets: api.github.com, models.github.ai (the free GitHub Models AI tier, using the session GitHub token), api.openai.com (Bearer) and api.anthropic.com (x-api-key + anthropic-version) — BYOK keys injected server-side. Anything else is 403 |
GitHub authorization in the proxy is asymmetric by design: write methods use only the session's own GitHub token — repo creation and commits are always authored by the signed-in user, never a shared platform identity. Read methods prefer the session token and fall back to the platform GITHUB_TOKEN. A write without a GitHub-backed session returns 403 with instructions to sign in with GitHub.
The proxy is what lets the console's AI editing flow call OpenAI with the user's own key, and read/propose against GitHub, without shipping any secret to the browser.
Bindings and secrets¶
| Name | Kind | Purpose |
|---|---|---|
FDS_API_KV |
KV namespace | Sessions, per-user workspace, encrypted secrets |
GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET |
secret | Console GitHub OAuth app |
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET |
secret | Console Google OAuth app |
GITHUB_TOKEN |
secret (optional) | Platform fallback for GitHub proxy reads only; writes always use the session token |
PUBLIC_BASE_URL, EDITOR_BASE_URL |
var | Site and console origins |