calcom/cal.com
tRPC
The Next.js front end's primary API. Every dashboard interaction, every public booking-page query, every settings save lands here. See packages/trpc for package details; this page describes the API surface.
Mount point
apps/web/pages/api/trpc/[trpc].ts is the single mount. It calls createNextApiHandler from packages/trpc/server/createNextApiHandler.ts which builds the per-request context ({ prisma, session, user, locale, req, res, sourceIp, ... }) and dispatches to the appropriate router.
Router groups
packages/trpc/server/routers/
├── _app.ts # Root router
├── viewer/ # Authenticated (most procedures)
├── loggedInViewer/ # Authenticated, user-scoped only
├── publicViewer/ # No auth (booking pages, public lookups)
└── features/ # Feature flagsWithin each group, every procedure is split into:
<action>.handler.ts— implementation<action>.schema.ts— Zod input schema<action>.handler.test.ts— Vitest test_router.tsx— registration
Notable procedure groups inside viewer/:
bookings/— list, cancel, reschedule, confirmeventTypes/— list, create, update, delete, reorder, duplicateavailability/— schedule CRUD, slot lookupcalendars/— selected/destination managementsettings/— profile, billing, notifications, securityapps/— App Store install/uninstall, per-app settingswebhooks/— outbound webhook subscriptionsappRoutingForms/— routing forms (some EE removed in Cal.diy)
publicViewer/ exposes:
event— load an event type by username + slug for the booking pagemarkHostAsNoShow— public link from a notificationsubmitRating— post-booking ratingcountryCode— best-guess country lookup for prefilling timezonecheckIfUserEmailVerificationRequiredtimezones— list
Authentication
- Session cookie —
getServerSession()(packages/features/auth/lib/getServerSession.ts) is called increateContext. Authenticated procedures use theauthedProcedurebuilder. - CSRF — protected by NextAuth's CSRF cookie.
- Public procedures use
publicProcedureand don't require a session.
Errors
Procedures throw TRPCError (from @trpc/server). Services they call throw ErrorWithCode (from packages/lib/errorCodes.ts). The error formatter (packages/trpc/server/errorFormatter.ts) unwraps both and translates Zod validation errors to readable messages. The client receives { code, message, data: { code, httpStatus, ... } }.
Rate limiting
packages/lib/rateLimit.ts implements a Redis-backed token-bucket limiter, applied via tRPC middleware. Critical procedures (signup, booking submit) have stricter limits.
Client
The React client lives at packages/trpc/react. Consumers do:
import { trpc } from '@calcom/trpc/react';
const { data } = trpc.viewer.bookings.list.useQuery({ status: 'upcoming' });
const reschedule = trpc.viewer.bookings.reschedule.useMutation();React Query is the underlying caching layer.
Example: a typical procedure
packages/trpc/server/routers/viewer/eventTypes/duplicate.handler.ts
packages/trpc/server/routers/viewer/eventTypes/duplicate.schema.ts
packages/trpc/server/routers/viewer/eventTypes/duplicate.handler.test.ts
packages/trpc/server/routers/viewer/eventTypes/_router.tsx (registers it)The handler validates input via Zod, calls a service in packages/features/eventtypes/services/, and returns the result. The handler stays thin; the service owns the business logic.
Related pages
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.