API and tRPC
Fast Unicorn uses tRPC as the main typed API layer and Next.js route handlers for selected integrations.
This split keeps app-facing contracts strongly typed while still leaving room for HTTP-first entrypoints like webhooks and external provider callbacks.
How to read this feature
Use this page to understand the API architecture. If you want to change auth or billing behavior specifically, continue with Configure Auth or Configure Stripe.
What this feature includes
Procedure boundaries
The API layer separates public, authenticated, and role-aware access through reusable procedure types.
Router organization
Feature-specific routers keep contracts grouped by domain instead of scattering mutations across the app.
Hybrid entrypoints
tRPC handles app-facing contracts while route handlers remain available for integrations that need raw HTTP boundaries.
Main files and folders
- src/server/api/trpc.ts: Shared procedure types and API context.
- src/server/api/root.ts: Root router composition.
- src/server/api/routers/customAuth.ts: Authentication-facing mutations and flows.
- src/server/api/routers/stripe.ts: Billing-facing procedures.
- src/server/api/routers/user.ts: User-oriented contracts.
- src/app/api/trpc/[trpc]/route.ts: Next.js route handler that exposes the tRPC API.
Procedure types
The current API layer exposes:
publicProcedureprotectedProcedureadminProcedure
These are defined in src/server/api/trpc.ts.
Each procedure type gives the app a consistent place to apply access rules before request logic reaches the domain layer.
Current routers
The root router currently includes:
useCustomAuthuseStripeuseUser
These routers define the transport-facing API shape, while reusable business logic continues to live in src/server/services.
What tRPC is used for
Use tRPC when you want:
- type-safe queries and mutations
- authenticated server actions for app features
- shared server contracts across frontend and backend
Good default
If the request comes from your own application UI and benefits from shared typing, tRPC is usually the right first choice.
What still uses route handlers
Some integration boundaries remain in src/app/api, especially where third-party webhooks or HTTP-first entrypoints make more sense.
Examples:
- Stripe checkout route
- Stripe webhook route
- NextAuth route handler
Those boundaries are kept explicit so external systems can talk to the app without forcing everything through the same transport shape.
Recommended convention
- keep transport concerns in routers and route handlers
- keep domain logic in
src/server/services - keep permission checks in procedures and service helpers
This structure keeps the API readable, predictable, and easier to extend as the product grows.