{"record":{"id":"984a7d5adeb37346","repo":"calcom/cal.diy","slug":"apikeysservice-this-endpoint-can-only-be-accesse","errorCode":null,"errorMessage":"ApiKeysService - This endpoint can only be accessed using an API key by providing 'Authorization: Bearer <apiKey>' header","messagePattern":"ApiKeysService - This endpoint can only be accessed using an API key by providing 'Authorization: Bearer <apiKey>' header","errorType":"exception","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"apps/api/v2/src/modules/api-keys/services/api-keys.service.ts","lineNumber":22,"sourceCode":"import { CreateApiKeyInput } from \"@/modules/api-keys/inputs/create-api-key.input\";\nimport { RefreshApiKeyInput } from \"@/modules/api-keys/inputs/refresh-api-key.input\";\nimport { ApiAuthGuardRequest } from \"@/modules/auth/strategies/api-auth/api-auth.strategy\";\nimport { BadRequestException, Injectable, UnauthorizedException } from \"@nestjs/common\";\nimport { ConfigService } from \"@nestjs/config\";\nimport { DateTime } from \"luxon\";\n\nimport { createApiKeyHandler } from \"@calcom/platform-libraries\";\n\n@Injectable()\nexport class ApiKeysService {\n  constructor(\n    private readonly apiKeysRepository: ApiKeysRepository,\n    private readonly config: ConfigService\n  ) {}\n\n  async getRequestApiKey(request: ApiAuthGuardRequest) {\n    if (request.authMethod !== AuthMethods.API_KEY) {\n      throw new UnauthorizedException(\n        \"ApiKeysService - This endpoint can only be accessed using an API key by providing 'Authorization: Bearer <apiKey>' header\"\n      );\n    }\n    const apiKey = request.get(\"Authorization\")?.replace(\"Bearer \", \"\");\n    if (!apiKey) {\n      throw new UnauthorizedException(\"ApiKeysService - No API key provided\");\n    }\n    return apiKey;\n  }\n\n  async createApiKey(authUserId: number, createApiKeyInput: CreateApiKeyInput) {\n    if (createApiKeyInput.apiKeyDaysValid && createApiKeyInput.apiKeyNeverExpires) {\n      throw new BadRequestException(\n        \"ApiKeysService -Cannot set both apiKeyDaysValid and apiKeyNeverExpires. It has to be either or none of them.\"\n      );\n    }\n\n    const defaultApiKeyDaysValid = 30;","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/api-keys/services/api-keys.service.ts#L4-L40","documentation":"Thrown by ApiKeysService.getRequestApiKey when request.authMethod does not equal AuthMethods.API_KEY ('api-key'). This endpoint requires API key authentication specifically, but the request was authenticated via a different method (OAuth client, access token, NextAuth session, or third-party access token). The guard has already authenticated the user, but the service rejects the request because API-key-specific operations require the API key itself for further processing (e.g. key refresh, key deletion).","triggerScenarios":"Calling an API-key management endpoint (like DELETE /api-keys or POST /api-keys/refresh) while authenticated with an OAuth access token instead of an API key. The route is protected by ApiAuthGuard which sets authMethod based on which strategy succeeded, but the downstream service checks that the method is specifically API_KEY.","commonSituations":"A frontend app that uses OAuth login trying to manage API keys without first generating one. Swagger/OpenAPI UI using a bearer access token instead of an API key. Confusion between the OAuth access token flow and the API key flow in client code.","solutions":["Switch the Authorization header to use a valid API key (Bearer cal_<key>) instead of an OAuth access token when calling API-key management endpoints.","If you don't have an API key yet, first create one via POST /v2/api-keys using an authenticated session or access token, then use that key for subsequent API-key-specific operations.","Check the ApiAuthGuard configuration to confirm which auth methods are accepted on the route and ensure API_KEY is among them."],"exampleFix":"// before: using OAuth access token for key-management endpoint\nconst res = await fetch('/v2/api-keys/refresh', {\n  headers: { Authorization: `Bearer ${oauthAccessToken}` }\n});\n\n// after: use a valid API key for the Bearer header\nconst res = await fetch('/v2/api-keys/refresh', {\n  headers: { Authorization: `Bearer cal_${validApiKey}` }\n});","handlingStrategy":"validation","validationCode":"// Validate auth method before calling API-key-only endpoints\nconst isApiKeyAuth = (authMethod: string): boolean =>\n  authMethod === 'api-key';\n\n// Ensure the Authorization header contains an API key, not an OAuth token\nconst ensureApiKeyAuth = (headers: Record<string, string>): void => {\n  const auth = headers['Authorization'] ?? headers['authorization'];\n  if (!auth?.startsWith('Bearer cal_')) {\n    throw new Error('This endpoint requires API key auth (Bearer cal_<key>). Current auth is not an API key.');\n  }\n};","typeGuard":"type ApiKeyAuthHeaders = { Authorization: `Bearer cal_${string}` };\nconst hasApiKeyAuth = (h: Record<string, string>): h is ApiKeyAuthHeaders =>\n  h['Authorization']?.startsWith('Bearer cal_') ?? false;","tryCatchPattern":null,"preventionTips":["Document which endpoints require API-key auth vs OAuth/access-token auth in your API client SDK.","Use separate API client instances for different auth methods to avoid accidentally sending the wrong token type.","Before calling API-key management endpoints, verify the client was initialized with an API key, not an OAuth token."],"tags":["authentication","api-key","nestjs","api-v2","unauthorized","authorization"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}