Install and set up the Corbado Observe SDK, including your first tracked event, in Getting started. This page explains the subflow concept and documents all available subflow types.
stepName.
How subflows work
A subflow groups related events for one authentication method. Every subflow has a type (e.g.,passkey-login or password-login) and consists of a trigger and one or more steps.
Trigger
The trigger (subflow_trigger) marks the moment of interaction with the subflow. Usually the actor is the user (e.g., clicking “Sign in with passkey”), but in some cases the system can be the actor too (e.g., during passkey enrollment with conditional mediation).
Note that steps can run before the trigger fires. For example, during passkey login the get-options step may complete in the background while the UI renders a “Sign in with passkey” button. The trigger fires only when the user clicks that button. If the user never clicks, there is no trigger — meaning there was no interaction with this subflow.
Corbado Observe uses the trigger to calculate how long it takes the user to interact with a subflow and to determine if a subflow should be included in certain dashboards or not.
The trigger carries:
| Field | Description |
|---|---|
actor | Who initiated the interaction: user (e.g., clicked a button) or system (e.g., auto-started passkey enrollment with conditional mediation). |
explicitSpecType | Optional. A variant label that distinguishes different flavors of the same subflow type (see the spec type tables for each subflow below). |
Steps
Each step represents one phase of the subflow. A step is identified by itsstepName (e.g., get-options, ceremony, post-response) and tracked with three generic events:
| Event | Description |
|---|---|
subflow_step_started | The step began. |
subflow_step_finished | The step completed successfully. |
subflow_step_error | The step failed. |
stepName string to the generic step events.
Example: passkey login
A successful passkey login subflow where assertion options are pre-fetched in the background:| # | Event | Step | Description |
|---|---|---|---|
| 1 | subflow_step_started | get-options | SDK requests assertion options from your server in the background. |
| 2 | subflow_step_finished | get-options | Server returns assertion options. UI can now show a “Sign in with passkey” button. |
| 3 | subflow_trigger | — | User clicks the button (actor: user). |
| 4 | subflow_step_started | ceremony | Browser WebAuthn ceremony begins. |
| 5 | subflow_step_finished | ceremony | User completes the ceremony. |
| 6 | subflow_step_started | post-response | SDK sends the assertion response to your server for verification. |
| 7 | subflow_step_finished | post-response | Server confirms the login. |
| # | Event | Step | Description |
|---|---|---|---|
| 1 | subflow_trigger | — | User clicks “Sign in with passkey” (actor: user). |
| 2 | subflow_step_started | get-options | SDK requests assertion options from your server. |
| 3 | subflow_step_finished | get-options | Server returns assertion options. |
| … |
subflow_step_error replaces the corresponding subflow_step_finished.
Subflow types
1. Provide identifier
SDK class:provideIdentifierOperationFull(inputHtmlField)
Tracks when users enter and submit their identifier (e.g., an email address).
Because passkey Conditional UI (CUI) is always bound to the same input field as the identifier, CUI passkey login events are tracked together with the provide-identifier subflow. This means a single integration point covers both the identifier input and an optional CUI-initiated passkey login.
Steps
| Step | Subflow type | Description |
|---|---|---|
post-response | provide-identifier | Server-side identifier check (e.g., does user exist, which login methods are available). |
get-options | passkey-login | CUI requests assertion options from the server. |
ceremony | passkey-login | Browser CUI ceremony (auto-fill prompt). |
post-response | passkey-login | Server verifies the CUI assertion response. |
Spec types
explicitSpecType | Subflow type | Description |
|---|---|---|
email | provide-identifier | User typed into the identifier field (auto-detected by the SDK). |
passkey-cui | passkey-login | User interacted with the Conditional UI auto-fill prompt (auto-detected by the SDK). |
Code example
The operation is bound to the identifier input field. This enables the SDK to automatically detect user interaction: when the user starts typing, the provide-identifier trigger fires; when the user interacts with the browser’s CUI autofill prompt, the CUI trigger and ceremony start fire automatically. The SDK also auto-detects CUI cancellation.- Provide identifier + CUI
2. Passkey login
SDK class:passkeyLoginFullOperation()
Tracks passkey-based sign-in attempts where the relying party explicitly triggers the WebAuthn ceremony (not via Conditional UI — see Provide identifier for CUI).
Steps
| Step | Description |
|---|---|
get-options | Request assertion options from the server. |
ceremony | Browser WebAuthn authentication ceremony. |
post-response | Server verifies the assertion response. |
Spec types
explicitSpecType | Description |
|---|---|
passkey-known-identifier | User’s identifier is already known (e.g., post-identifier screen). The server can scope the allowed credentials to this user. |
passkey-no-identifier | No identifier is known. The server returns a broad set of allowed credentials. |
passkey-cui | Conditional UI initiated passkey login (typically tracked via the provide-identifier integration). |
Code example
- Manual trigger (post-identifier)
- Auto trigger (post-identifier)
The user’s identifier is already known. A “Sign in with passkey” button is shown, and the user clicks it to start. The trigger fires on click with
actor: "user".3. Passkey enrollment
SDK class:passkeyEnrollmentFullOperation()
Tracks passkey registration and setup after authentication (e.g., during a post-login enrollment prompt).
Steps
| Step | Description |
|---|---|
get-options | Request attestation options from the server. |
ceremony | Browser WebAuthn registration ceremony. |
post-response | Server verifies the attestation response and stores the credential. |
Spec types
explicitSpecType | Description |
|---|---|
conditional-auto-manual | System first attempts conditional (auto-register) enrollment, then falls back to a regular prompt if it fails, and finally allows the user to trigger it manually. |
auto-manual | System auto-triggers the enrollment prompt, with a manual fallback. |
manual | User explicitly triggers enrollment (e.g., clicks “Create passkey”). |
Code example
- Conditional mediation + auto
- Auto
- Manual
The system first attempts conditional mediation (auto-register) enrollment. If the user dismisses the conditional prompt, it falls back to a regular auto-triggered prompt.
4. Password login
SDK class:passwordLoginFullOperation(autoTrackConfig?)
Tracks password-based login attempts. The trigger is auto-detected by the SDK when the user starts typing into the password input field.
Steps
| Step | Description |
|---|---|
post-response | Server verifies the submitted password. |
Spec types
explicitSpecType | Description |
|---|---|
password-known-identifier | Identifier was already submitted in a previous step (e.g., post-identifier screen with a pre-filled email). |
password-with-identifier | Identifier and password are submitted together on the same screen. |
Typed errors
In addition to passing raw errors, the password login subflow supports typed error codes:| Code | Description |
|---|---|
invalid_password | The submitted password is incorrect. |
user_not_found | No user exists for the given identifier. |
account_locked | The account has been locked. |
5. Password enrollment
SDK class:passwordEnrollmentFullOperation(autoTrackConfig?)
Tracks password creation or password reset during authentication journeys.
The trigger is auto-detected by the SDK when the user starts typing into the password input field.
Steps
| Step | Description |
|---|---|
post-response | Server processes the new or updated password. |
Spec types
explicitSpecType | Description |
|---|---|
password-set | User sets a password for the first time (e.g., during signup). |
password-reset | User resets an existing password (e.g., via a recovery flow). |
Typed errors
| Code | Description |
|---|---|
requirements_not_fulfilled | The password does not meet the required complexity rules. |
6. Email OTP
SDK class:emailOtpOperationFull()
Tracks one-time-password verification sent by email.
Steps
| Step | Description |
|---|---|
send | Server sends the OTP email to the user. |
post-response | Server verifies the OTP code the user submitted. |
resend | User requests a new OTP code. |
Spec types
explicitSpecType | Description |
|---|---|
email-otp-login | OTP is used as a login method. |
email-otp-enrollment | OTP is used for enrollment or account activation. |
7. Email link
SDK class:emailLinkOperationFull()
Tracks authentication flows where users sign in or verify their identity through a link sent by email.
Steps
| Step | Description |
|---|---|
send | Server sends the email containing the magic link. |
post-response | Server verifies the token from the clicked link. |
resend | User requests a new email link. |
Spec types
explicitSpecType | Description |
|---|---|
email-link-login | Email link is used as a login or recovery method. |
email-link-enrollment | Email link is used for enrollment or account activation. |
8. Social login
SDK class:socialLoginOperationFull()
Tracks authentication with social identity providers (e.g., Google, Apple, Facebook).
Steps
| Step | Description |
|---|---|
get-redirect-url | Application initiates the OAuth redirect to the social provider. |
exchange-code | Application exchanges the authorization code for tokens after the user returns from the provider. |
Spec types
explicitSpecType | Description |
|---|---|
pre-identifier | Social login button is shown before the user enters any identifier (e.g., on the initial login screen). |
post-identifier | Social login is offered after the user has already provided an identifier. |
9. Coming soon
The following subflow types are planned but not yet available:| Subflow type | Description |
|---|---|
sms-otp | OTP verification sent via SMS. |
provide-data | Collecting additional user data during a flow (e.g., name, address). |
totp | Time-based one-time password (authenticator app). |