
Prerequisites
Before using the onboarding embed, you need:- An OAuth client ID from the Cal.com team. Fill out this form to get started.
- A redirect URI registered on your OAuth client that shares the same origin (scheme + domain + port) as the page hosting the embed.
- The
@calcom/atomsReact package installed in your project.
How it works
The component opens a dialog containing an iframe that runs Cal.com’s onboarding flow. Because the iframe runs on Cal.com’s domain with a first-party session, no third-party cookies are needed. The flow automatically detects where the user is:- No session — starts at signup/login, then profile setup, calendar connection, and OAuth consent.
- Session with incomplete onboarding — resumes from where the user left off.
- Session with complete onboarding — skips straight to OAuth consent.
Two modes
The component supports two modes for receiving the authorization code:- Callback mode — provide an
onAuthorizationAllowedcallback to receive the code directly. No page navigation occurs. - Redirect mode — omit the callback and the browser navigates to your
redirectUriwith the code as a query parameter.
Callback mode
ProvideonAuthorizationAllowed to receive the authorization code directly. The dialog closes and your callback fires after the user authorizes — no page reload.
Redirect mode
OmitonAuthorizationAllowed and the browser navigates to your redirectUri after the user completes onboarding and grants access:
Props
| Prop | Type | Required | Description |
|---|---|---|---|
oAuthClientId | string | Yes | Your OAuth client ID. |
host | string | No | Cal.com host URL. Defaults to https://app.cal.com. |
theme | "light" or "dark" | No | Theme for the embedded UI. Defaults to "light". |
user | { email?, name?, username? } | No | Prefill user details in signup and profile steps. |
authorization | See below | Yes | OAuth authorization parameters. |
onAuthorizationAllowed | ({ code }) => void | No | Called with the authorization code on success. Enables callback mode. If omitted, enables redirect mode. |
onError | (error) => void | No | Called when an error occurs. |
onAuthorizationDenied | () => void | No | Called when the user declines authorization. If omitted, the browser redirects with error=access_denied. |
onClose | () => void | No | Called when the user dismisses the dialog. |
trigger | ReactNode | No | Custom trigger element. Defaults to a “Continue with Cal.com” button. |
Authorization props
| Prop | Type | Required | Description |
|---|---|---|---|
redirectUri | string | Yes | One of the redirect URIs registered on your OAuth client. Must share the same origin as the page hosting the embed. |
scope | string[] | Yes | OAuth scopes to request. Must be a subset of scopes registered on the OAuth client. |
state | string | Yes | A unique CSRF token. Generate one per session and verify it matches when you receive the authorization code. |
codeChallenge | string | For public clients | PKCE code challenge (S256 method). Required for public OAuth clients that cannot store a client secret. |
If the user signs up via Google, the
user prop values are ignored — name, email, and username come from the Google account instead.Theming and custom trigger
Thetheme prop controls the appearance of the trigger button, the onboarding steps, and the authorization page.
| Light theme (default) | Dark theme |
|---|---|
![]() | ![]() |
trigger prop:
Step-by-step walkthrough
Here is what the user sees when they click the trigger button:Login or signup
The dialog opens with a login form. Existing users sign in with email or Google. New users click “Create account” to sign up. The 
user.email prop prefills the email field.
Profile setup
After signing up, the user sets their display name. The 
user.name prop prefills this field.
Authorize
The user reviews the permissions your app requests and clicks “Allow”. The displayed permissions correspond to the 
scope you passed to the component.
Public clients (PKCE)
If your OAuth client cannot safely store a client secret (for example, a browser-only app), use PKCE to secure the authorization code exchange. Generate acode_verifier, derive a code_challenge, and pass it to the component:
Error handling
TheonError callback receives an error with a code and message:
| Code | What it means |
|---|---|
INVALID_PROPS | Required props are missing or invalid (for example, the oAuthClientId does not exist or the redirectUri does not match a registered URI). |
SIGNUP_FAILED | Account creation failed. |
ONBOARDING_FAILED | An error occurred during one of the onboarding steps. |
AUTHORIZATION_FAILED | OAuth consent failed. |
STATE_MISMATCH | The state in the response did not match what you provided. This could indicate a CSRF attack. |
UNKNOWN | An unexpected error occurred. |
redirectUri:

