calcom/cal.diy · error · ForbiddenException

checkBookingRequiresAuthentication - user is not authorized

Error message

checkBookingRequiresAuthentication - user is not authorized to access this event type. User has to be either event type owner, host, team admin or owner or org admin or owner.

What it means

Thrown in checkBookingRequiresAuthenticationSetting when the event type requires auth, the request IS authenticated (authUser present), but eventTypeAccessService.userIsEventTypeAdminOrOwner returns false — the authenticated user is not the event type owner/host nor a team/org admin/owner. HTTP 403.

Source

Thrown at apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts:182

        `Can't book this team event type because it has no hosts. Please, add at least 1 host to event type with id=${eventTypeId} belonging to team with id=${eventType?.teamId} and try again.`
      );
    }
  }

  async checkBookingRequiresAuthenticationSetting(
    eventType: EventTypeWithOwnerAndTeam,
    authUser: AuthOptionalUser,
    userIsEventTypeAdminOrOwner: boolean
  ) {
    if (!eventType.bookingRequiresAuthentication) return true;
    if (!authUser) {
      throw new UnauthorizedException(
        "checkBookingRequiresAuthentication - request must be authenticated by passing credentials belonging to event type owner, host or team or org admin or owner."
      );
    }

    if (!userIsEventTypeAdminOrOwner) {
      throw new ForbiddenException(
        "checkBookingRequiresAuthentication - user is not authorized to access this event type. User has to be either event type owner, host, team admin or owner or org admin or owner."
      );
    }
  }

  async getBookedEventType(body: CreateBookingInput) {
    if (body.eventTypeId) {
      return await this.eventTypesRepository.getEventTypeByIdWithOwnerAndTeam(body.eventTypeId);
    } else if (body.username && body.eventTypeSlug) {
      const user = await this.usersRepository.findByUsername(body.username, body.organizationSlug);
      if (!user) {
        throw new NotFoundException(`User with username ${body.username} not found`);
      }
      return await this.eventTypesRepository.getUserEventTypeBySlugWithOwnerAndTeam(
        user.id,
        body.eventTypeSlug
      );
    } else if (body.teamSlug && body.eventTypeSlug) {

View on GitHub (pinned to 176037d0af)

Solutions

  1. Use credentials of an authorized user: event type owner, a host, or a team/org admin/owner.
  2. Grant the authenticated user the appropriate team-admin or org-admin/owner role.
  3. Confirm the authenticated user is still listed as owner/host of the event type.
Defensive patterns

Strategy: validation

Validate before calling

// Before booking a protected event type, confirm the caller is authorized.
const eventType = await api.get(`/v2/event-types/${eventTypeId}`);
if (eventType.bookingRequiresAuthentication) {
  // use credentials of the owner / host / team or org admin; otherwise expect 403
  if (!isOwnerOrAdmin(currentUser, eventType)) throw new Error('Caller is not authorized for this protected event type');
}

Try / catch

try {
  await api.post('/v2/bookings', body);
} catch (err) {
  if (err.status === 403 && /not authorized to access this event type/.test(err.message)) {
    // switch to an owner/admin token, or grant the user the required role
  }
  throw err;
}

Prevention

When it happens

Trigger: POST /v2/bookings with credentials of a user who lacks admin/owner rights over a bookingRequiresAuthentication event type.

Common situations: Using a regular member's credentials instead of an owner/admin; wrong team's API key; org member vs org admin role mismatch; host was removed from the event type.

Understand the failure class

Related errors


AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12). Data as JSON: /api/errors/3e502af51479812e. Report an issue: GitHub.