Skip to main content
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) 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:
{
  "type": "opal.session.started",
  "mode": "opal",
  "object": "session",
  "action": "started",
  "timestamp": "2025-06-10T22:50:53.024Z",
  "data": null
}

Event fields

FieldTypeDescription
typestringFully qualified event name: <flow>.<object>.<action> or opal.session.<action> for default session events.
modestringThe active operational mode (e.g., connect, identity_verification, account_verification, transactions).
objectstringThe related object (e.g., session, flow, step, identity, card, accounts).
actionstringThe action that occurred (e.g., started, completed, verified, errored).
timestampstringISO 8601 timestamp of when the event occurred.
dataobject | nullAdditional context that varies by event type; may be null for lifecycle events.

Possible flows:

  • identity_verification
  • connect
  • account_verification
  • transactions

Sample Events

opal.session.started

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

opal.session.errored

{
  "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

{
  "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.startedOpal UI opened and session began.
SESSION_COMPLETED - opal.session.completedUser completed the overall Opal flow successfully.
SESSION_ERRORED - opal.session.erroredA recoverable or terminal error occurred.
SESSION_EXITED - opal.session.exitedUser closed or dismissed Opal before completion.
FLOW_STARTED - opal.flow.startedA sub-flow (for any mode) started.
FLOW_COMPLETED - opal.flow.completedA sub-flow (for any mode) completed.
STEP_STARTED - opal.step.startedA step (screen) started.
STEP_COMPLETED - opal.step.completedA step (screen) completed.
IDV_FLOW_STARTED - identity_verification.flow.startedIdentity Verification flow started.
IDV_STEP_STARTED - identity_verification.step.startedA step in Identity Verification started.
IDV_STEP_COMPLETED - identity_verification.step.completedA step in Identity Verification completed.
IDV_FLOW_COMPLETED - identity_verification.flow.completedIdentity Verification flow completed.
IDV_VERIFICATION_COMPLETED - identity_verification.identity.completedIdentity successfully verified (KYC passed).
CXN_FLOW_STARTED - connect.flow.startedConnect flow started.
CXN_STEP_STARTED - connect.step.startedA step in Connect started.
CXN_STEP_COMPLETED - connect.step.completedA step in Connect completed.
CXN_FLOW_COMPLETED - connect.flow.completedConnect flow completed.
CXN_ACCOUNTS_SELECTED - connect.accounts.selectedUser selected one or more accounts to connect.
AVF_FLOW_STARTED - account_verification.flow.startedAccount Verification flow started.
AVF_STEP_STARTED - account_verification.step.startedA step in Account Verification started.
AVF_STEP_COMPLETED - account_verification.step.completedA step in Account Verification completed.
AVF_FLOW_COMPLETED - account_verification.flow.completedAccount Verification flow completed.
AVF_CARD_VERIFIED - account_verification.card.verifiedCard verified successfully.
TXN_FLOW_STARTED - transactions.flow.startedTransactions flow started.
TXN_STEP_STARTED - transactions.step.startedA step in Transactions started.
TXN_STEP_COMPLETED - transactions.step.completedA step in Transactions completed.
TXN_FLOW_COMPLETED - transactions.flow.completedTransactions flow completed.
TXN_ACCOUNTS_LINKED - transactions.accounts.linkedAccounts linked and subscribed for transactions.

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
Use these payloads to retrieve context such as selected accounts, verification results, or linkage details.

Enhanced Event Handling

Using the JavaScript SDK

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

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
I