Skip to main content
Subflows are the concrete building blocks inside a flow and are auto-discovered by Corbado Observe based on the events you send. They represent a specific authentication method, for example passkey login, password enrollment, or email OTP verification.
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.
On SDK level, every subflow type has a dedicated class that helps with tracking. Each class defines the default steps you typically want to track for that subflow. If you need to track additional steps beyond the defaults, you can do so by using the generic step events with a custom 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 interaction happens. 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 interaction happens only when the user clicks that button. If the user never clicks, there was no interaction with this subflow. Corbado Observe uses the interaction moment 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. Not every subflow needs an explicit trigger event. Check the documentation of each subflow type below: some detect the interaction on their own (e.g., provide-identifier from typing into the bound input field, passkey-login from the started ceremony step), while others still require you to send subflow_trigger (e.g., passkey enrollment). For subflow types with automatic detection, explicit triggers are deprecated. Where an explicit trigger is required, it carries:

Steps

Each step represents one phase of the subflow. A step is identified by its stepName (e.g., get-options, ceremony, post-response) and tracked with three generic events: Every subflow type defines a set of predefined steps (documented in the sections below). You can also define custom steps by passing any stepName string to the generic step events.

Example: passkey login

A successful passkey login subflow where assertion options are pre-fetched in the background: The get-options steps run in the background without any user involvement — only the started ceremony step counts as the interaction. If the user never clicks the button, the ceremony never starts and there was no interaction with this subflow. If any step fails, a 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

Spec types

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.
You do not need to send subflow_trigger events for this subflow — interaction is handled automatically. Explicit triggers for provide-identifier are deprecated and will be removed in a future SDK version.

2. Passkey login

SDK class: passkeyLoginFullOperation() Tracks passkey-based sign-in attempts where the WebAuthn ceremony is started explicitly — by the relying party or via immediate mediation (not via Conditional UI — see Provide identifier for CUI).

Steps

Spec types

You do not need to send subflow_trigger events for this subflow — the started ceremony step marks the interaction. Explicit triggers for passkey-login are deprecated and will be removed in a future SDK version.

Code example

The browser offers a passkey prompt immediately when the login page loads — before the user has entered an identifier and before Conditional UI starts. No trigger is sent: there is no user click and the prompt is owned by the browser, so the started ceremony step marks the interaction.

3. Passkey enrollment

SDK class: passkeyEnrollmentFullOperation() Tracks passkey registration and setup after authentication (e.g., during a post-login enrollment prompt).

Steps

Spec types

Code example

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 operation is bound to the password input field via autoTrackConfig, so the SDK automatically detects the interaction when the user starts typing.
You do not need to send subflow_trigger events for this subflow — interaction is handled automatically. Explicit triggers for password-login are deprecated and will be removed in a future SDK version.

Steps

Spec types

Typed errors

In addition to passing raw errors, the password login subflow supports typed error codes:

Code example

The operation is bound to the password input field. When the user starts typing, the SDK detects the interaction automatically — your code only tracks the server-side verification step.
Identifier and password are entered together on the same screen (no separate identifier step before).

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

Spec types

Typed errors


6. Email OTP

SDK class: emailOtpOperationFull() Tracks one-time-password verification sent by email.

Steps

Spec types


SDK class: emailLinkOperationFull() Tracks authentication flows where users sign in or verify their identity through a link sent by email.

Steps

Spec types

Cross-environment transactions

Email links often continue in a different browser tab, browser profile, device, or app than the one where the link was requested. For example, a user can start password recovery on desktop but open the email link on mobile. Use crossEnvironmentTransactionID to connect the send step with the later post-response step. The value can be chosen as needed: you can generate a new ID for the email-link transaction or reuse an existing transaction ID from your system. The only requirement is that the same value is available when sending the email and when verifying the link after it has been clicked. crossEnvironmentTransactionID does not replace userId or identifier. Use it to correlate the transaction across environments, and still provide userId via a user reference as soon as it is known.

8. Social login

SDK class: socialLoginOperationFull() Tracks authentication with social identity providers (e.g., Google, Apple, Facebook).

Steps

Spec types


9. Coming soon

The following subflow types are planned but not yet available: