Almost every route runs through a security wrapper (apiSecurity.* / withSecurity()) that enforces a rate limit, method/content-type validation, and a body-size cap. Tiers: public() 30/min no-auth · authenticated() 30/min · admin() 5/min + is_admin · ai() 10/min · webhook() 100/min + signature. State-changing requests (POST/PATCH/PUT/DELETE) additionally require CSRF (Origin/Referer + token). Errors return a typed envelope — { "error": "message", "code": "ERROR_CODE" } — with codes from core/*/error-codes.ts (never raw internals). Feature-gated domains (referrals, affiliates, error logs) return 404 when disabled, not 403.
Exceptions to the wrapper
Two endpoints intentionally bypass apiSecurity.*: /api/ai/stream uses raw POST + manual rateLimiters.ai(user.id:ip) + validateOrigin() so it can stream Server-Sent Events; /api/health is a public GET with no rate limit so a load balancer can probe it cheaply.
Authentication
Endpoint
Method
Description
/api/auth/magic-link
POST
Send magic-link email (link + 6-digit OTP code)
/api/auth/verify-otp
POST
Verify the 6-digit code from the magic-link email (alternate path to clicking the link)
End a trialing subscription early and unlock full plan credits
/api/billing/current-plan
GET
Resolve the active plan for the current account (subscription preferred over license in hybrid mode)
/api/stripe/webhook
POST
Stripe webhook handler
AI
Endpoint
Method
Description
/api/ai/stream
POST
Streaming AI response (SSE)
/api/ai/config
GET
AI configuration
Chat
Endpoint
Method
Description
/api/chat/sessions
GET
List sessions
/api/chat/sessions
POST
Create session
/api/chat/sessions/[id]
GET
Get session with messages
/api/chat/sessions/[id]
PATCH
Update session
/api/chat/sessions/[id]
DELETE
Delete session
User
Endpoint
Method
Description
/api/user/export-data
GET
GDPR data export (multi-section CSV)
/api/user/sessions
GET
List recent login sessions
/api/user/sessions
DELETE
Revoke all other sessions
/api/user/log-activity
POST
Log user activity event
/api/user/onboarding
POST
Validate and store onboarding profile fields server-side
Invitations
Endpoint
Method
Description
/api/invitations/accept
POST
Accept workspace invitation
/api/invitations/resend
POST
Resend invitation email (owner/admin)
/api/invitations/revoke
POST
Revoke a pending workspace invitation (owner/admin)
Organization
Endpoint
Method
Description
/api/org/schedule-deletion
POST
Schedule org deletion (30-day grace)
/api/org/cancel-deletion
POST
Cancel pending org deletion
/api/org/settings
PATCH
Update workspace name/slug through a validated server boundary
CMS (Admin)
Endpoint
Method
Description
/api/admin/cms/pages
GET
List all CMS pages
/api/admin/cms/pages
POST
Create page
/api/admin/cms/pages
PATCH
Update page
/api/admin/cms/pages?id=xxx
DELETE
Delete page
/api/admin/cms/blocks
GET
List all blocks
/api/admin/cms/blocks
POST
Create block
/api/admin/cms/blocks
PATCH
Update block
/api/admin/cms/blocks?id=xxx
DELETE
Delete block (query param is id, the block's UUID)
/api/admin/cms/media
GET
List media files
/api/admin/cms/media
POST
Upload file
/api/admin/cms/media
PATCH
Rename file
/api/admin/cms/media?path=xxx
DELETE
Delete file
/api/admin/cms/categories
GET
List all blog categories (with usage counts)
/api/admin/cms/categories
POST
Create category
/api/admin/cms/categories/[id]
PATCH
Update category
/api/admin/cms/categories/[id]
DELETE
Delete category
/api/admin/cms/tags
GET
List all blog tags (with usage counts)
/api/admin/cms/tags
POST
Create tag
/api/admin/cms/tags/[id]
PATCH
Update tag
/api/admin/cms/tags/[id]
DELETE
Delete tag
Jobs
Endpoint
Method
Description
/api/jobs/run
POST
Execute a job (cron/manual/api). Dual auth: Authorization: Bearer JOBS_SECRET_KEY (constant-time compared, webhook rate limit) OR an admin user session with Origin/CSRF validation and strict rate limiting.
/api/admin/jobs
GET
List all jobs
/api/admin/jobs
POST
Create job
/api/admin/jobs/[jobId]
PATCH
Update job
/api/admin/jobs/[jobId]
DELETE
Delete job
/api/admin/jobs/handlers
GET
List all handlers (code + webhook)
/api/admin/jobs/handlers
POST
Create webhook handler
/api/admin/jobs/handlers/[handlerId]
GET
Read a single webhook handler
/api/admin/jobs/handlers/[handlerId]
PATCH
Update webhook handler
/api/admin/jobs/handlers/[handlerId]
DELETE
Delete webhook handler
Notifications
Endpoint
Method
Description
/api/notifications
GET
Fetch latest 50 notifications
/api/notifications
PATCH
Mark notifications as read
API Keys
Endpoint
Method
Description
/api/account/api-keys
GET
List API keys
/api/account/api-keys
POST
Create API key
/api/account/api-keys
DELETE
Revoke API key
Knowledge Base / Documents (RAG)
Endpoint
Method
Description
/api/documents
GET
List documents
/api/documents
POST
Upload document (multipart). Triggers async processing with credit deduction.
/api/documents
DELETE
Delete document + chunks + storage
/api/documents/[id]
GET
Document details + chunks
Changelog (Admin)
Endpoint
Method
Description
/api/admin/changelog
GET
List changelog entries
/api/admin/changelog
POST
Create changelog entry
/api/admin/changelog
PATCH
Update changelog entry
/api/admin/changelog
DELETE
Delete changelog entry
Referrals
Account-centric referral program. Every endpoint returns 404 when REFERRAL_ENABLED is off (surface invisibility).
Endpoint
Method
Security
Description
/api/referral/code
GET
authenticated · standard
Lazy-create the account's active referral code
/api/referral/stats
GET
authenticated · standard
Dashboard counters
/api/referral/list
GET
authenticated · standard
Cursor-paginated referrals
/api/referral/apply
POST
authenticated + CSRF · strict
Manually apply a referral code
/api/referral/attribute
POST
authenticated + CSRF · strict
Cookie-based attribution (called from onboarding)
/[locale]/refer/[code]
GET
public · relaxed
Tracking redirect — sets the bsk_ref cookie
/api/admin/referrals
GET
admin · strict
Filterable list
/api/admin/referrals/stats
GET
admin · strict
Aggregate KPIs
/api/admin/referrals/[id]
GET
admin · strict
Detail + audit trail
/api/admin/referrals/[id]/reverse
POST
admin + CSRF · strict
Clawback granted credits
/api/admin/referrals/[id]/reject
POST
admin + CSRF · strict
Reject a pending referral
/api/admin/referral-codes
GET
admin · strict
Codes + usage counts
/api/admin/referral-codes/[id]/deactivate
POST
admin + CSRF · strict
Deactivate a code
Affiliates
Cash-commission partner program (distinct from referrals). Every endpoint returns 404 when AFFILIATES_ENABLED is off.
Tracking redirect — sets bsk_aff cookie + records click
/api/admin/affiliates/applications/[id]/approve
POST
admin + CSRF · strict
Approve at a tier (defaults to config defaultTierSlug)
/api/admin/affiliates/applications/[id]/reject
POST
admin + CSRF · strict
Reject with sanitized reason
/api/admin/affiliates/conversions/[id]/reverse
POST
admin + CSRF · strict
Manual conversion clawback (fraud / dispute)
Push Notifications
Endpoint
Method
Security
Description
/api/push/subscribe
POST
authenticated
Register a push subscription (with device name)
/api/push/unsubscribe
POST
authenticated
Remove a push subscription
/api/push/vapid-key
GET
public
Fetch the VAPID public key (browser subscription)
/api/push/preferences
GET
authenticated
Get notification preferences
/api/push/preferences
PATCH
authenticated
Update preferences / quiet hours
/api/push/track
POST
authenticated
Track interaction (click / dismiss / view)
Error Logs (Admin)
Endpoint
Method
Security
Description
/api/admin/logs
GET
admin · 5/min
Cursor-paginated error logs (Zod-validated filters). 404 when LOGS_ENABLED is off. Read-only — no write endpoints.
Public & Misc
Endpoint
Method
Security
Description
/api/contact
POST
public + Turnstile · contact (3/min)
Contact form (queues on provider failure)
/api/newsletter/subscribe
POST
public + Turnstile · standard
Newsletter signup
/api/newsletter/unsubscribe
POST
authenticated + CSRF · strict
Unsubscribe the current authenticated user from the newsletter. Public email links need a separate signed-token route.
/api/locale
POST
public
Persist locale preference cookie
/api/health
GET
none
Health check (use for uptime monitoring / load-balancer probes)
Admin & Platform
Super-admin surface — all admin-gated (5/min, is_admin) with CSRF on state-changing calls. Sensitive actions that change access, billing, credits, retention, or destructive state also require recent auth and write immutable audit rows.
Purge orphaned pg_cron entries that no longer match any jobs row
Non-admin routes previously grouped here have moved to their correct sections:
/api/billing/current-plan → Billing ·
/api/locale → Public & Misc ·
/api/org/cancel-deletion → Organizations.