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

# Opal Events

Communication between Opal and your app is handled through a consistent, mode-aware event system. Events are emitted throughout the user session to indicate progress, completion, errors, and important milestones.

## Listening to Events

We strongly recommend using one of the Opal SDKs to receive typed events and lifecycle callbacks. The SDKs provide `onEvent`, `onOpen`, and `onExit` handlers and expose a small enum of well-known events under `OpalEventType` for convenience (e.g., `SESSION_STARTED`, `SESSION_COMPLETED`).

Each Opal mode (`identity_verification`, `connect`, `card_connect`, `account_verification`, `transactions`, `balance_transfer`) emits a set of mode‑specific events in addition to default session events. See below for structure, a complete list, and examples.

## Event Structure

All Opal events follow a consistent structure:

```json theme={null}
{
  "type": "opal.session.started",
  "mode": "opal",
  "object": "session",
  "action": "started",
  "timestamp": "2025-06-10T22:50:53.024Z",
  "data": null
}
```

### Event fields

| Field | Type | Description |
| - | - | - |
| `type` | string | Fully qualified event name: `<flow>.<object>.<action>` or `opal.session.<action>` for default session events. |
| `mode` | string | The active operational mode (e.g., `connect`, `identity_verification`, `account_verification`, `transactions`). |
| `object` | string | The related object (e.g., `session`, `flow`, `step`, `identity`, `card`, `accounts`). |
| `action` | string | The action that occurred (e.g., `started`, `completed`, `verified`, `errored`). |
| `timestamp` | string | ISO 8601 timestamp of when the event occurred. |
| `data` | object \| null | Additional context that varies by event type; may be `null` for lifecycle events. |

### Possible flows:

* `identity_verification`
* `connect`
* `account_verification`
* `transactions`
* `balance_transfer`

## Sample Events

### opal.session.started

```json theme={null}
{
  "type": "opal.session.started",
  "mode": "connect",
  "object": "session",
  "action": "started",
  "timestamp": "2025-06-10T22:50:53.024Z",
  "data": null
}
```

### opal.session.errored

```json theme={null}
{
  "type": "opal.session.errored",
  "mode": "connect",
  "object": "session",
  "action": "errored",
  "timestamp": "2025-06-10T22:50:53.024Z",
  "data": {
    "type": "INVALID_REQUEST",
    "sub_type": "INVALID_SMS_CODE",
    "message": "Invalid request please try again"
  }
}
```

### connect.flow\.completed

```json theme={null}
{
  "type": "connect.flow.completed",
  "mode": "connect",
  "object": "flow",
  "action": "completed",
  "timestamp": "2025-06-10T22:50:53.024Z",
  "data": {
    "accounts": ["acc_ge9hxMTPGdXmQ"],
    "entity_id": "ent_wrDBN43PR8LKC"
  }
}
```

## Event Categories

### Default session events (always available)

* `opal.session.started` - Opal UI opened and session began
* `opal.session.completed` - User completed the flow successfully
* `opal.session.errored` - A recoverable or terminal error occurred
* `opal.session.exited` - User exited or dismissed Opal

### Generic flow and step events

Emitted in addition to the default session events. These mirror the active mode‑specific events but are prefixed with `opal` and can be emitted for any mode.

#### Flow

* `opal.flow.started` - A sub‑flow of Opal started (e.g., identity verification, account selection, verification).
* `opal.flow.completed` - A sub‑flow of Opal completed. This does not always signify the end of the session; use `opal.session.completed` to detect when Opal is fully completed.

#### Step

* `opal.step.started` - A new step started (e.g., phone input, card selection, CVV input).
* `opal.step.completed` - A step completed and the next page is opening.

Notes:

* Additional mode-specific events may be introduced over time. Your handler should use the `OpalEventType` enum to handle the specific cases you need.

## All Event Types

The following table lists all currently supported event types with their `OpalEventType` mapping, and when they are typically emitted.

