Plaid logo
Docs
ALL DOCS

Link

  • Overview
Libraries
  • Web
  • iOS
  • Android
  • React Native
  • Webview
Core Link flows
  • OAuth guide
  • Update mode
  • Preventing duplicate Items
  • Data Transparency Messaging migration
  • Account Select v2 migration guide
  • Link Token migration guide
  • Legacy public key integrations
Optimizing Link
  • Optimizing Link conversion
  • Measuring Link conversion
  • Pre-Link messaging
  • Customizing Link
  • Choosing when to inititalize products
  • Returning user experience
  • Modular Link (UK/EU only)
Errors and troubleshooting
  • Troubleshooting
  • Handling an invalid Link Token
  • Institution status in Link
Plaid logo
Docs
Plaid.com
Get API keys
Open nav

OAuth Guide

Configure Link to connect to institutions via OAuth

Prefer to learn by watching? Video guides are available for this topic.

  • OAuth overview and guide for web
  • OAuth video guide for Android
  • OAuth video guide for iOS

Introduction to OAuth

OAuth support is required in all Plaid integrations that connect to financial institutions. Without OAuth support, your end users will not be able to connect accounts from institutions that require OAuth. OAuth setup can be skipped only if your Plaid integration is limited to products that do not connect to financial institutions (Identity Verification, Monitor, Document Income, and Wallet Onboard).

OAuth is an industry-standard protocol for authenticating and permissioning data to third parties. With OAuth, end users can grant third parties access to their data without sharing their credentials directly with the third party.

Typically, end users authenticate and permission data directly within Plaid Link when connecting their financial accounts to third party applications. With OAuth, however, end users temporarily leave Link to authenticate and permission data using the institution's website or mobile app instead. Afterward, they're redirected back to Link to complete the Link flow and return control to the third party application.

A typical OAuth flow
A typical OAuth flow with Plaid Link

In addition, Plaid integrations with OAuth have several benefits over the traditional, non-OAuth experience in Link, such as:

  • Familiar and trustworthy experiences With OAuth, end users authenticate via the bank's website or mobile app, a familiar experience that can help with conversion.

  • Streamlined login experiences Some OAuth-enabled institutions (e.g., Chase) provide an "App-to-App" experience for end users if the end user has the institution's mobile app installed on their device. App-to-App can provide alternative authentication methods to end users (e.g., Touch ID or Face ID) that can help simplify and accelerate the authentication process.

  • Greater connection uptime You can generally expect greater connection uptime with OAuth-enabled institutions, which means fewer connection errors for end users when using Plaid Link.

  • Longer-lived connections Items at OAuth-enabled institutions generally remain connected longer. This typically results in fewer re-authentication errors (e.g., ITEM_LOGIN_REQUIRED).

  • Improved MFA (multi/second-factor) support OAuth-enabled institutions can support end user accounts that may be currently unsupported due to the end user's MFA settings.

OAuth support and compatibility

Plaid supports the OAuth2 protocol. For a list of the largest Plaid-supported institutions that use OAuth in the US, consult the OAuth institutions page. For European institutions, call /institutions/get endpoint with your desired country_codes and the oauth option set to true. The response for all institutions includes an oauth field, which indicates whether or not Plaid uses OAuth to authenticate users for that institution. Note that this endpoint should not be used to check OAuth compatibility for non-European institutions, as oauth will only be set to true for institutions that have fully completed the migration to OAuth and do not have any active Items on non-OAuth connections.

All OAuth flows are compatible with advanced Link flows such as Returning User Experience, Instant Match, and micro-deposit based verification. Implementing OAuth support will not impact existing non-OAuth flows, and you can safely add support for OAuth institutions at any time without disrupting support for non-OAuth institutions.

Prerequisites for adding OAuth support

Ensure you have implemented Link tokens

OAuth requires the use of Link tokens. If you are using a legacy implementation with public keys rather than Link tokens, see the Link token migration guide.

Request Production access from Plaid

Production access is a prerequisite for supporting OAuth. Plaid will contact you once your account has been enabled for Production.

In the US and Canada, OAuth requires Production access; you cannot connect to US OAuth institutions in the Development environment without having received both OAuth approval and Production approval. You can, however, test OAuth in the Sandbox environment, using Sandbox-only institutions, without needing Production approval.

