> For the complete documentation index, see [llms.txt](https://even-financial.gitbook.io/developer-center/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://even-financial.gitbook.io/developer-center/marketplace-integrations/mobile-sdks/banking/flutter.md).

# Flutter

Flutter Banking Mobile SDK Integration Guide

## Overview

This documentation covers installation, required prerequisites, the configuration properties surfaced for the Banking product type (`channel`, `zone`, `queryParams`, `clientTags`), and a basic usage example.

## Setup Instructions

You'll need the correct `channel` and `zone` values for your integration. Ask your Partner Manager to provide these values for Flutter Banking.

### Step 1: Confirm Software Requirements

* Flutter 3.0.0 or higher
* Dart 3.10.7 or higher

### Step 2: Install the SDK

Install the SDK via pub get:

```yaml
flutter pub add engine_mobile_flutter_sdk
```

Note: This installs the latest compatible SDK version. For a specific version, pin it explicitly in pubspec.yaml.

### Step 3: Initialize the SDK

In your app, initialize the SDK by adding the following imports to any Dart file where you want to use it. The second import exposes `ProductType` (imported with the `engine` prefix to avoid name collisions with Flutter):

```dart
import 'package:engine_mobile_flutter_sdk/engine_mobile_flutter_sdk.dart';
import 'package:engine_mobile_flutter_sdk/api_models.dart' as engine;
```

### Basic Example

Place the `EngineSDK` widget anywhere in your widget tree to render the Banking flow.

```dart
Scaffold(
  resizeToAvoidBottomInset: false, // see the note below
  body: EngineSDK(
    channel: 'your-channel',
    zone: 'your-zone',
    productTypes: const [engine.ProductType.savings],
    queryParams: const {'zip': '10011'},
    onExit: (_) {
      debugPrint("Exit triggered from SDK");
      Navigator.pop(context);
    },
    // ...optional event handlers, please see Event Handlers section below
  ),
)
```

{% hint style="warning" %}
**Known limitation:** Please set `resizeToAvoidBottomInset: false` on the `Scaffold` that hosts `EngineSDK` so Flutter doesn't resize the body on top of the WebView's own keyboard handling.
{% endhint %}

## Properties

Pass these properties to `EngineSDK`:

<table><thead><tr><th width="220">Prop</th><th width="220">Type</th><th width="130">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>channel</code></td><td><code>String</code></td><td>Yes</td><td>Identifies your integration in Engine. Provided by your Partner Manager (e.g. <code>'direct'</code>).</td></tr><tr><td><code>zone</code></td><td><code>String</code></td><td>Yes</td><td>Identifies the placement or distribution surface for the SDK. Provided by your Partner Manager (e.g. <code>'banking'</code>).</td></tr><tr><td><code>productTypes</code></td><td><code>List&#x3C;ProductType></code></td><td>Yes</td><td>Product flow(s) to render. <code>ProductType</code> is imported from the Engine SDK package — use <code>[engine.ProductType.savings]</code> for Banking, which maps to the string value <code>"savings"</code>.</td></tr><tr><td><code>queryParams</code></td><td><code>Map&#x3C;String, String></code></td><td>No</td><td>Query parameters appended to the Banking experience. Supported key: <code>zip</code>. See <a href="#query-parameters">Query Parameters</a> below.</td></tr><tr><td><code>clientTags</code></td><td><code>Map&#x3C;String, List&#x3C;String>></code></td><td>No</td><td>Arbitrary key/value tags for reporting and attribution. See <a href="#client-tags-for-reporting">Client Tags for Reporting</a> below.</td></tr><tr><td><code>onExit</code></td><td><code>OnExitCallback</code></td><td>Yes</td><td>Fired when the user exits the flow.</td></tr><tr><td><code>onInitialize</code>, <code>onCreate</code>, <code>onRateTableRender</code>, <code>onOfferClick</code>, <code>onErrorPageView</code>, <code>onErrorPageRetry</code>, <code>onEmbedError</code>, <code>onEmbedErrorRetry</code></td><td>Callbacks</td><td>No</td><td>Optional tracking hooks. See <a href="#event-handlers">Event Handlers</a> below.</td></tr></tbody></table>

## Query Parameters

`queryParams` is a `Map<String, String>` of parameters appended to the Banking experience the SDK loads. Use it to preselect what the user sees on the explore screen.

### Supported Keys

<table><thead><tr><th width="180">Key</th><th width="180">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>zip</code></td><td><code>String</code></td><td>5-digit US ZIP code. Preselects the user's location.</td></tr></tbody></table>

### Example

```dart
EngineSDK(
  channel: 'your-channel',
  zone: 'your-zone',
  productTypes: const [engine.ProductType.savings],
  queryParams: const {'zip': '10011'},
  onExit: (_) {},
)
```

## Client Tags for Reporting

The Engine Flutter SDK supports adding your unique Client Tags to track performance of specific campaigns or users. All Client Tag data is attributed to the lead level.

Client Tags can be added by including a **clientTags** attribute at the top level of the EngineSDK widget, where the value is a **Map\<String, List\<String>>**.

We strongly recommend including only one element per list for ease of reporting and attribution—if you want two separate tags, include the second tag under a different key. There is no limit to the number of keys in the **clientTags** map

### Example

```dart
EngineSDK( 
channel: '{your_channel}', 
zone: '{your_zone}', 
productTypes: const [engine.ProductType.loan],
clientTags: const { 
'clientId': ['client1'], 
'trafficsource': ['email'], 
'campaignId': ['campaign1'], 
}, 
// ...optional Event Handlers, please see Event Handler section 
)
```

### Supported Client Tag Keys for Reporting

If you plan for the Engine team to set up reporting (i.e., you do not plan to hit the Analytics API), these are the only keys that are currently fully supported. If a different key is needed, please reach out to your partner manager—we may be able to accommodate, but adding nonstandard keys will increase the time it takes Engine to report Client Tag values back to you and is therefore not recommended.

* agentId
* campaignId
* clientId
* deviceid
* medium
* sourceId
* subid
* subid1
* subid2
* subid3
* target
* trafficsource
* userid

See the [GET Lead Client Tags](https://engine.tech/docs/api-reference/#get-lead-client-tags) endpoint for information on attributing lead analytics to your own client tags, if you decide to hit the Analytics API for reporting.

## Event Handlers

`EngineSDK` exposes optional callback arguments that notify your app when key moments occur during the user's journey. Each callback receives a strongly-typed event object containing a `timestamp` (ISO 8601 UTC) and event-specific fields.

All callbacks are optional except `onExit`. Pass any combination when constructing `EngineSDK`. If a callback is not provided, the SDK will still log the event to the debug console in development mode.

```dart
EngineSDK(
  channel: 'your-channel',
  zone: 'your-zone',
  productTypes: const [engine.ProductType.savings],
  queryParams: const {'zip': '10011'},
  onInitialize: (event) {
    debugPrint('SDK initialized at ${event.timestamp}');
  },
  onCreate: (event) {
    debugPrint('Lead created: ${event.leadUuid}');
  },
  onRateTableRender: (event) {
    debugPrint('Offers rendered: ${event.bankingOffers?.length}');
  },
  onOfferClick: (event) {
    debugPrint('Offer clicked: ${event.offerUuid}');
  },
  onExit: (event) {
    // Navigate the user back or perform cleanup
    Navigator.pop(context);
  },
  // ...other callbacks
)
```

### Available Events

For Banking, `onRateTableRender` populates `bankingOffers`, and `onOfferClick` carries `leadUuid`, `offerUuid`, `financialInstitutionName`, `financialInstitutionUuid`, `productType`, and `productSubType`.

| Callback              | Event Type           | Trigger                          |
| --------------------- | -------------------- | -------------------------------- |
| **onInitialize**      | InitializeEvent      | SDK finished loading the embed   |
| **onCreate**          | CreateEvent          | New lead created                 |
| **onRateTableRender** | RateTableRenderEvent | Rate table displayed with offers |
| **onOfferClick**      | OfferClickEvent      | User clicked an offer            |
| **onErrorPageView**   | ErrorPageViewEvent   | Error page displayed in the flow |
| **onErrorPageRetry**  | ErrorPageRetryEvent  | User retried from the error page |
| **onExit**            | ExitEvent            | User exited the SDK              |
| **onEmbedError**      | EmbedErrorEvent      | Web embed failed to load         |
| **onEmbedErrorRetry** | EmbedErrorRetryEvent | User retried after embed failure |

Every event includes a `timestamp` (ISO 8601 UTC). All other fields are optional and may be null or absent.

**onInitialize**

Fired once, when the SDK finishes loading the embedded experience for the first time.

| Field         | Type   | Description                                          |
| ------------- | ------ | ---------------------------------------------------- |
| **timestamp** | String | ISO 8601 UTC timestamp of when the event was emitted |

**onCreate**

Fired when a new lead is created.

| Field          | Type   | Description                                           |
| -------------- | ------ | ----------------------------------------------------- |
| **timestamp**  | String | ISO 8601 UTC timestamp of when the event was emitted  |
| **leadUuid**   | String | Unique identifier for the newly created lead          |
| **createPage** | String | The page where the lead was created. Always `explore` |

**onRateTableRender**

Fired when the rate table is rendered with offers.

| Field             | Type   | Description                                          |
| ----------------- | ------ | ---------------------------------------------------- |
| **timestamp**     | String | ISO 8601 UTC timestamp of when the event was emitted |
| **rateTableUuid** | String | Unique identifier for the Engine rate table          |
| **bankingOffers** | List   | Array of banking offers returned for the lead        |

**onOfferClick**

Fired when the user clicks an offer in the rate table.

| Field                        | Type   | Description                                                      |
| ---------------------------- | ------ | ---------------------------------------------------------------- |
| **timestamp**                | String | ISO 8601 UTC timestamp of when the event was emitted             |
| **leadUuid**                 | String | Unique identifier for the lead                                   |
| **offerUuid**                | String | Unique identifier for the clicked offer                          |
| **financialInstitutionName** | String | Name of the institution offering the account (e.g. Example Bank) |
| **financialInstitutionUuid** | String | Unique identifier for the institution                            |
| **productType**              | String | Type of product (e.g. `savings`)                                 |
| **productSubType**           | String | Account product sub-type (e.g. `savings_account`)                |

**onErrorPageView**

Fired when the error page is displayed within the embedded flow. This is different from `onEmbedError`, which fires when the embedded experience itself fails to load.

| Field         | Type   | Description                                                 |
| ------------- | ------ | ----------------------------------------------------------- |
| **timestamp** | String | ISO 8601 UTC timestamp of when the event was emitted        |
| **leadUuid**  | String | Unique identifier for the lead                              |
| **fromPage**  | String | The page the user was on before the error. Always `explore` |

**onErrorPageRetry**

Fired when the user taps "Retry" on the error page within the embedded flow.

| Field         | Type   | Description                                                    |
| ------------- | ------ | -------------------------------------------------------------- |
| **timestamp** | String | ISO 8601 UTC timestamp of when the event was emitted           |
| **leadUuid**  | String | Unique identifier for the lead                                 |
| **toPage**    | String | The page the user is retrying to navigate to. Always `explore` |

**onExit**

Fired when the user dismisses the SDK.

| Field         | Type   | Description                                          |
| ------------- | ------ | ---------------------------------------------------- |
| **timestamp** | String | ISO 8601 UTC timestamp of when the event was emitted |

**onEmbedError**

Fired when the embedded experience fails to load (network error, or an HTTP status of 400 or above). The SDK then shows an error screen with "Retry" and "Close" options.

| Field            | Type   | Description                                          |
| ---------------- | ------ | ---------------------------------------------------- |
| **timestamp**    | String | ISO 8601 UTC timestamp of when the event was emitted |
| **errorMessage** | String | Description of the error that occurred               |

**onEmbedErrorRetry**

Fired when the user taps "Retry" on the SDK's error screen after a load failure.

| Field            | Type   | Description                                                |
| ---------------- | ------ | ---------------------------------------------------------- |
| **timestamp**    | String | ISO 8601 UTC timestamp of when the event was emitted       |
| **errorMessage** | String | Description of the original error that triggered the retry |

## Changelog

<details>

<summary>View the full Flutter SDK changelog</summary>

### 1.4.0 (2026-11-03)

* Updated how the SDK identifies its delivery method when loading the hosted experience

### 1.3.0 (2026-10-20)

* Add new product vertical support

### 1.2.1 (2026-10-13)

* Fixed external browser behavior to properly open links outside the app

### 1.2.0 (2026-09-29)

* Improve type definition
* If you imported `package:engine_mobile_flutter_sdk/src/models/engine_events.dart` directly, import `package:engine_mobile_flutter_sdk/engine_mobile_flutter_sdk.dart` instead

  ```diff
  -import 'package:engine_mobile_flutter_sdk/src/models/engine_events.dart';
  +import 'package:engine_mobile_flutter_sdk/engine_mobile_flutter_sdk.dart';
  ```

### 1.1.0 (2026-09-15)

* Made channel and zone required properties for SDK initialization.

### 1.0.0 (2026-07-21)

* Remove deprecated `prefilledData` prop from Flutter SDK
* Prefill is now done via `personalInformation`, `loanInformation`, `mortgageInformation`, `creditInformation`, `financialInformation`, `employmentInformation`, `legalInformation`, `creditCardInformation`, `educationInformation` props.

### 0.1.1 (2026-07-01)

* Added explicit dependency declaration for improved Flutter SDK compatibility

### 0.1.0 (2026-07-01)

* Added support for credit card process in Flutter SDK
* Integrated OpenAPI specifications for improved API type safety and reliability
* Enhanced embed URL resolution to properly handle partner page prefill URLs

### 0.0.8 (2026-05-19)

* Improved error handling by ensuring users can always exit error states
* Enhanced Flutter SDK navigation by adding exit callback support

### 0.0.7 (21 Apr 2026)

* Minor internal improvements

### 0.0.6 (31 Mar 2026)

* Updated event callbacks with new event model
* Removed unused `onClose` event
* Added key for close button in WebView container
* Code formatting and refactoring improvements

### 0.0.5 (24 Mar 2026)

* Enabled prefill API call and updated `LeadPrefillData` to use typed model instead of raw map
* Added lead prefill enums (`LoanPurpose`, `CreditRating`, `PropertyStatus`, `EducationLevel`, `EmploymentStatus`, `PayFrequency`)
* Added input sanitization for prefill data (phone, email, SSN, address, loan amount, bank routing number)
* Improved `ApiException` with truncated `toString()` for better error messages
* Added loading overlay with progress indicator on WebView

### 0.0.3 (6 Mar 2026)

* Added JavaScript channel for SDK events
* Added props to expose to partner app
* Flatten props and refactor code
* Added constants and functions to build embed URL
* Added leads prefill endpoint integration
* Implemented error state handling and updated nav bar
* Updated README and DEVELOPMENT.md

### 0.0.2 (20 Feb 2026)

* Added WebView widget for rendering the Engine marketplace
* Added leads prefill scaffold with basic data models and service layer

### 0.0.1 (9 Feb 2026)

* Initial release - Basic SDK structure and documentation

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://even-financial.gitbook.io/developer-center/marketplace-integrations/mobile-sdks/banking/flutter.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
