> ## Documentation Index
> Fetch the complete documentation index at: https://docs.corbado.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Decisions with Corbado Observe

> Track explicit user and system choices with decisions in Corbado Observe.

Decisions capture explicit choice points in an authentication journey.

<Frame>
  <iframe className="w-full aspect-video rounded-xl" src="https://www.youtube.com/embed/CLogBNykxnQ" title="Passkey vs Password: See what Users actually use | Corbado Observe" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
</Frame>

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](/corbado-observe/tracking/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 method                    | When to send                                      | Required fields           |
| ------------------------------- | ------------------------------------------------- | ------------------------- |
| `authMethodsDecisionStarted()`  | Auth method choices are shown or become available | `decisionName`, `options` |
| `authMethodsDecisionFinished()` | A concrete auth method outcome is known           | `decisionName`, `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 method             | When to send                            | Required fields           |
| ------------------------ | --------------------------------------- | ------------------------- |
| `authDecisionStarted()`  | A decision point becomes visible/active | `decisionName`, `options` |
| `authDecisionFinished()` | A concrete decision outcome is known    | `decisionName`, `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.

<Tabs>
  <Tab title="NPM">
    <Info>
      **Corbado Observe SDK** installation and setup are explained in [Getting started](/corbado-observe/overview/getting-started).
    </Info>

    ```typescript theme={null}
    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",
    });
    ```
  </Tab>

  <Tab title="CDN">
    <Info>
      **Corbado Observe SDK** installation and setup are explained in [Getting started](/corbado-observe/overview/getting-started).
    </Info>

    ```html theme={null}
    <script>
      Corbado.init({
        projectId: "<ProjectID>",
        apiBaseUrl: "<APIBaseURL>",
      });

      Corbado.get().authMethodsDecisionStarted({
        decisionName: "post-identifier",
        options: ["passkey-login-known-identifier", "social-google", "reset-flow"],
      });

      Corbado.get().authMethodsDecisionStarted({
        decisionName: "post-identifier",
        options: ["social-google", "password-login-known-identifier", "reset-flow"],
        explicitDecisionValue: "switch-method",
      });
    </script>
    ```
  </Tab>
</Tabs>

### 4.2 Example: passkey enrollment prompt

After login, the user is prompted to enroll a passkey. This is a binary decision: enroll or skip.

```typescript theme={null}
// 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.

```typescript theme={null}
// 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",
});
```

## 5. Recommended best practices

* 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

<Tip>
  Keep `decisionName` values short, stable, and implementation-agnostic. Avoid naming that changes with experiments or UI wording.
</Tip>

## 6. Next steps

* Continue with [Flows](/corbado-observe/tracking/flows) to model complete journeys.
* Continue with [Subflows](/corbado-observe/tracking/subflows) to learn about subflow types and their steps.