Complete the registration requirements

Before implementing support for OAuth institutions, be sure to complete the registration requirements in the Plaid Dashboard.

  • Application display information – This is public information that end users of your application will see when managing connections between your application and their bank accounts, including during OAuth flows. This information helps end users understand what your application is and why it is requesting access, which can improve conversion. In addition, some US institutions require your profile to be completed and will not allow apps with an empty profile to access their OAuth implementations.

  • Company information – Information about your company. This information is not shared with end users of your application and is only accessible to Plaid, members of your team, and financial institutions you register with.

  • Plaid Master Services Agreement – (US/CA only) Your latest contract with Plaid. If this is marked as incomplete, please reach out to your account manager for an updated version.

  • Plaid security questionnaire – (US/CA only) You must complete a questionnaire about your company's risk and security practices before accessing certain bank APIs.

Because OAuth support requires client-side changes, we recommend implementing OAuth support even before your account has been enabled for OAuth, especially if integrating with mobile SDKs, in order to allow sufficient time for app approval and distribution.

Implementing OAuth support

Required steps
  1. Create and register a redirect URI

  2. Generate a Link token and configure it with your redirect URI

  3. Reinitialize Link at your redirect URI

  4. Wait for OAuth approval from Plaid, which can be tracked on the OAuth institution page.

  5. Understand institution-specific behaviors and, if necessary, update your app to support them.

Recommended, optional steps
  1. Handle Link OAuth events

  2. Listen for consent expiration webhooks

  3. Manage consent revocation

  4. (US/CA only) Enable OAuth and migrate users

  5. (Europe only) Enable QR Code authentication

Create and register a redirect URI

After successfully completing the OAuth flow via their bank's website or app, you'll need to redirect the end user back to your application. This is accomplished with a redirect URI that you'll need to set up and configure accordingly depending on your client platform.

Constructing valid redirect URIs

Redirect URIs must use HTTPS. The only exception is on Sandbox, where, for testing purposes, redirect URIs pointing to localhost are allowed over HTTP. Custom URI schemes are not supported in any environment. Subdomain wildcards are supported using a * character. For example, adding https://*.example.com/oauth-page.html to the allowlist permits https://oauth1.example.com/oauth-page.html, https://oauth2.example.com/oauth-page.html, etc. Subdomain wildcards can only be used for domains that you control and are not allowed for domains on the Public Suffix List. For example, https://*.co.uk/oauth-page.html is not a valid subdomain wildcard.

Note: Do not enter a wildcard (*) when specifying a redirect_uri in the call to /link/token/create. Wildcards are reserved for the allowlist on the dashboard only.

Desktop web, mobile web, React, or Webview

For desktop web, mobile web, or React, the redirect URI is typically the address of a blank web page you'll need to create and host. This web page will be used to allow the end user to resume and complete the Link flow after completing the OAuth flow on their bank's website or app. https://example.com/oauth-page.html is an example of a typical redirect URI. After creating your redirect URI, add it to the Allowed redirect URIs.

Redirect URIs and desktop web

OAuth flows will function properly on web even if you don't set up a redirect URI. Desktop web integrations will always open the OAuth bank's website in a new pop-up window, regardless of whether a redirect_uri is provided.
However, for users on mobile web, if the end user has the bank's app installed, and the institution supports App-to-App, not providing a redirect URI will prevent the higher-converting App-to-App OAuth flow from being used and will instead route users to the mobile web flow. To provide the best experience for end users on mobile web, always specify a redirect URI and reinitialize Link.

iOS SDK, React Native (iOS)

To maintain support for Chase OAuth flows, all integrations must upgrade to version 4.1.0 of the Link iOS SDK or version 9.0.0 of the React Native SDK (released January 2023) by June 30, 2023.

For iOS SDK or React Native (iOS), the redirect URI is typically the address of a blank web page you'll need to create and host. You'll need to configure an Apple App Association File to associate your redirect URI with your application. To enable App-to-App authentication flows, you'll need to register the redirect URI as an app link. Custom URI schemes are not supported; a proper universal link must be used.

Android SDK, React Native (Android)

Register your Android package by adding the Android package name(s) to the Allowed Android package names list. Plaid will automatically create your redirect URI and its contents based on your package name. When specifying a redirect URI in the following steps, you will use android_package_name.

