calcom/cal.diy · error · ForbiddenException
You are not authorized to book this event type. You must be
Error message
You are not authorized to book this event type. You must be the event type owner, a host, a team admin/owner, or an organization admin/owner.
What it means
A 403 Forbidden thrown by checkBookingRequiresAuthentication when the event type requires authentication, the caller is successfully authenticated (a valid user was resolved), but the user lacks authorization for this specific event type. Authorization is granted if the user is the event type owner, a listed host, a team admin/owner of the event type's team, or an organization admin/owner of the parent org.
Source
Thrown at apps/api/v2/src/platform/bookings/2024-04-15/controllers/bookings.controller.ts:492
const isEventTypeOwner = eventType.userId === userId;
const isHost = eventType.hosts.some((host) => host.userId === userId);
const isTeamAdminOrOwner = eventType.team?.members.some((member) => member.userId === userId) ?? false;
let isOrgAdminOrOwner = false;
if (eventType.team?.parentId) {
const orgTeam = await this.teamRepository.getTeamByIdIfUserIsAdmin({
userId,
teamId: eventType.team.parentId,
});
isOrgAdminOrOwner = !!orgTeam;
} else if (eventType.team?.isOrganization) {
isOrgAdminOrOwner = isTeamAdminOrOwner;
}
const isAuthorized = isEventTypeOwner || isHost || isTeamAdminOrOwner || isOrgAdminOrOwner;
if (!isAuthorized) {
throw new ForbiddenException(
"You are not authorized to book this event type. You must be the event type owner, a host, a team admin/owner, or an organization admin/owner."
);
}
}
private async getOAuthClientsParams(clientId: string, isEmbed = false): Promise<OAuthRequestParams> {
const res = { ...DEFAULT_PLATFORM_PARAMS };
if (isEmbed) {
// embed should ignore oauth client settings and enable emails by default
return { ...res, arePlatformEmailsEnabled: true, areCalendarEventsEnabled: true };
}
try {
const client = await this.oAuthClientRepository.getOAuthClient(clientId);
// fetch oAuthClient from db and use data stored in db to set these values
if (client) {
res.platformClientId = clientId;View on GitHub (pinned to 176037d0af)
Solutions
- Verify the authenticated user has one of: event type ownership, host membership, team admin/owner role, or org admin/owner role for this event type.
- If the user should be a host, add them to the event type's hosts list in the Cal.com dashboard or via the event types API.
- If the user should have team-level access, promote them to team admin or owner in the team settings.
- Confirm the correct eventTypeId is being requested — a typo can point to an event type the user has no relation to.
Example fix
// before — regular team member attempts to book restricted event type
POST /v2/bookings { eventTypeId: 42 }
// Authorization: Bearer <regular-member-token> -> 403
// after — either promote the user to team admin or use an authorized user's token
POST /v2/bookings { eventTypeId: 42 }
// Authorization: Bearer <team-admin-token> -> 200 Defensive patterns
Strategy: validation
Validate before calling
// Check if the user is authorized for the event type before booking
async function canUserBookEventType(userToken, eventTypeId) {
const res = await fetch(`/v2/event-types/${eventTypeId}`, {
headers: { Authorization: `Bearer ${userToken}` }
});
if (!res.ok) return false;
const { data } = await res.json();
// Verify the user is owner, host, or team/org admin
return data.userId === currentUserId || data.hosts?.some(h => h.userId === currentUserId);
}
if (!(await canUserBookEventType(token, eventTypeId))) {
throw new Error('User not authorized for this event type — request access from the team admin');
} Try / catch
try {
await api.createBooking({ eventTypeId, ... });
} catch (err) {
if (err.statusCode === 403) {
// Surface to the user that they need elevated permissions
console.error('Access denied. Request team admin or owner role for event type', eventTypeId);
}
throw err;
} Prevention
- Before booking, verify the authenticated user's role against the event type's team.
- Use the event types API to check hosts and team membership.
- Maintain a mapping of which users are authorized for which event types in your integration.
- When a user joins or leaves a team, update their API tokens' associated event types.
When it happens
Trigger: POST /v2/bookings or POST /v2/bookings/recurring with valid credentials against a restricted event type, where the authenticated user is: not the owner (eventType.userId mismatch), not in the eventType.hosts array, not a team member with admin/owner role, and not an org admin/owner of the parent organization.
Common situations: A user was added as a regular team member (not admin) and tries to book a restricted team event type. The event type was moved to a different team and the user's membership is stale. The user belongs to a child team but the org-level check requires parent org admin role. A host was removed from the event type but still has an API key.
Related errors
- Access denied. Either the team with ID=${teamId} does not ow
- BookingPbacGuard - user with id=${user.id} does not have acc
- checkBookingRequiresAuthentication - user is not authorized
- RolesGuard - user with id=${user.id} does not have the minim
- User is not authorized to update this booking location. User
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/3ce5846d953fb551.
Report an issue: GitHub.