Link iOS SDK 
=============

#### Reference for integrating with the Link iOS SDK 

#### Overview 

The Plaid Link SDK is a quick and secure way to link bank accounts to Plaid from within your iOS app. LinkKit is a drop-in framework that handles connecting a financial institution to your app (credential validation, multi-factor authentication, error handling, etc.) without passing sensitive information to your server.

[Prefer to learn by watching? Check out this quick guide to implementing Plaid on iOS devices](https://www.youtube.com/watch?v=QXHHRSSaspY)

Want even more video lessons? A [full tutorial](https://youtu.be/9fgmW38usTo) for integrating Plaid with iOS is available on our YouTube channel.

To get started with Plaid Link for iOS, clone the [GitHub repository](https://github.com/plaid/plaid-link-ios) and try out the example application, which provides a reference implementation in both Swift and Objective-C. You'll want to sign up for [free API keys](https://dashboard.plaid.com/developers/keys) through the Plaid Dashboard to get started.

#### Initial iOS setup 

Before writing code using the SDK, you must first perform some setup steps to register your app with Plaid and configure your project.

The "Register your redirect URI" and "Set up Universal Links" steps describe setting up your app for OAuth redirects. If your integration uses only Link flows that do not initiate connections to financial institutions, such as the Identity Verification or Document Income flows, they can be skipped; they are mandatory otherwise.

##### Register your redirect URI 

1.  Sign in to the [Plaid Dashboard](https://dashboard.plaid.com/signin) and go to the [Developers -> API](https://dashboard.plaid.com/developers/api) page.
2.  Next to **Allowed redirect URIs** click **Configure** then **Add New URI**.
3.  Enter your redirect URI, which you must also set up as a Universal Link for your application, for example: `https://app.example.com/plaid/`.
4.  Click **Save Changes**.

These redirect URIs must be set up as [Universal Links](https://developer.apple.com/ios/universal-links/) in your application. For details, see Apple's documentation on [Allowing Apps and Websites to Link to Your Content](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content) .

Plaid does not support registering URLs with custom URL schemes as redirect URIs since they lack the security of Universal Links through the two-way association between your app and your website. Any application can register custom URL schemes and there is no further validation from iOS. If multiple applications have registered the same custom URL scheme, a different application may be launched each time the URL is opened. To complete Plaid OAuth flows, it is important that _your_ application is opened and not any arbitrary application that has registered the same URL scheme.

##### Set up Universal Links 

In order for Plaid to return control back to your application after a user completes a bank's OAuth flow, you must specify a redirect URI, which will be the URI from which Link will be re-launched to complete the OAuth flow. The redirect URI must be a Universal Link. An example of a typical redirect URI is: `https://app.example.com/plaid`.

Universal Links consist of the following parts:

*   An `applinks` entitlement for the Associated Domains capability in your app. For details, see Apple's documentation on the [Associated Domains Entitlement](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_associated-domains) and the [entitlements example](https://github.com/plaid/plaid-link-ios/blob/master/LinkDemo-Swift/LinkDemo-Swift/LinkDemo-Swift.entitlements) in the LinkDemo-Swift example app.
*   An `apple-app-site-association` file on your website. For details, see Apple's documentation on [Supporting Associated Domains](https://developer.apple.com/documentation/xcode/supporting-associated-domains) and see our minimal example below.

There are a few requirements for `apple-app-site-association` files:

*   Must be a static JSON file
*   Must be hosted using a `https://` scheme with a valid certificate and no redirects
*   Must be hosted at `https://<my-fully-qualified-domain>/.well-known/apple-app-site-association`

Below is an example for `https://my-app.com` (`https://my-app.com/.well-known/apple-app-site-association`)

```json
{
  "applinks": {
    "details": [
      {
        "appIDs": ["<My Application Identifier Prefix>.<My Bundle ID>"],
        "components": [
          {
            "/": "/plaid/*",
            "comment": "Matches any URL path whose path starts with /plaid/"
          }
        ]
      }
    ]
  }
}
```

Once you have enabled Universal Links, your iOS app is now set up and ready to start integrating with the Plaid SDK.

Ensure that the corresponding entry for the configured redirect URI in the `apple-app-site-association` file on your website continues to be available. If it is removed, OAuth sessions will fail until it is available again.

#### Installation 

Plaid Link for iOS is an embeddable framework that is bundled and distributed with your application. To obtain the necessary files and keep them up-to-date, we recommend using [Swift Package Manager](https://swiftpackageindex.com/plaid/plaid-link-ios) . Regardless of what you choose, submitting a new version of your application with the updated [LinkKit.xcframework](https://github.com/plaid/plaid-link-ios/releases) to the App Store is required.

##### Requirements 

| LinkKit iOS version | Xcode toolchain minimum support | Supported iOS versions |
| --- | --- | --- |
| LinkKit 7.x.x (beta) | Xcode 16.1 | iOS 15 or greater |
| LinkKit 6.x.x | Xcode 16.1 | iOS 14 or greater |
| LinkKit 5.x.x | Xcode 15 | iOS 14 or greater |
| LinkKit 4.x.x | Xcode 14 | iOS 11 or greater |
| LinkKit 3.x.x | Xcode 13 | iOS 11 or greater |

Select group for content switcher

Swift Package ManagerCocoaPodsManual

##### Swift Package Manager 

1.  To integrate LinkKit using Swift Package Manager, Swift version >= 5.3 is required.
2.  In your Xcode project from the Project Navigator (**Xcode ❯ View ❯ Navigators ❯ Project ⌘ 1**) select your project, activate the **Package Dependencies** tab and click on the plus symbol **➕** to open the **Add Package** popup window:
    
    (An image of "Xcode interface showing how to add a Swift package dependency; plus button highlighted.")
    
3.  Enter the LinkKit package URL `https://github.com/plaid/plaid-link-ios-spm` into the search bar in the top right corner of the **Add Package** popup window. The main repository with full git history is very large (~1 GB), and Swift Package Manager always downloads the full repository with all git history. This `plaid-link-ios-spm` repository is much smaller (less than 500kb), making the download faster.
4.  Select the `plaid-link-ios-spm` package.
5.  Choose your **Dependency Rule** (we recommend **Up to Next Major Version**).
6.  Select the project to which you would like to add LinkKit, then click **Add Package**:
    
    (An image of "Xcode screenshot showing input of Plaid Link iOS Swift package URL for package addition. 'Add Package' button highlighted.")
    
7.  Select the `LinkKit` package product and click **Add Package**:
    
    (An image of "Dialog in Xcode for selecting Plaid link-ios package. 'LinkKit' checked, type 'Library', target 'MySampleApp'.")
    
8.  Verify that the LinkKit Swift package was properly added as a package dependency to your project:
    
    (An image of "Xcode showing the Plaid Link iOS package dependency from GitHub in Package Dependencies tab.")
    
9.  Select your application target and ensure that the LinkKit library is embedded into your application:
    
    (An image of "Xcode screenshot showing the Frameworks section with LinkKit listed under Package Dependencies for MySampleApp.")
    

##### CocoaPods 

Using CocoaPods is highly discouraged. CocoaPods will officially become read-only on December 2, 2026. The last Plaid iOS SDK release that will support CocoaPods is 6.4.7 (released March 19, 2026). Version 7.x of the Plaid iOS SDK will not support CocoaPods. New integrations should use Swift Package Manager instead.

1.  If you haven't already, install the latest version of [CocoaPods](https://guides.cocoapods.org/using/getting-started.html) .
2.  If you don't have an existing Podfile, run the following command to create one:
    
    Create a new Podfile
    
    ```bash
    pod init
    ```
    
3.  Add this line to your `Podfile`:
    
    Edit the Podfile to include the following line
    
    ```bash
    pod 'Plaid'
    ```
    
4.  Run the following command:
    
    Install the Plaid and other CocoaPods
    
    ```bash
    pod install
    ```
    
5.  To update to newer releases in the future, run:
    
    Update the Plaid and other CocoaPods
    
    ```bash
    pod install
    ```
    

##### Manual 

Get the latest version of the [LinkKit.xcframework](https://github.com/plaid/plaid-link-ios/releases) and embed it into your application, for example by dragging and dropping the XCFramework bundle onto the **Embed Frameworks** build phase of your application target in Xcode as shown below.

(An image of "Xcode project with LinkKit.xcframework added under Frameworks, Libraries, and Embedded Content. LinkKit.xcframework folder in Downloads.")

  

##### Camera Support (Identity Verification only) 

When using the [Identity Verification](https://plaid.com/docs/identity-verification/index.html.md) product, the Link SDK may use the camera if a user needs to take a picture of identity documentation or a selfie. To support this workflow, add a [NSCameraUsageDescription](https://developer.apple.com/documentation/bundleresources/information_property_list/nscamerausagedescription) entry to your application's plist with an informative string. This allows iOS to prompt the user for camera access. iOS will crash your application if this string is not provided.

##### Upgrading 

New versions of [LinkKit.xcframework](https://github.com/plaid/plaid-link-ios/releases) are released frequently. Major releases occur annually. The Link SDK uses Semantic Versioning, ensuring that all non-major releases are non-breaking, backwards-compatible updates. We recommend you update regularly (at least once a quarter, and ideally once a month) to ensure the best Plaid Link experience in your application.

SDK versions are supported for two years; with each major SDK release, Plaid will stop officially supporting any previous SDK versions that are more than two years old. While these older versions are expected to continue to work without disruption, Plaid will not provide assistance with unsupported SDK versions.

For details on each release see the [GitHub releases](https://github.com/plaid/plaid-link-ios/releases) and [version release notes](https://github.com/plaid/plaid-link-ios/blob/master/CHANGELOG.md) .

#### Opening Link 

Before you can open Link, you need to first create a `link_token`. A `link_token` can be configured for different Link flows and is used to control much of Link's behavior. To learn how to create a new `link_token`, see the API Reference entry for [/link/token/create](https://plaid.com/docs/api/link/index.html.md#linktokencreate) .

For iOS the [/link/token/create](https://plaid.com/docs/api/link/index.html.md#linktokencreate) call must include the `redirect_uri` parameter and it must match the redirect URI you have configured with Plaid (see [Register your redirect URI](https://plaid.com/docs/link/ios/index.html.md#register-your-redirect-uri) above).

##### Create a Configuration 

Starting the Plaid Link for iOS experience begins with creating a `link_token`. Once the `link_token` is passed to your app, create an instance of `LinkTokenConfiguration`, then create a `Handler` using `Plaid.create()` passing the previously created `LinkTokenConfiguration`. Plaid will begin to pre-load Link as soon as `Plaid.create()` is called, so to reduce UI latency when rendering Link, you should call `Plaid.create()` when initializing the screen where the user can enter the Link flow.

After calling `Plaid.create()`, to show the Link UI, call `open()` on the handler passing your preferred presentation method.

Note that each time you open Link, you will need to get a new `link_token` from your server and create a new `LinkTokenConfiguration` with it.

**Properties**

String

Specify a `link_token` to authenticate your app with Link. This is a short lived, one-time use token that should be unique for each Link session. In addition to the primary flow, a `link_token` can be configured to launch Link in [update mode](https://plaid.com/docs/link/update-mode/index.html.md) . See the `/link/token/create` endpoint for more details.

closure

A required closure that is called when a user successfully links an Item. The closure should expect a single `LinkSuccess` argument, containing the `publicToken` String and a `metadata` of type `SuccessMetadata`. See [onSuccess](https://plaid.com#onsuccess) below.

closure

An optional closure that is called when a user exits Link without successfully linking an Item, or when an error occurs during Link initialization. The closure should expect a single `LinkExit` argument, containing an optional `error` and a `metadata` of type `ExitMetadata`. See [onExit](https://plaid.com#onexit) below.

closure

An optional closure that is called when a user reaches certain points in the Link flow. The closure should expect a single `LinkEvent` argument, containing an `eventName` enum of type `EventType` and a `metadata` of type `EventMetadata`. See [onEvent](https://plaid.com#onevent) below.

```swift
var linkConfiguration = LinkTokenConfiguration(
    token: "<#LINK_TOKEN_FROM_SERVER#>",
    onSuccess: { linkSuccess in
        // Send the linkSuccess.publicToken to your app server.
    }
)

// Optional: Configure additional Link presentation options. 

// If true, skips the default Link loading animation.
// Use this if you're displaying your own custom loading UI.
linkConfiguration.noLoadingState = true

// Optional: Configure additional Link presentation options -
// Available in SDK v6.2.0 and above:

// If false, displays a solid background instead of the default
// transparent gradient.
linkConfiguration.showGradientBackground = false

```

```objectivec
PLKLinkTokenConfiguration* linkConfiguration = [PLKLinkTokenConfiguration createWithToken:@"<#LINK_TOKEN_FROM_SERVER#>"
                                                                                onSuccess:^(PLKLinkSuccess *linkSuccess) {
    // Send the linkSuccess.publicToken to your app server.
}];

// Optional: Configure additional Link presentation options:

// If true, skips the default Link loading animation.
// Use this if you're displaying your own custom loading UI.
// Be sure to dismiss your loading UI when you receive the
// OPEN and EXIT events.
linkConfiguration.noLoadingState = YES;

// Optional: Configure additional Link presentation options –
// Available in SDK v6.2.0 and above:

// If NO, displays a solid background instead of the default
// transparent gradient. This is useful when customizing the UI or
// providing your own background. For best results, also set
// `noLoadingState = YES` to avoid conflicting visuals.
linkConfiguration.showGradientBackground = NO;

```

##### Create a Handler 

A `Handler` is a one-time use object used to open a Link session. The `Handler` must be retained for the duration of the Plaid SDK flow. It will also be needed to respond to OAuth Universal Link redirects. For more details, see the [OAuth guide](https://plaid.com/docs/link/oauth/index.html.md#ios) .

You can optionally provide an `onLoad` (available in **SDK v6.2.0 and above**) callback to know when Link has finished preloading and is ready to be presented. This is useful if you want to delay presenting Link until it's fully loaded, or enable related UI elements.

Note for Layer customers: You should wait for the `LAYER_READY` event before presenting Link, rather than relying solely on `onLoad`.

```swift
let result = Plaid.create(linkConfiguration, onLoad: { [weak self] in
    // Optional callback invoked once Plaid Link has finished preloading and is ready
    // to be presented.
    //
    // Example: Enable a button once Link has loaded
    // self?.openButton.isEnabled = true
    //
    // Example: Automatically present Link once it has loaded
    // guard let self = self else { return }
    // self.handler?.open(presentUsing: .viewController(self))
})

switch result {
case .failure(let error):
    logger.error("Unable to create Plaid handler due to: \(error)")
case .success(let handler):
    // Retain the handler for the duration of the Link flow (and OAuth redirects)
    self.handler = handler
}

```

```objectivec
// Choose ONE of the following examples. In both cases, retain the handler for the
// duration of the Link flow (and OAuth redirects).

// --- Example 1: With onLoad (requires iOS SDK v6.2.0+) ---
{
  NSError *createError = nil;

  id handler =
    [PLKPlaid createWithLinkTokenConfiguration:linkConfiguration
                                       onLoad:^{
      // Optional callback that is invoked once Plaid Link has
      // finished loading and is ready to be presented.
      // You could use your own loading UI and automatically launch
      // Link when this callback fires.
      //
      // Example:
      //     [self.linkHandler openWithContextViewController:self];
      //
      // Example: Enable a button once Link has loaded
      //     self.openButton.enabled = YES;
    }
                                        error:&createError];

  if (handler) {
    self.linkHandler = handler;
  } else {
    NSLog(@"Unable to create PLKHandler due to: %@", createError);
  }
}

// --- Example 2: Without onLoad ---
{
  NSError *createError = nil;

  id handler =
    [PLKPlaid createWithLinkTokenConfiguration:linkConfiguration
                                        error:&createError];

  if (handler) {
    self.linkHandler = handler;
  } else {
    NSLog(@"Unable to create PLKHandler due to: %@", createError);
  }
}

```

##### Open Link 

Finally, open Link by calling `open` on the `Handler` object. This will usually be done in a button's target action.

```swift
let method: PresentationMethod = .viewController(self)
handler.open(presentUsing: method)

```

```objectivec
[handler openWithContextViewController:self];

```

\=\*=\*=\*=

#### onSuccess 

The closure is called when a user successfully links an Item. It should take a single `LinkSuccess` argument, containing the `publicToken` String and a `metadata` of type `SuccessMetadata`.

**Properties**

LinkSuccess

Contains the `publicToken` and `metadata` for this successful flow.

String

Displayed once a user has successfully completed Link. If using Identity Verification or Beacon, this field will be `null`. If using Document Income or Payroll Income, the `public_token` will be returned, but is not used.

LinkSuccess

Displayed once a user has successfully completed Link.

nullable, Institution

An institution object. If the Item was created via Same-Day Micro-deposit verification, will be `null`.

String

The full institution name, such as 'Wells Fargo'

InstitutionID (String)

The Plaid institution identifier

Array<Account>

A list of accounts attached to the connected Item

AccountID (String)

The Plaid `account_id`

String

The official account name

Optional<AccountMask> (Optional<String>)

The last 2-4 alphanumeric characters of an account's official account number. Note that the mask may be non-unique between an Item's accounts, it may also not match the mask that the bank displays to the user.

AccountSubtype

The account subtype and its type. See [Account Types](https://plaid.com/docs/api/accounts/index.html.md#account-type-schema) for a full list of possible values.

Optional<VerificationStatus>

Indicates an Item's micro-deposit-based verification or database verification status. Possible values are:

`pending_automatic_verification`: The Item is pending automatic verification.

`pending_manual_verification`: The Item is pending manual micro-deposit verification. Items remain in this state until the user successfully verifies the deposit.

`automatically_verified`: The Item has successfully been automatically verified.

`manually_verified`: The Item has successfully been manually verified.

`verification_expired`: Plaid was unable to automatically verify the deposit within 7 calendar days and will no longer attempt to validate the Item. Users may retry by submitting their information again through Link.

`verification_failed`: The Item failed manual micro-deposit verification because the user exhausted all 3 verification attempts. Users may retry by submitting their information again through Link.

`database_matched`: The Item has successfully been verified using Plaid's data sources.

`database_insights_pending`: The Database Insights result is pending and will be available upon Auth request.

`nil`: Neither micro-deposit-based verification nor database verification are being used for the Item.

String

A unique identifier associated with a user's actions and events through the Link flow. Include this identifier when opening a support ticket for faster turnaround.

String

Unprocessed metadata, formatted as JSON, sent from the Plaid API.

```swift
onSuccess: { linkSuccess in
  // Send the linkSuccess.publicToken to your app server.
}

```

```objectivec
onSuccess:^(PLKLinkSuccess *success) {
  // Send the linkSuccess.publicToken to your app server.
}

```

\=\*=\*=\*=

#### onExit 

This optional closure is called when a user exits Link without successfully linking an Item, or when an error occurs during Link initialization. It should take a single `LinkExit` argument, containing an optional `error` and a `metadata` of type `ExitMetadata`.

**Properties**

LinkExit

Contains the optional `error` and `metadata` for when the flow was exited.

Optional<ExitError> (Swift), Optional<NSError> (Objective-C)

An Error type that contains the `errorCode`, `errorMessage`, and `displayMessage` of the error that was last encountered by the user. If no error was encountered, `error` will be `nil`. In Objective-C, field names will match the `NSError` type.

ExitErrorCode

The error code and error type that the user encountered. Each `errorCode` has an associated `errorType`, which is a broad categorization of the error.

String

A developer-friendly representation of the error code.

Optional<String>

A user-friendly representation of the error code or `nil` if the error is not related to user action. This may change over time and is not safe for programmatic use.

ExitMetadata

Displayed if a user exits Link without successfully linking an Item.

Optional<ExitStatus>

The status key indicates the point at which the user exited the Link flow.

User prompted to answer security question(s).

User prompted to answer multiple choice question(s).

User prompted to provide a one-time passcode.

User prompted to select a device on which to receive a one-time passcode.

User prompted to provide credentials for the selected financial institution or has not yet selected a financial institution.

User prompted to select one or more financial accounts to share

User exited the Link flow on the institution selection pane. Typically this occurs after the user unsuccessfully (no results returned) searched for a financial institution. Note that this status does not necessarily indicate that the user was unable to find their institution, as it is used for all user exits that occur from the institution selection pane, regardless of other user behavior.

User exited the Link flow after discovering their selected institution is no longer supported by Plaid

The exit status has not been defined in the current version of the SDK. The `unknown` case has an associated value carrying the original exit status as sent by the Plaid API.

Optional<Institution>

An institution object. If the Item was created via Same-Day Micro-deposit verification, will be omitted.

InstitutionID (String)

The Plaid specific identifier for the institution.

String

The full institution name, such as 'Wells Fargo'.

Optional<String>

A unique identifier associated with a user's actions and events through the Link flow. Include this identifier when opening a support ticket for faster turnaround.

Optional<String>

The request ID for the last request made by Link. This can be shared with Plaid Support to expedite investigation.

RawJSONMetadata (String)

Unprocessed metadata, formatted as JSON, sent from Plaid API.

```swift
linkConfiguration.onExit = { linkExit in
  // Optionally handle linkExit data according to your application's needs
}

```

```objectivec
linkConfiguration.onExit = ^(PLKLinkExit * linkExit) {
  // Optionally handle linkExit data according to your application's needs
};

```

\=\*=\*=\*=

#### onEvent 

This closure is called when certain events in the Plaid Link flow have occurred. The `open`, `layerReady`, `layerNotAvailable`, `layerAutofillNotAvailable` events are guaranteed to fire in real time; other events will typically be fired when the Link session finishes, when `onSuccess` or `onExit` is called. Callback ordering is not guaranteed; `onEvent` callbacks may fire before, after, or surrounding the `onSuccess` or `onExit` callback, and event callbacks are not guaranteed to fire in the order in which they occurred.

The following `onEvent` callbacks are stable, which means that they are suitable for programmatic use in your application's logic: `open`, `exit`, `handoff`, `selectInstitution`, `error`, `bankIncomeInsightsCompleted`, `identityVerificationPassSession`, `identityVerificationFailSession`, `layerReady`, `layerNotAvailable`, `layerAutofillNotAvailable`. The remaining callback events are informational and subject to change, and should be used for analytics and troubleshooting purposes only.

**Properties**

LinkEvent

Contains the `eventName` and `metadata` for the Link event.

EventName

An enum representing the event that has just occurred in the Link flow.

The user was automatically sent an OTP code without a UI prompt. This event can only occur if the user's phone number was provided to Link via the `/link/token/create` call and the user has previously consented to receive OTP codes from Plaid.

The user has completed the Assets and Bank Income Insights flow.

The user closed the third-party website or mobile app without completing the OAuth flow.

The user has chosen to link a new institution instead of linking a saved institution. This event is only emitted in the Link Remember Me flow.

A recoverable error occurred in the Link flow, see the `errorCode` in the metadata.

The user has exited without completing the Link flow and the [onExit](https://plaid.com#onexit) callback is fired.

The user encountered an error while completing the third-party's OAuth login flow.

The user has exited Link after successfully linking an Item.

An Identity Match check configured via the Account Verification Dashboard failed the Identity Match rules and did not detect a match.

An Identity Match check configured via the Account Verification Dashboard passed the Identity Match rules and detected a match.

The user has started a step of the Identity Verification flow. The step is indicated by `view_name`.

The user has passed a step of the Identity Verification flow. The step is indicated by `view_name`.

The user has failed a step of the Identity Verification flow. The step is indicated by `view_name`.

The user has reached the pending review state.

The user has started a new Identity Verification session.

The user has resumed an existing Identity Verification session.

The user has passed their Identity Verification session.

The user has failed their Identity Verification session.

The user has completed their Identity Verification session, which is now in a pending review state.

The user has opened the UI of their Identity Verification session.

The user has resumed the UI of their Identity Verification session.

The user has closed the UI of their Identity Verification session.

The user's date of birth passed to Link is not eligible for Layer Extended Autofill.

The user phone number passed to Link is not eligible for Layer.

The user phone number passed to Link is eligible for Layer and `open()` may now be called.

The user selected an institution that was presented as a matched institution. This event can be emitted if [Embedded Institution Search](https://plaid.com/docs/link/embedded-institution-search/index.html.md) is being used, if the institution was surfaced as a matched institution likely to have been linked to Plaid by a returning user, or if the institution's `routing_number` was provided when calling `/link/token/create`. For details on which scenario is triggering the event, see `metadata.matchReason`.

The user has opened Link.

The user has opened my.plaid.com. This event is only sent when Link is initialized with Assets as a product.

The user has navigated to a third-party website or mobile app in order to complete the OAuth login flow.

The user has searched for an institution.

The user has chosen whether to Link instantly or manually (i.e., with micro-deposits). This event emits the `selection` metadata to indicate the user's selection.

The user selected a brand, e.g. Bank of America. The brand selection interface occurs before the institution select pane and is only provided for large financial institutions with multiple online banking portals.

The user selected an institution with a `DEGRADED` health status and was shown a corresponding message.

The user selected an institution with a `DOWN` health status and was shown a corresponding message.

The user selected an institution Plaid does not support all requested products for and was shown a corresponding message.

The user selected an institution.

The user has opted to not provide their phone number to Plaid. This event is only emitted in the Link Remember Me flow.

The user has submitted an account number. This event emits the `accountNumberMask` metadata to indicate the mask of the account number the user provided.

The user has submitted credentials.

The user is being prompted to submit documents for an Income verification flow.

The user encountered an error when submitting documents for an Income verification flow.

The user has successfully submitted documents for an Income verification flow.

The user has submitted MFA.

The user has submitted an OTP code during the phone number verification flow. This event is only emitted in the Link Returning User Experience (Remember Me) flow or the Layer flow. This event will not be emitted if the phone number is verified via SNA.

The user has submitted their phone number. This event is only emitted in the Link Remember Me flow.

The user has submitted a routing number. This event emits the `routingNumber` metadata to indicate user's routing number.

The `transitionView` event indicates that the user has moved from one view to the next.

The user is asked to upload documents (for Income verification).

The user has successfully verified their phone number via either OTP or SNA. This event is only emitted in the Link Returning User Experience (Remember Me) flow or the Layer flow.

The user has viewed data types on the data transparency consent pane.

The event has not been defined in the current version of the SDK. The `unknown` case has an associated value carrying the original event name as sent by the Plaid API.

EventMetadata struct

An object containing information about the event

Optional<String>

The account number mask extracted from the user-provided account number. If the user-inputted account number is four digits long, `account_number_mask` is empty. Emitted by `SUBMIT_ACCOUNT_NUMBER`.

Optional<ExitErrorCode>

The error code that the user encountered. Emitted by: `error`, `exit`.

Optional<String>

The error message that the user encountered. Emitted by: `error`, `exit`.

Optional<ExitStatus>

The status key indicates the point at which the user exited the Link flow. Emitted by: `exit`.

User prompted to answer security question(s).

User prompted to answer multiple choice question(s).

User prompted to provide a one-time passcode.

User prompted to select a device on which to receive a one-time passcode.

User prompted to provide credentials for the selected financial institution or has not yet selected a financial institution.

User exited the Link flow on the institution selection pane. Typically this occurs after the user unsuccessfully (no results returned) searched for a financial institution. Note that this status does not necessarily indicate that the user was unable to find their institution, as it is used for all user exits that occur from the institution selection pane, regardless of other user behavior.

The exit status has not been defined in the current version of the SDK. The unknown case has an associated value carrying the original exit status as sent by the Plaid API.

Optional<InstitutionID> (Optional<String>)

The ID of the selected institution. Emitted by: _all events_.

Optional<String>

The name of the selected institution. Emitted by: _all events_.

Optional<String>

The query used to search for institutions. Emitted by: `searchInstitution`.

Optional<String>

Indicates if the current Link session is an update mode session. Emitted by: `OPEN`.

nullable, string

The reason this institution was matched. This will be either `returning_user` or `routing_number` if emitted by: `MATCHED_SELECT_INSTITUTION`. Otherwise, this will be `SAVED_INSTITUTION` or `AUTO_SELECT_SAVED_INSTITUTION` if emitted by: `SELECT_INSTITUTION`.

String

The `link_session_id` is a unique identifier for a single session of Link. It's always available and will stay constant throughout the flow. Emitted by: _all events_.

Optional<MFAType>

If set, the user has encountered one of the following MFA types: `code`, `device`, `questions`, `selections`. Emitted by: `submitMFA` and `transitionView` when `viewName` is `mfa`

Optional<String>

The request ID for the last request made by Link. This can be shared with Plaid Support to expedite investigation. Emitted by: _all events_.

Optional<String>

The routing number submitted by user at the micro-deposits routing number pane. Emitted by `SUBMIT_ROUTING_NUMBER`.

Optional<String>

The Auth Type Select flow type selected by the user. Possible values are `flow_type_manual` or `flow_type_instant`. Emitted by: `SELECT_AUTH_TYPE`.

Date

An ISO 8601 representation of when the event occurred. For example `2017-09-14T14:42:19.350Z`. Emitted by: _all events_.

Optional<ViewName>

The name of the view that is being transitioned to. Emitted by: `transitionView`.

The view showing Terms of Service in the identity verification flow.

The user has connected their account.

We ask the user to consent to the privacy policy.

Asking the user for their account credentials.

The view requesting Documentary Verification in the identity verification flow (configured via "Fallback Settings" in the "Rulesets" section of the template editor).

An error has occurred.

Confirming if the user wishes to close Link.

The user has authorized an instant micro-deposit to be sent to their account over the RTP or FedNow network with a 3-letter code to verify their account.

The view representing the "know your customer" step in the identity verification flow.

Link is making a request to our servers.

The user is asked by the institution for additional MFA authentication.

The user is asked to insert their account and routing numbers.

The user goes through the Same-Day Micro-deposits flow with Reroute to Credentials.

The user is informed they will authenticate with the financial institution via OAuth.

The user is asked to review their profile data in the Layer flow.

The user was presented with a Google reCAPTCHA to verify they are human.

The risk check step in the identity verification flow (configured via "Risk Rules" in the "Rulesets" section of the template editor).

The user has authorized a same day micro-deposit to be sent to their account over the ACH network with a 3-letter code to verify their account.

The watchlist screening step in the identity verification flow.

We ask the user to choose an account.

The user is asked to choose whether to Link instantly or manually (i.e., with micro-deposits).

The user is asked to select a brand, e.g. Bank of America. The brand selection interface occurs before the institution select pane and is only provided for large financial institutions with multiple online banking portals.

We ask the user to choose their institution.

The user is asked to select their saved accounts and/or new accounts for linking in the Link Remember Me flow.

The user is asked to pick a saved institution or link a new one in the Link Remember Me flow.

The view in the identity verification flow which uses the camera to confirm there is a real user that matches their ID documents.

The user is asked for their phone number in the Link Remember Me flow.

The user is asked to upload documents (for Income verification).

The user is asked to verify their phone OTP in the Link Remember Me flow.

The SMS verification step in the identity verification flow.

The view has not been defined in the current version of the SDK. The unknown case has an associated value carrying the original view name as sent by the Plaid API.

RawJSONMetadata (String)

Unprocessed metadata, formatted as JSON, sent from Plaid API.

```swift
linkConfiguration.onEvent = { linkEvent in
  // Optionally handle linkEvent data according to your application's needs
}

```

```objectivec
linkConfiguration.onEvent = ^(PLKLinkEvent * linkEvent) {
  // Optionally handle linkEvent data according to your application's needs
};

```

\=\*=\*=\*=

#### submit() 

The `submit` function is currently only used in the Layer product. It allows the client application to submit additional user-collected data to the Link flow (e.g. a user phone number).

**Properties**

object

Data to submit during a Link session.

String

The end user's phone number.

String

The end user's date of birth. To be provided in the format "yyyy-mm-dd".

```swift
// Create a model that conforms to the SubmissionData interface
struct PlaidSubmitData: SubmissionData {
    var phoneNumber: String?
}

let data = PlaidSubmitData(phoneNumber: "14155550015")

self.handler.submit(data)

```

```objectivec
// The `submit()` API is Swift-only. The underlying `SubmissionData`
// protocol is not exposed to Objective-C, so call `submit(_:)` from a
// Swift helper in your project.

```

#### Next steps 

Once you've gotten Link working, see [Link best practices](https://plaid.com/docs/link/best-practices/index.html.md) for recommendations on further improving the Link flow.