Skip to main content
Decisions capture explicit choice points in an authentication journey. Use decisions to track:
  • User choices, for example selecting between passkey login, password login, or social login
  • System choices, for example policy or backend logic selecting an auth path automatically
Unlike subflows, decisions are not auto-discovered. You define them by sending decision events from your integration.

1. Why decisions matter

Without decision events, complex authentication funnels can be hard to interpret because branch points are only implied by downstream events. With decision tracking, you make branch points explicit, which helps you:
  • Understand where users hesitate or switch methods repeatedly
  • Analyze system-driven routing behavior (for example post-identifier routing)
  • Filter and segment funnels by concrete choice outcomes
  • Measure prompt-style interactions such as “accept” vs “dismiss”

2. Decision model

A decision in Corbado Observe has:
  • A stable decisionName (for example login-method or passkey-enrollment)
  • A list of offered options at the decision point
  • An optional chosen value (explicitDecisionValue) when the decision resolves
Common properties:
  • The same decision can occur multiple times in one flow
  • Available options can change between attempts
  • Decision outcomes can be user-driven or system-driven

3. Decision types

The SDK offers two decision event variants. Both follow the same started/finished lifecycle, but differ in how options are typed.

3.1 Auth method decisions

Use authMethodsDecisionStarted() / authMethodsDecisionFinished() when the decision involves choosing an authentication method. This is the more convenient variant for auth method selection because options use predefined AuthMethodType values, which reduces tracking code and enables richer analytics out of the box.
Event methodWhen to sendRequired fields
authMethodsDecisionStarted()Auth method choices are shown or become availabledecisionName, options
authMethodsDecisionFinished()A concrete auth method outcome is knowndecisionName, options
Available AuthMethodType values include: passkey-login-known-identifier, passkey-login-no-identifier, passkey-login-cui, passkey-enrollment, password-login-known-identifier, password-login-with-identifier, password-enrollment, email-otp-login, email-otp-enrollment, email-link-login, email-link-enrollment, social-google, social-apple, social-facebook, social-other, identifier-email, reset-flow. You can also pass custom strings alongside these predefined values.

3.2 Generic decisions

Use authDecisionStarted() / authDecisionFinished() for decisions that are not about selecting an authentication method, for example prompt-style interactions like “accept” vs “dismiss” or binary choices like “keep me logged in”.
Event methodWhen to sendRequired fields
authDecisionStarted()A decision point becomes visible/activedecisionName, options
authDecisionFinished()A concrete decision outcome is knowndecisionName, options

3.3 explicitDecisionValue

Both decision types support an optional explicitDecisionValue field. Use it when you want to record which option was selected. Common patterns:
  • On finished events: Set explicitDecisionValue to record the user’s final choice (for example "password-login" or "skip").
  • On started events: Set explicitDecisionValue when the decision is re-offered after a user action and you want to capture what triggered the transition (for example "switch-method" when the user navigated back to a different set of options).
If the decision resolves implicitly (for example the user proceeds with the only available option), you can omit explicitDecisionValue.

4. Track decisions in your integration

4.1 Example: post-identifier auth method selection

After identifier lookup, the user sees available login methods. Each time the available options change (for example the user switches between method sets), a new decision event is sent.
Corbado Observe SDK installation and setup are explained in Getting started.
import { init, getTracker } from "@corbado/observe";

init({
  projectId: "<ProjectID>",
  apiBaseUrl: "<APIBaseURL>",
});

// User sees passkey + other method options after identifier check
getTracker().authMethodsDecisionStarted({
  decisionName: "post-identifier",
  options: ["passkey-login-known-identifier", "social-google", "reset-flow"],
});

// User clicks "show other methods", new options are presented
getTracker().authMethodsDecisionStarted({
  decisionName: "post-identifier",
  options: ["social-google", "password-login-known-identifier", "reset-flow"],
  explicitDecisionValue: "switch-method",
});

4.2 Example: passkey enrollment prompt

After login, the user is prompted to enroll a passkey. This is a binary decision: enroll or skip.
// Enrollment prompt is shown
getTracker().authMethodsDecisionStarted({
  decisionName: "enrollment-user",
  options: ["passkey-enrollment", "skip"],
});

// User skips enrollment
getTracker().authMethodsDecisionFinished({
  decisionName: "enrollment-user",
  options: ["passkey-enrollment", "skip"],
  explicitDecisionValue: "skip",
});

4.3 Example: generic decision (identifier prefilling)

A non-auth-method decision, for example whether the user accepts a pre-filled identifier.
// Pre-filled identifier is shown, user can accept or change it
getTracker().authDecisionStarted({
  decisionName: "prefilling-accepted",
  options: ["accept", "deny"],
});

// User proceeds with the pre-filled identifier
getTracker().authDecisionFinished({
  decisionName: "prefilling-accepted",
  options: ["accept", "deny"],
  explicitDecisionValue: "accept",
});
  • Use authMethodsDecision* for authentication method selection and authDecision* for everything else
  • Track every important branch point with one consistent decisionName
  • Send a started event whenever options are shown or change
  • Send a finished event as soon as the outcome is known
  • Include all currently offered options in both events for clear context
  • Re-send decision events if users revisit the same choice point
Keep decisionName values short, stable, and implementation-agnostic. Avoid naming that changes with experiments or UI wording.

6. Next steps

  • Continue with Flows to model complete journeys.
  • Continue with Subflows to learn about subflow types and their steps.