Configure your Link token with your redirect URI

OAuth support requires use of Link tokens. The legacy client-side settings oauthRedirectUri and oauthNonce are ignored and will not be read. If you are still using a legacy public key, see the Link token migration guide.

You'll need to specify your redirect URI via the redirect_uri field when generating a Link token with /link/token/create (on Android, use the android_package_name parameter to provide your Android package name instead). Use this Link token to initialize Link.

If you're using Link in update mode, ensure you specify your redirect URI via the redirect_uri field (on Android, use the android_package_name parameter to provide your package name instead).

Do not use query parameters when specifying the redirect_uri. Make sure to specify the user.client_user_id.

Select group for content switcher
Select Language
Copy
1const request = {
2 user: {
3 // This should correspond to a unique id for the current user.
4 client_user_id: 'user-id',
5 },
6 client_name: 'Plaid Test App',
7 products: [Products.Transactions],
8 country_codes: [CountryCode.Us],
9 language: 'en',
10 webhook: 'https://sample-web-hook.com',
11 redirect_uri: 'https://example.com/callback',
12};
13
14try {
15 const createTokenResponse = await client.linkTokenCreate(request);
16 const linkToken = response.data.link_token;
17} catch (error) {
18 // handle error
19}
Using OAuth within an iFrame

Launching Link from within an iFrame is not recommended. Link conversion for OAuth institutions is typically up to 15 percentage points higher when using Plaid's SDKs than when using iFrames. If Link is launched from within an iFrame, you'll be unable to maintain user state. Page rendering, sizing, and data exchange may also be suboptimal.

Reinitializing Link

