The Portal acts as a Backend for Frontend (BFF) proxy. The browser does not communicate directly with the database (AllCodex Core) or the parsing brain (AllKnower). It sends requests to /api/* on the Portal, which parses authentication cookies server-side and forwards requests to private backends.
Credential flow
All backend calls resolve credentials from HTTP-only cookies via getEtapiCreds() and getAkCreds() (defined in lib/get-creds.ts). If cookies are not set, the route falls back to environment variables in .env.local. The browser does not receive tokens.
Zero-login auto-provisioning: In dev/zero-login deployments, the auto-provisioning middleware sets the AllKnower token cookie, and Core credentials are bootstrapped into the default user’s UserIntegration — so neither step above is required for the first user.
Lore CRUD
These routes proxy requests directly to the AllCodex Core ETAPI.
POST /api/lore — create note example
Note attributes and relationships
POST /api/lore/[id]/attributes — create label
POST /api/lore/[id]/attributes — create relation
Note content, revisions, and media
Lore tree operations
POST /api/lore/move
POST /api/lore/upload-image
Send binary image body. Set x-vercel-filename header for the file name.
Search and discovery
POST /api/lore/autolink
Returns:
Brain dump
POST /api/brain-dump
Modes:
auto — extract and write entities immediately
review — extract entities and return as proposals for user approval
inbox — queue the raw text for later processing
POST /api/brain-dump/commit
POST /api/ai/consistency
PUT /api/ai/relationships — apply
RAG
Content collections
These routes query AllCodex ETAPI for notes with specific labels.
Share settings
GET /api/share/tree — response fields
Each note includes: noteId, title, isDraft, isGmOnly, shareAlias, isProtected, isShared.
Public share endpoints
These routes power the Portal’s public-facing site (/ and /public/lore/[id]) and do not require authentication. They only return content from the configured #shareRoot subtree, and they strip notes tagged #draft or #gmOnly. Use them to embed AllCodex lore in your own website or to integrate a campaign wiki with other tools.
GET /api/public/lore/[id] — example response
Configuration and auth
Import
Notifications
Web-push notifications (e.g. brain dump completion status).
Usage and budgets
Key developer patterns
- Proxy architecture: Every
/api/* route is a thin proxy. No domain logic lives in the Portal.
- Error handling: Routes call
notConfigured() when credentials are missing and handleRouteError() for exceptions.
- HTML sanitization: The Portal performs DOMPurify sanitization. Do not assume content from ETAPI is safe for direct HTML insertion.
- Content-Type constraint: PUT requests to
/api/lore/[id]/content must use Content-Type: text/plain due to Express raw-parser behavior in Core.
- Cookie-only secrets: The system stores all tokens in HTTP-only cookies. Browser JavaScript does not have access to credentials.