Developers & Integrations
API Reference
The /api/* routes every client talks to.
Every API route lives in apps/web/src/app/api/ — there is no separate
API server. Both native apps and every webhook integration call into this
same set of routes.
Route families
/api/portal/*— the customer portal's own backend, also reused verbatim by the native customer app (apps/customer) rather than being duplicated./api/mobile/*— the staff companion app's backend (apps/mobile), authenticated againstStaffMemberrecords via the staff Clerk application./api/webhooks/stripe— receives real-time payment and subscription events from Stripe. See Payment Issues if events aren't arriving./api/cron/*— scheduled jobs, registered inapps/web/vercel.json(not a repo-rootvercel.json— that's a real, previously-hit gotcha). Each cron route checks a bearer-token secret rather than relying on network-level trust.- Public route actions — the public pages (
/book,/day-pass, the registered-office signup, the guided office-inquiry funnel) use Next.js server actions rather than a separate REST surface for their own mutations.
Authentication
- Staff routes check the caller against an active
StaffMembervia the staff Clerk application's session. - Portal/customer routes check against a
Customervia the customer Clerk application's session — a completely separate app and secret key from staff, see Security & Access Model. - No-login mail-action links and payment-setup links use a possession-based token instead of a session — knowing the token is the authorization, the same pattern used everywhere in this codebase for a resumable, unauthenticated link.
Extending the API
New backend logic goes in packages/shared, not directly in a route
handler — routes should stay thin wrappers that check auth, call a shared
function, and shape the response. See
Extending the Platform.