After completing the OAuth flow, the end user will be redirected to your redirect URI (e.g., https://example.com/oauth-page.html). This is where they'll resume and complete the Link flow and return to your application. To do this, you'll need to reinitialize Link at your redirect URI.

Depending on your client platform, Link may require additional configuration to work with OAuth. Detailed instructions for each platform are provided below.

Client platformLink reinitialization required?
Desktop webNo
Mobile webNot strictly required, but strongly recommended to maximize conversion
WebviewYes
iOS SDKYes
React Native (iOS)Yes
Android SDK (version 3.2.3 or later required)No, but app package registration required
React Native (Android)No, but app package registration required
Desktop web, mobile web, or React

A reference implementation for OAuth in React can be found in the Plaid React GitHub. If you are looking for a demonstration of a real-life app that incorporates the implementation of OAuth in React see Plaid Pattern, a Node-based example app.

For desktop web, mobile web, or React, you'll need to launch Link twice, once before the OAuth redirect (i.e., the first Link initialization) and once after the OAuth redirect (i.e., Link reinitialization). The Link reinitialization should occur at your redirect URI.

When reinitializing Link, configure it using the same Link token you used when initializing Link the first time. It is up to you to determine the best way to provide the correct link_token upon redirect. As an example, the code sample below demonstrates the use of a browser's local storage to retrieve the Link token from the first Link initialization.

Select group for content switcher
Copy
1import React, { useEffect } from 'react';
2import { usePlaidLink } from 'react-plaid-link';
3
4const OAuthLink = () => {
5 // The Link token from the first Link initialization
6 const linkToken = localStorage.getItem('link_token');
7
8 const onSuccess = React.useCallback((public_token: string) => {
9 // send public_token to server, retrieve access_token and item_id
10 // return to "https://example.com" upon completion
11 });
12
13 const onExit = (err, metadata) => {
14 // handle error...
15 };
16
17 const config: Parameters<typeof usePlaidLink>[0] = {
18 token: linkToken!,
19 receivedRedirectUri: window.location.href, //the redirect URI with an OAuth state ID parameter
20 onSuccess,
21 onExit,
22 };
23
24 const { open, ready, error } = usePlaidLink(config);
25
26 // automatically reinitialize Link
27 useEffect(() => {
28 if (ready) {
29 open();
30 }
31 }, [ready, open]);
32
33 return <></>;
34};
35
36export default OAuthLink;

In addition, when reinitializing Link, you should configure it with the receivedRedirectUri field and pass in the full received redirect URI, as demonstrated in the code sample. The received redirect URI is your redirect URI appended with an OAuth state ID parameter. The OAuth state ID parameter will allow you to persist user state when reinitializing Link, allowing the end user to resume the Link flow where they left off. No extra configuration or setup is needed to generate the received redirect URI. The received redirect URI is programmatically generated for you by Plaid after the end user authenticates on their bank's website or mobile app. You can retrieve it using window.location.href.

The received redirect URI must not contain any extra query parameters or fragments other than what is provided upon redirect. The standard Link callback onSuccess will be triggered as usual once the user completes the Link flow.

Copy
1https://example.com/oauth-page.html?oauth_state_id=9d5feadd-a873-43eb-97ba-422f35ce849b`
Optional methods for retrieving the initial Link token

If Link is reinitialized in the same browser session as the first Link initialization, you can store the Link token in a cookie or local storage in the browser for easy access when reinitializing Link. For example, the Plaid Quickstart uses localStorage.setItem to store the token.

If Link is reinitialized in a different browser session than the first Link initialization, you can store a mapping of the Link token associated with the user (server-side). Upon opening the second browser session, authenticate the user, fetch the corresponding Link token from the server, and use it to reinitialize Link.

Webview

Beginning June 30, 2023, all webview-based integrations will need to extend the webview handler for redirects in order to support Chase OAuth. This can be accomplished with code samples for iOS and Android For more details, see Extending webview instances for specific institutions.

For webview, you'll need to launch Link twice, once before the OAuth redirect (i.e., the first Link initialization) and once after the OAuth redirect (i.e., Link reinitialization). The Link reinitialization should occur at your redirect URI.

For the initial Link instance, first generate a Link token as described in Configure your Link token with your redirect URI, then set Link's token parameter to this Link token. After the end user successfully completes the OAuth flow via their bank's website or app, they'll be redirected to your redirect URI, where you'll reinitialize Link.

Copy
1https://cdn.plaid.com/link/v2/stable/link.html? isWebview=true
2&token=GENERATED_LINK_TOKEN

When reinitializing Link, use the same Link token you generated when you first initialized Link. It is up to you to determine the best way to provide the correct link_token upon redirect.

In addition, when reinitializing Link, you should configure it with the receivedRedirectUri field. The received redirect URI is your redirect URI appended with an OAuth state ID parameter. The OAuth state ID parameter will allow you to persist user state when reinitializing Link, allowing the end user to resume the Link flow where they left off. No extra configuration or setup is needed to generate the received redirect URI. The received redirect URI is programmatically generated after the end user authenticates on their bank's website or mobile app. The received redirect URI must not contain any extra query parameters or fragments other than what is provided upon redirect.

Copy
1https://cdn.plaid.com/link/v2/stable/link.html? isWebview=true
2&token=SAME_GENERATED_LINK_TOKEN&receivedRedirectUri=https://example.com/oauth-page?oauth_state_id=9d5feadd-a873-43eb-97ba-422f35ce849b
Extending webview instances to support certain institutions

Some institutions require further modifications to work with mobile webviews. This applies to USAA on Android and Chase app-to-app on Android. Beginning on June 30, 2023, this also applies to all Chase webview integrations. For these institutions, you'll need to extend your Webview instance to override the handler for redirects. An example function for Android and an example function for iOS can be found within Plaid's Link examples on GitHub and can be copied for use with your app.

On Android, you will also need to support Android App links to have a valid working redirect_uri to provide to /link/token/create. This requires creating a `./well_known/assetlinks.json and an IntentFilter on the Android app.

iOS

A complete client implementation of OAuth support for both Swift and Objective-C can be found in the Plaid Link for iOS sample app, within the AppDelegate+OAuthSupport and ViewController components.

To maintain support for Chase OAuth flows, all integrations must upgrade to version 4.1.0 of the Link iOS SDK (released January 2023) by June 30, 2023.

For the initial Link instance, first generate a Link token as described in Configure your Link token with your redirect URI. Your redirect_uri must also be added to the Plaid dashboard and should be configured as a universal link (not a custom URI) using an Apple App Association File.

Select Language
Copy
1// With custom configuration
2let linkToken = "<#GENERATED_LINK_TOKEN#>"
3let onSuccess: (LinkSuccess) -> Void = { (success) in
4 // Read success.publicToken here
5 // Log/handle success.metadata here
6}
7let linkConfiguration = LinkTokenConfiguration(linkToken: linkToken, onSuccess: onSuccess)
8let handlerResult = Plaid.create(linkConfiguration)
9
10switch handlerResult {
11case .success(let handler):
12 self.handler = handler
13 handler.open(presentUsing: .viewController(self))
14case .failure(let error):
15 // Log and handle the error here.
16}

OAuth on iOS devices can occur fully within the integrating application (In-App OAuth), or it can include a transition from your application to the bank's app (App-to-App OAuth). App-to-App OAuth is initiated by the bank itself and is not controlled by the iOS SDK. In order to ensure your users can return to your application, you must support App-to-App OAuth.

App-to-App OAuth requirements

During App-to-App OAuth, the end user is directed from your application to the bank's app to authenticate. To return the end user back to your application after they authenticate, your redirect URI must be a universal link. Once the user returns to your app, UIKit will invoke a method within your application and provide the redirect URI that triggered this return to the app.

The iOS SDK requires this redirect URI to be passed to its continue(from:) API in order to continue OAuth. Without this call, the SDK will not know whether the OAuth flow has completed and will therefore not update the UI. Add the following code to either your application delegate's func application(_:, continue:, restorationHandler:), or to your scene delegate's func scene(_:, continue:) function:

Select Language
Copy
1if userActivity.activityType == NSUserActivityTypeBrowsingWeb, let redirectUri = userActivity.webpageURL {
2 // NOTE: Your handler must be accessible from your application delegate or scene delegate.
3 self.handler.continue(from: redirectUri)
4}

App-to-App behavior can be tested in the Sandbox environment. If App-to-App does not function as intended, verify that the continue(from:) API is being called by setting a breakpoint on the function call. If the breakpoint is not hit, validate that the redirect URI used to configure Link is a valid universal link and that your application has the associated-domains entitlement for that URI.

When contacting Plaid Support for help with App-to-App OAuth issues, you may be asked to provide the value you pass to the continue(from:) API. This can be found by setting a breakpoint as described above, and logging the value of the parameter to LLDB (e.g. $ po redirectUri.absoluteString()).

React Native on iOS

To maintain support for Chase OAuth flows, all integrations must upgrade to version 9.0.0 of the React Native SDK (released January 2023) by June 30, 2023.

React Native on iOS uses universal links for OAuth, and the following code is required in the AppDelegate in the native iOS code:

Copy
1- (BOOL)application:(UIApplication *)application
2continueUserActivity:(NSUserActivity *)userActivity
3 restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
4{
5 return [RCTLinkingManager application:application
6 continueUserActivity:userActivity
7 restorationHandler:restorationHandler];
8}

This code block informs the React Native Linking library when the application is opened through a universal link. The React Native Plaid Link SDK will correctly continue OAuth when the application is opened through the registered universal link.

Handling universal links within React Native

The PlaidLink component handles Universal Links by default. For integrations that use PlaidLink.openLink, Universal Links will not be handled by default. The useDeepLinkRedirector hook must be invoked by the component that calls PlaidLink.openLink.

Android SDK and Android on React Native

You won't need to reinitialize Link at a redirect URI when using Android SDK or Android on React Native, but you must generate a Link token by calling /link/token/create and passing in an android_package_name. Your package name (e.g., com.example.testapp) must also be added to the Plaid dashboard. Do not pass a redirect_uri into the /link/token/create call. Proceed to initialize Link with the generated token.

Select group for content switcher
Copy
1String clientUserId = "user-id";
2
3LinkTokenCreateRequestUser user = new LinkTokenCreateRequestUser()
4 .clientUserId(clientUserId)
5 .legalName("legal name")
6 .phoneNumber("4155558888")
7 .emailAddress("email@address.com");
8
9LinkTokenCreateRequest request = new LinkTokenCreateRequest()
10 .user(user)
11 .clientName("Plaid Test App")
12 .products(Arrays.asList(Products.AUTH))
13 .countryCodes(Arrays.asList(CountryCode.US))
14 .language("en")
15 .webhook("https://example.com/webhook")
16 .linkCustomizationName("default")
17 .androidPackageName("com.plaid.example")
18
19Response<LinkTokenCreateResponse> response = client()
20 .linkTokenCreate(request)
21 .execute();
22
23String linkToken = response.body().getLinkToken();

Testing OAuth

You can test OAuth on Sandbox even if Plaid has not yet enabled OAuth flows for your account. To test out the OAuth flow in the Sandbox environment, you can use Platypus OAuth Bank (ins_127287), Platypus OAuth App2App Bank (ins_132241) for testing App2App flows on mobile, or to emulate European flows, Flexible Platypus Open Banking (ins_117181). These dummy institutions direct you to a Plaid sample OAuth flow that is similar to what you would see for a bank’s OAuth flow. When prompted, you can enter anything as credentials (including leaving the input fields blank) to proceed through the sample OAuth flow. Note that institution-specific OAuth flows cannot be tested in Sandbox; OAuth panes for Platypus institutions will be shown instead.

To ensure your OAuth integration works across all platforms, test it in the following scenarios before deployment:

  • On each client platform that is available to your users (e.g. desktop, iOS app, iOS mobile web, Android app, Android mobile web)
  • With the OAuth institution app installed, for institutions that support app-to-app authentication (i.e. Chase)
  • Without the OAuth institution app installed
  • In update mode, by using /sandbox/item/reset_login in the Sandbox environment

In September 2022, Plaid changed the OAuth flow on Sandbox so that Sandbox now works exactly the same as Production; Sandbox will now use the pop-up flow on desktop and the redirect flow on mobile. To test the redirect flow in Sandbox, you can use your browser's developer tools to simulate running your application on a mobile device. On Chrome, for example, select the "Toggle Device Toolbar" option from within Chrome's Developer Tools.

Troubleshooting common OAuth problems

For guides to troubleshooting common OAuth issues, see Link troubleshooting.

Enabling OAuth connections and migrating users

Your integration will automatically convert to using OAuth connections for a given institution on the date that Plaid has indicated to you. You may also have the option to migrate to OAuth earlier; if this option is available, a button to enable OAuth for the institution will appear on the OAuth institution page.

Your existing Items with the institution being migrated will automatically be moved into the ITEM_LOGIN_REQUIRED state. This will happen gradually over a migration period (by default, 90 days, but the duration may vary depending on the institution), starting on or shortly after the OAuth enablement date. Completing the update mode flow for these Items will convert them to use OAuth connections. To avoid any disruption in connectivity, you can also prompt your users to complete the update mode flow as soon as you have been enabled for OAuth with their institution.

Institution-specific behaviors

Some institutions have unique behaviors when used with OAuth connections. Note that these behaviors are standard for any connection using these institutions' APIs and not specific to their integration with Plaid.

The behaviors listed below are the ones most likely to require changes to your application's business logic; for an exhaustive list of institution-specific OAuth details, see the "Bank-specific documentation" section of the OAuth integration PDF guide.

Chase

When used with Auth, Chase will return "tokenized" routing and account numbers, which can be used for ACH transactions but are not the user's actual account and routing numbers. The mask, however, will continue to be based on the actual account number. For this reason, when displaying account numbers from Chase to the user to help them identify their account in your UI, always use the mask rather than displaying the account number. If a user revokes their permissions to your app, the tokenized numbers will continue to work for ACH deposits, but not withdrawals. For more details, see the API reference.

Existing Chase OAuth Items will be invalidated when a new public token is created using the same credentials. For more details, see Preventing duplicate Items.

Capital One

Capital One does not support real-time on-demand data updates. When calling /accounts/balance/get for Capital One, you will need to specify how fresh you require the balance data to be. If balance data meeting your requirements is not available, the call will fail and you will not be billed. For more details, see the API Reference. For similar reasons, /transactions/refresh will result in a PRODUCT_NOT_SUPPORTED error if used on a Capital One Item.

Charles Schwab

Existing Schwab OAuth Items will be invalidated when a new public token is created using the same credentials. For more details, see Preventing duplicate Items.

Handling Link events

OAuth flows have a different sequence of Link events than non-OAuth flows. If you are using Link events to measure conversion metrics for completing the Link process, you may need to handle these events differently when using OAuth.

In addition, the flow itself may be different if you are initiating OAuth with a redirect URI or displaying the OAuth screen in a separate pop-up window.

The events fired for a non-OAuth flow might look something like this:

Copy
1OPEN (view_name = CONSENT)
2TRANSITION_VIEW view_name = SELECT_INSTITUTION)
3SELECT_INSTITUTION
4TRANSITION_VIEW (view_name = CREDENTIAL)
5SUBMIT_CREDENTIALS
6TRANSITION_VIEW (view_name = LOADING)
7TRANSITION_VIEW (view_name = MFA, mfa_type = code)
8SUBMIT_MFA (mfa_type = code)
9TRANSITION_VIEW (view_name = LOADING)
10TRANSITION_VIEW (view_name = CONNECTED)
11HANDOFF
12onSuccess

The events fired for a typical OAuth flow may look more like the following:

Copy
1OPEN (view_name = CONSENT)
2TRANSITION_VIEW (view_name = SELECT_INSTITUTION)
3SELECT_INSTITUTION
4TRANSITION_VIEW (view_name = OAUTH)
5OPEN_OAUTH
6...
7(The user completes the OAuth flow at their bank)
8...
9TRANSITION_VIEW (view_name = CONNECTED)
10HANDOFF
11onSuccess

Beginning July 2022, Link will no longer issue the SUBMIT_CREDENTIALS event when a user authenticates with an institution that requires OAuth. Link issues the OPEN_OAUTH event when a user chooses to be redirected to the institution’s OAuth portal. It is recommended to track this event instead of SUBMIT_CREDENTIALS.

In most situations, if Plaid encounters an error from the bank's OAuth flow, or if the user chooses to not grant access via their OAuth login attempt, the user will return to your application and Link will fire an EXIT event with a requires_oauth exit status. You may also see an ERROR event, depending on the type of error that Plaid encountered.

Copy
1SELECT_INSTITUTION
2OPEN (view_name = null)
3ERROR (error_code = INTERNAL_SERVER_ERROR)
4TRANSITION_VIEW (view_name = ERROR)
5TRANSITION_VIEW (view_name = EXIT)
6EXIT (exit_status = requires_oauth)

If the user closes the bank's OAuth window without completing the OAuth flow, Link will fire a CLOSE_OAUTH event. This only happens in situations where the OAuth flow appears in a pop-up window.

If the OAuth flow times out while waiting for the user to sign in, Link will fire a FAIL_OAUTH event. This only happens in situations where the OAuth flow appears in a pop-up window.

Once you receive the onSuccess callback from an OAuth flow, the integration steps going forward are the same as for non-OAuth flows.

Refreshing Item consent

Some institutions require users to periodically re-affirm their consent to avoid Item expiration. When using OAuth, end users may need to refresh their access-consent after a certain amount of time, such as one year or three months. This is particularly common in Europe, where access-consent typically expires after 90 days. Expiring access-consent is less common in the US, and consent periods are typically longer. For more details on which US institutions expire access-consent and how frequently, see the "Bank-specific documentation" section (section 8) of the OAuth integration PDF guide.

To determine when a user will need to re-authenticate, make a request to the /item/get endpoint and note the consent_expiration_time field. Plaid will also send a PENDING_EXPIRATION webhook one week before a user’s access-consent is set to expire. In order to continue receiving data for that user without interruption, ensure they re-authenticate via update mode prior to that date. When using Link in update mode, be sure to specify your redirect URI via the redirect_uri field as described in Configure your Link token with your redirect URI.

If consent is not refreshed before the Item expires, the Item will enter the ITEM_LOGIN_REQUIRED error state. Sending the Item through update mode, as described above, will resolve the error.

For a real-life example of handling the PENDING_EXPIRATION webhook and update mode, see handleItemWebhook.js, linkTokens.js and launchLink.tsx. These files illustrate the code for handling of webhooks and update mode for Plaid Link for React for the Node-based Plaid Pattern sample app.

Managing consent revocation

Many institutions that support OAuth provide a means for the end user to revoke consent via their website. If an end user revokes consent, the Item will enter an ITEM_LOGIN_REQUIRED state after approximately 24-48 hours. We recommend giving the user an opportunity to either verify that they intended to remove the Item or to indicate that they did not mean to revoke access. If the user verifies that they meant to remove the Item or does not respond after a few days, delete the Item and associated data. If the user did not mean to revoke access, they can re-authorize access by going through the standard update mode flow.

Institutions that support OAuth may also provide the end user the ability to revoke consent for a single account, without revoking consent for the entire Item. Accounts in this situation are treated the same as accounts that have been closed: no webhook will be fired, you will stop receiving transactions associated with the account, and Plaid will stop returning the account in API responses. Access can be re-authorized via the update mode flow.

When using Link in update mode (for either case described in this section), be sure to specify your redirect URI via the redirect_uri field as described in Configure your Link token with your redirect URI.

Partial consent

OAuth can provide the ability for end users to configure granular permissions on their Items. For example, an end user may allow access to a checking account but not a credit card account behind the same login, or may allow an institution to share only certain account information, such as identity data but not transaction history. If an end user chooses not to share data that is required by your Link token's products configuration, or does not share access to any accounts, the Link attempt will fail. In this case, they will need to restart the Link flow.

Note that if your app calls /link/token/create using an account_filter parameter to limit the account types that can be used with Link, the filter will only be applied after the OAuth flow has been completed and will not affect the permission selection interface within the OAuth flow.

If your app later needs to request access to a product or account that was not originally granted for that Item during Link, you can send the user to the update mode flow to authorize additional permissions. When using Link in update mode, be sure to specify your redirect URI via the redirect_uri field as described in Configure your Link token with your redirect URI.

App-to-App authentication

Some banks (i.e. Chase) support an App-to-App experience if the user is authenticating on their mobile device and has the bank's app installed. Instead of logging in via the bank's site, the bank's app will be launched instead, from which the user will be able to log in (including via TouchID or Face ID) before being redirected back to your app. Support for App-to-App should be automatic once you have implemented support for OAuth on mobile with any of Plaid's mobile SDKs. Note that on iOS, this requires configuring an Apple App Association file to associate your redirect URI with your app, as described under Create and register a redirect URI. If using webviews, App-to-App support is not automatic; for an App-to-App experience, it is strongly recommended to use a Plaid mobile SDK instead.

The full App-to-App flow can be tested in the Sandbox environment. You can test that your universal link works correctly using the Platypus OAuth App2App Bank (ins_132241) test institution. The bank's 'app' for this test institution will be a mobile web browser, but the universal link will function as expected if configured correctly, switching back to your app on handoff.

Chase is currently the only bank that supports App-to-App authentication on Plaid.

QR code authentication

For many European institutions, Plaid supports the ability for an end user to authenticate via their bank's mobile app – even if the user's journey begins in a desktop-based web session – in order to optimize for conversion. After the user selects an institution, they will be presented with the choice to scan a QR code and authenticate in the bank’s mobile app or to continue on desktop. When the user scans the QR code, they will be redirected to the bank’s app (or website, if the user does not have the app installed). After the user completes the OAuth flow, they will be redirected to a Plaid-owned page instructing them to return to their desktop to complete the flow.

To enable QR authentication, contact your Plaid account manager or file a Support ticket. No changes to your Link OAuth implementation are required to enable this flow.

To test out the QR code flow in the Sandbox environment, you can use Flexible Platypus Open Banking (ins_117181). When you launch Link with this institution selected in Sandbox, the QR code authentication flow will be triggered. The Sandbox institution does not direct you to a real bank's mobile app, but allows you to grant, deny, or simulate errors from the placeholder OAuth page instead.

Supported institutions for QR code authentication
Institution nameInstitution ID
Bank of Scotland - Personalins_118274
Bank of Scotland - Businessins_118276
Barclays (UK) - Mobile Banking: Businessins_118512
Barclays (UK) - Mobile Banking: Personalins_118511
Barclays (UK) - Mobile Banking: Wealth Managementins_118513
First Directins_81
Halifaxins_117246
HSBC (UK) - Businessins_118277
HSBC (UK) - Personalins_55
Lloyds Bank - Business and Commercialins_118275
Lloyds Bank - Personalins_61
Monzoins_117243
Nationwide Building Societyins_60
NatWest - Current Accountsins_115643
Revolutins_63
Royal Bank of Scotland - Current Accountsins_115642
Santander (UK) - Personal and Businessins_62
Starlingins_117520
Tesco (UK)ins_118393
TSBins_86
Ulster Bank (UK)ins_117734
Was this helpful?
Developer community
GitHub
GitHub
Stack Overflow
Stack Overflow
YouTube
YouTube
Twitter
Twitter
Discord
Discord