| Event (OpalEventType - type) | When you might see it |
| - | - |
| `SESSION_STARTED` - `opal.session.started` | Opal UI opened and session began. |
| `SESSION_COMPLETED` - `opal.session.completed` | User completed the overall Opal flow successfully. |
| `SESSION_ERRORED` - `opal.session.errored` | A recoverable or terminal error occurred. |
| `SESSION_EXITED` - `opal.session.exited` | User closed or dismissed Opal before completion. |
| `FLOW_STARTED` - `opal.flow.started` | A sub-flow (for any mode) started. |
| `FLOW_COMPLETED` - `opal.flow.completed` | A sub-flow (for any mode) completed. |
| `STEP_STARTED` - `opal.step.started` | A step (screen) started. |
| `STEP_COMPLETED` - `opal.step.completed` | A step (screen) completed. |
| `IDV_FLOW_STARTED` - `identity_verification.flow.started` | Identity Verification flow started. |
| `IDV_STEP_STARTED` - `identity_verification.step.started` | A step in Identity Verification started. |
| `IDV_STEP_COMPLETED` - `identity_verification.step.completed` | A step in Identity Verification completed. |
| `IDV_FLOW_COMPLETED` - `identity_verification.flow.completed` | Identity Verification flow completed. |
| `IDV_VERIFICATION_COMPLETED` - `identity_verification.identity.completed` | Identity successfully verified (KYC passed). |
| `CXN_FLOW_STARTED` - `connect.flow.started` | Connect flow started. |
| `CXN_STEP_STARTED` - `connect.step.started` | A step in Connect started. |
| `CXN_STEP_COMPLETED` - `connect.step.completed` | A step in Connect completed. |
| `CXN_FLOW_COMPLETED` - `connect.flow.completed` | Connect flow completed. |
| `CXN_ACCOUNTS_SELECTED` - `connect.accounts.selected` | User selected one or more accounts to connect. |
| `AVF_FLOW_STARTED` - `account_verification.flow.started` | Account Verification flow started. |
| `AVF_STEP_STARTED` - `account_verification.step.started` | A step in Account Verification started. |
| `AVF_STEP_COMPLETED` - `account_verification.step.completed` | A step in Account Verification completed. |
| `AVF_FLOW_COMPLETED` - `account_verification.flow.completed` | Account Verification flow completed. |
| `AVF_CARD_VERIFIED` - `account_verification.card.verified` | Card verified successfully. |
| `TXN_FLOW_STARTED` - `transactions.flow.started` | Transactions flow started. |
| `TXN_STEP_STARTED` - `transactions.step.started` | A step in Transactions started. |
| `TXN_STEP_COMPLETED` - `transactions.step.completed` | A step in Transactions completed. |
| `TXN_FLOW_COMPLETED` - `transactions.flow.completed` | Transactions flow completed. |
| `TXN_ACCOUNTS_LINKED` - `transactions.accounts.linked` | Accounts linked and subscribed for transactions. |

### Balance Transfer events

The `OpalEventType` enum does not include constants for Balance Transfer events. Match these events on `event.type`.

| Event type | When you might see it |
| - | - |
| `balance_transfer.flow.started` | Balance Transfer amount allocation started. |
| `balance_transfer.step.started` | A step in Balance Transfer started. |
| `balance_transfer.step.completed` | A step in Balance Transfer completed. |
| `balance_transfer.amounts.confirmed` | User confirmed their allocations and closed the confirmation screen. |
| `balance_transfer.flow.completed` | Balance Transfer flow completed. |

See [Balance Transfer](https://docs.methodfi.com/opal/balance_transfer/overview.md#events) for the payload of each event.

### Data Payloads

The following events always include a non-null `event.data` payload:

* `identity_verification.identity.completed`
* `connect.accounts.selected`
* `account_verification.card.verified`
* `transactions.accounts.linked`
* `balance_transfer.amounts.confirmed`

Use these payloads to retrieve context such as selected accounts, verification results, or linkage details.

## Enhanced Event Handling

### Using the JavaScript SDK

```javascript theme={null}
import { OpalEventType } from '@methodfi/opal-react';

const config = {
  onEvent: (event) => {
    console.log("Event received:", event.type);

    // Handle specific events using the OpalEventType enum
    switch (event.type) {
      case OpalEventType.SESSION_STARTED:
        // Session lifecycle
        break;
      case OpalEventType.SESSION_COMPLETED:
        // Entire Opal session completed successfully
        break;
      case OpalEventType.SESSION_ERRORED:
        // Handle recoverable or terminal error
        console.error("Opal error:", event.data);
        break;
      case OpalEventType.IDV_VERIFICATION_COMPLETED:
        // Identity verification completed; payload contains verification details
        handleIdentityVerified(event.data);
        break;
      case OpalEventType.CXN_ACCOUNTS_SELECTED:
        // User selected accounts in Connect
        handleAccountsSelected(event.data);
        break;
      case OpalEventType.AVF_CARD_VERIFIED:
        // Card verified in Account Verification
        handleCardVerified(event.data);
        break;
      case OpalEventType.TXN_ACCOUNTS_LINKED:
        // Accounts linked for Transactions
        handleAccountsLinked(event.data);
        break;
      default:
        // Optionally handle generic flow/step events
        break;
    }
  },

  // Specific event handlers
  onSuccess: (payload) => {
    // Called for successful completion events
    console.log("Success:", payload);
  },

  onError: (error) => {
    // Enhanced error handling with detailed information
    console.error("Error:", error.code, error.message);
    console.error("Details:", error.details);
  },
};

const opal = new MethodOpal(config);
```

## PostMessage Communication

For applications not using the Opal SDKs, you can listen to events via PostMessage:

### Setup PostMessage Listener

```javascript theme={null}
window.addEventListener("message", function (event) {
  // Verify origin for security
  if (event.origin !== "https://opal.production.methodfi.com") {
    return;
  }

  const opalEvent = event.data;
  console.log("Opal event:", opalEvent.type, opalEvent.data);

  // Handle events
  switch (opalEvent.type) {
    case OpalEventType.SESSION_STARTED:
      console.log("Opal started");
      break;
    case OpalEventType.SESSION_COMPLETED:
      console.log("Opal completed:", opalEvent.data);
      break;
  }
});
```

## Best Practices

### Event Handling

* Always verify event origins for security
* Use event filtering to reduce noise
* Implement proper error handling for all events
* Log events for debugging and analytics

### Security

* Validate all event data before processing
* Never trust client-side events for critical business logic


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.