
Get your OAuth “Continue with Cal.com” Badge
- https://app.cal.com/continue-with-calcom-coss-ui.svg
- https://app.cal.com/continue-with-calcom-dark-rounded.svg
- https://app.cal.com/continue-with-calcom-dark-squared.svg
- https://app.cal.com/continue-with-calcom-light-rounded.svg
- https://app.cal.com/continue-with-calcom-light-squared.svg
- https://app.cal.com/continue-with-calcom-neutral-rounded.svg
- https://app.cal.com/continue-with-calcom-light-squared.svg
1. OAuth Client Credentials
You can create an OAuth client via the following page https://app.cal.com/settings/developer/oauth. The OAuth client will be in a “pending” state and not yet ready to use. An admin from Cal.com will then review your OAuth client and you will receive an email if it was accepted or rejected. If it was accepted then your OAuth client is ready to be used.2. Authorize
To initiate the OAuth flow, direct users to the following authorization URL:https://app.cal.com/auth/oauth2/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&state=YOUR_STATE
URL Parameters:
| Parameter | Required | Description |
|---|---|---|
client_id | Yes | Your OAuth client ID |
redirect_uri | Yes | Where users will be redirected after authorization. Must exactly match the registered redirect URI. |
state | Recommended | A securely generated random string to mitigate CSRF attacks |
code_challenge | For public clients | PKCE code challenge (S256 method) |
redirect_uri with code (authorization code) and state as URL parameters:
Error Handling
Errors during the authorization step are displayed directly to the user on the Cal.com authorization page. Your application will not receive a JSON error response for these cases:- Client not found: No OAuth client exists with the provided
client_id. - Client not approved: The OAuth client has not been approved by a Cal.com admin yet.
- Mismatched redirect URI: The
redirect_uridoes not match the one registered for the OAuth client.
redirect_uri with an error:
3. Exchange Token
Exchange an authorization code for access and refresh tokens. The token endpoint also acceptsapplication/x-www-form-urlencoded content type.
Endpoint: POST https://api.cal.com/v2/auth/oauth2/token
3.1 Confidential Clients
Confidential clients authenticate with aclient_secret. All parameters are required:
| Parameter | Description |
|---|---|
client_id | Your OAuth client ID |
client_secret | Your OAuth client secret |
grant_type | Must be authorization_code |
code | The authorization code received in the redirect URI |
redirect_uri | Must match the redirect URI used in the authorization request |
- cURL
- fetch
- axios
3.2 Public Clients (PKCE)
Public clients (e.g. single-page apps, mobile apps) use PKCE instead of aclient_secret. You must have sent a code_challenge during the authorization step. All parameters are required:
| Parameter | Description |
|---|---|
client_id | Your OAuth client ID |
grant_type | Must be authorization_code |
code | The authorization code received in the redirect URI |
redirect_uri | Must match the redirect URI used in the authorization request |
code_verifier | The original PKCE code verifier used to generate the code_challenge |
- cURL
- fetch
- axios
Success Response (200)
Access tokens expire after 30 minutes (
expires_in: 1800). Use the refresh token to obtain a new access token.Error Responses
Error responses includeerror and error_description fields.
Invalid or expired authorization code (400)
Invalid or expired authorization code (400)
Invalid client credentials (401)
Invalid client credentials (401)
client_secret does not match the client_id. Verify your credentials.Client not found (401)
Client not found (401)
client_id.Missing client_id (400)
Missing client_id (400)
client_id field is missing from the request body.Invalid grant_type (400)
Invalid grant_type (400)
grant_type field must be either authorization_code or refresh_token.4. Refresh Token
Refresh an expired access token using a refresh token. Endpoint:POST https://api.cal.com/v2/auth/oauth2/token
4.1 Confidential Clients
Confidential clients authenticate with aclient_secret. All parameters are required:
| Parameter | Description |
|---|---|
client_id | Your OAuth client ID |
client_secret | Your OAuth client secret |
grant_type | Must be refresh_token |
refresh_token | The refresh token received from a previous token response |
- cURL
- fetch
- axios
4.2 Public Clients
Public clients do not use aclient_secret. All parameters are required:
| Parameter | Description |
|---|---|
client_id | Your OAuth client ID |
grant_type | Must be refresh_token |
refresh_token | The refresh token received from a previous token response |
- cURL
- fetch
- axios
Success Response (200)
Error Responses
Invalid refresh token (400)
Invalid refresh token (400)
Invalid client credentials (401)
Invalid client credentials (401)
client_secret does not match the client_id.Client not found (401)
Client not found (401)
client_id.5. Verify Access Token
To verify the correct setup and functionality of OAuth credentials, use the following endpoint: Endpoint:GET https://api.cal.com/v2/me
- cURL
- fetch
- axios