{"record":{"id":"4b1afbdc807e1ef1","repo":"calcom/cal.diy","slug":"this-event-type-requires-authentication-please-pr","errorCode":null,"errorMessage":"This event type requires authentication. Please provide valid credentials.","messagePattern":"This event type requires authentication\\. Please provide valid credentials\\.","errorType":"http","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"apps/api/v2/src/platform/bookings/2024-04-15/controllers/bookings.controller.ts","lineNumber":469,"sourceCode":"      return;\n    }\n\n    if (rescheduleUid) {\n      const isValidRescheduleBooking = await this.isValidRescheduleBooking(rescheduleUid, eventTypeId);\n      if (isValidRescheduleBooking) {\n        return;\n      } else {\n        throw new BadRequestException(\n          \"Trying to reschedule an event-type which requires authentication but provided invalid rescheduleUid.\"\n        );\n      }\n    }\n\n    const owner = await this.getOwner(req);\n    const userId = owner?.id;\n\n    if (!userId) {\n      throw new UnauthorizedException(\n        \"This event type requires authentication. Please provide valid credentials.\"\n      );\n    }\n\n    const isEventTypeOwner = eventType.userId === userId;\n    const isHost = eventType.hosts.some((host) => host.userId === userId);\n    const isTeamAdminOrOwner = eventType.team?.members.some((member) => member.userId === userId) ?? false;\n\n    let isOrgAdminOrOwner = false;\n    if (eventType.team?.parentId) {\n      const orgTeam = await this.teamRepository.getTeamByIdIfUserIsAdmin({\n        userId,\n        teamId: eventType.team.parentId,\n      });\n      isOrgAdminOrOwner = !!orgTeam;\n    } else if (eventType.team?.isOrganization) {\n      isOrgAdminOrOwner = isTeamAdminOrOwner;\n    }","sourceCodeStart":451,"sourceCodeEnd":487,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/bookings/2024-04-15/controllers/bookings.controller.ts#L451-L487","documentation":"A 401 Unauthorized thrown by checkBookingRequiresAuthentication when the event type requires authentication, no valid rescheduleUid was supplied (or one was supplied and validated), and the getOwner method could not resolve a user from the request's Authorization header. getOwner attempts to resolve the user either from a cal_ prefixed API key or from an OAuth access token.","triggerScenarios":"POST /v2/bookings or POST /v2/bookings/recurring against an event type with bookingRequiresAuthentication=true, where: the Authorization header is missing entirely, the API key is invalid/expired/revoked, the OAuth access token is expired or invalid, or the resolved ownerId doesn't correspond to an existing user record.","commonSituations":"Client forgot to include the Authorization header for a restricted event type. The API key was rotated and the old one is still in use. The OAuth token expired and wasn't refreshed. The cal_ API key prefix configured in api.apiKeyPrefix doesn't match the key being sent. The user account was deleted after the API key was issued.","solutions":["Include a valid Authorization: Bearer <token> header where token is either a cal_ prefixed API key or a valid OAuth access token.","If using an API key, verify it starts with the correct prefix (default 'cal_') and hasn't been revoked in the user's API key settings.","If using OAuth, refresh the access token using the refresh token flow and retry.","Confirm the event type actually requires authentication — if bookingRequiresAuthentication was enabled by mistake, disable it in the event type settings."],"exampleFix":"// before — missing auth header\nconst res = await fetch('/v2/bookings', {\n  method: 'POST',\n  body: JSON.stringify({ eventTypeId: 5, start: '...' })\n});\n\n// after — include valid credentials\nconst res = await fetch('/v2/bookings', {\n  method: 'POST',\n  headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },\n  body: JSON.stringify({ eventTypeId: 5, start: '...' })\n});","handlingStrategy":"validation","validationCode":"// Validate auth credentials before calling a restricted event type\nasync function ensureAuthenticated(token) {\n  // Test the token against any authenticated endpoint\n  const res = await fetch('/v2/bookings?status=upcoming', {\n    headers: { Authorization: `Bearer ${token}` }\n  });\n  return res.ok; // 200 means token is valid\n}\n\nif (!(await ensureAuthenticated(apiKey))) {\n  throw new Error('Invalid or expired credentials — refresh your API key or OAuth token');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await api.createBooking({ eventTypeId, ... });\n} catch (err) {\n  if (err.statusCode === 401) {\n    // Refresh OAuth token or prompt for new API key\n    const newToken = await refreshOAuthToken(refreshToken);\n    await api.createBooking({ eventTypeId, ... }); // retry with new token\n  } else {\n    throw err;\n  }\n}","preventionTips":["Implement OAuth token refresh logic with automatic retry on 401 responses.","Store API keys securely and rotate them before expiration.","Verify the API key prefix matches the configured api.apiKeyPrefix (default 'cal_').","Check if the event type has bookingRequiresAuthentication before sending unauthenticated requests."],"tags":["authentication","api-key","oauth","unauthorized","event-type","booking"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}