{"record":{"id":"a33c2ebf16e7e8ba","repo":"calcom/cal.diy","slug":"checkbookingrequiresauthentication-request-must","errorCode":null,"errorMessage":"checkBookingRequiresAuthentication - request must be authenticated by passing credentials belonging to event type owner, host or team or org admin or owner.","messagePattern":"checkBookingRequiresAuthentication - request must be authenticated by passing credentials belonging to event type owner, host or team or org admin or owner\\.","errorType":"exception","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts","lineNumber":176,"sourceCode":"  }\n\n  async checkEventTypeHasHosts(eventTypeId: number) {\n    const eventType = await this.eventTypesRepository.getEventTypeWithHosts(eventTypeId);\n    if (!eventType?.hosts?.length) {\n      throw new UnprocessableEntityException(\n        `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.`\n      );\n    }\n  }\n\n  async checkBookingRequiresAuthenticationSetting(\n    eventType: EventTypeWithOwnerAndTeam,\n    authUser: AuthOptionalUser,\n    userIsEventTypeAdminOrOwner: boolean\n  ) {\n    if (!eventType.bookingRequiresAuthentication) return true;\n    if (!authUser) {\n      throw new UnauthorizedException(\n        \"checkBookingRequiresAuthentication - request must be authenticated by passing credentials belonging to event type owner, host or team or org admin or owner.\"\n      );\n    }\n\n    if (!userIsEventTypeAdminOrOwner) {\n      throw new ForbiddenException(\n        \"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.\"\n      );\n    }\n  }\n\n  async getBookedEventType(body: CreateBookingInput) {\n    if (body.eventTypeId) {\n      return await this.eventTypesRepository.getEventTypeByIdWithOwnerAndTeam(body.eventTypeId);\n    } else if (body.username && body.eventTypeSlug) {\n      const user = await this.usersRepository.findByUsername(body.username, body.organizationSlug);\n      if (!user) {\n        throw new NotFoundException(`User with username ${body.username} not found`);","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts#L158-L194","documentation":"Thrown in checkBookingRequiresAuthenticationSetting when the event type has bookingRequiresAuthentication = true and the request carries no authenticated user (authUser is null). Protected event types require credentials; an anonymous public booking is refused with HTTP 401.","triggerScenarios":"POST /v2/bookings against an event type whose bookingRequiresAuthentication is enabled, without an Authorization header / API key (the public, unauthenticated booking path).","commonSituations":"Embed/public booking flow pointed at a protected event type; client forgot to send the access token; event type flipped to require-auth after the integration was built.","solutions":["Authenticate the request by sending a valid access token or API key for an authorized user.","If public booking is intended, disable bookingRequiresAuthentication on the event type.","Confirm the event type's require-auth flag before building the public flow."],"exampleFix":"// before\nawait api.post('/v2/bookings', body); // no Authorization header, protected event type\n// after\nawait api.post('/v2/bookings', body, { headers: { Authorization: `Bearer ${token}` } });","handlingStrategy":"validation","validationCode":"// Before booking a protected event type anonymously, check its require-auth flag.\nconst eventType = await api.get(`/v2/event-types/${eventTypeId}`);\nif (eventType.bookingRequiresAuthentication && !hasToken()) {\n  throw new Error('Event type requires authentication; provide an access token or API key');\n}","typeGuard":"function eventTypeRequiresAuth(et: { bookingRequiresAuthentication?: boolean } | null | undefined): boolean {\n  return !!et?.bookingRequiresAuthentication;\n}","tryCatchPattern":"try {\n  await api.post('/v2/bookings', body);\n} catch (err) {\n  if (err.status === 401 && /must be authenticated/.test(err.message)) {\n    // send Authorization header with an authorized user's token, or disable require-auth on the event type\n  }\n  throw err;\n}","preventionTips":["Send a valid access token/API key when booking protected event types.","Check eventType.bookingRequiresAuthentication before building public flows.","Keep the require-auth flag aligned with how the event type is consumed."],"tags":["authentication","booking","event-type","unauthorized"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}