Procedure selection
| Procedure | Use |
|---|---|
| publicProcedure | Public boot or health data, with captured-scope checks when supplied |
| protectedProcedure | An authenticated User's personal data |
| orgProcedure | Shared data in the membership-checked Active Organization |
| adminProcedure | Global reads requiring the current platform admin role |
| adminWriteProcedure | Admin writes through Better Auth's audited capability |
Routers live in packages/api/src/routers. Each feature separates its Zod schemas from the server implementation. Register the router in routers/index.ts. Browser and mobile clients use the type-only api/client export and the corresponding safe schema subpath.
Add an operation
- Define input and output schemas, including bounded pagination and text limits.
- Choose the procedure according to the resource owner.
- Apply Organization scope in every relevant query and mutation.
- Keep the mutation and Audit Event in one transaction when the operation is audited.
- Add any cross-package schema export explicitly, then consume it through a hook.
The HTTP endpoint is /api/rpc. The session-authenticated OpenAPI reference is at /api/rpc/api-reference, with its specification at /api/rpc/api-reference/spec.json.
Client state
TanStack Query owns server data, query keys and invalidation. Forms use TanStack Form. URL state expresses Todo views, filters and sorting. Components render the hook's state; they do not recreate authentication or authorization decisions.
Validate external payloads at the boundary. Use the shared error vocabulary and translated resolver rather than returning internal exceptions. Do not create a parallel REST API for a domain operation already represented by oRPC.