Plaid logo
Docs
ALL DOCS

Link

  • Overview
Libraries
  • Web
  • iOS
  • Android
  • React Native
  • Webview
Core Link flows
  • OAuth guide
  • Remember Me
  • Update mode
  • Preventing duplicate Items
  • Data Transparency Messaging migration
  • Link Token migration guide
  • Legacy public key integrations
Optimizing Link
  • Optimizing Link conversion
  • Measuring Link conversion
  • Pre-Link messaging
  • Customizing Link
  • Choosing when to initialize products
  • Embedded institution search
  • Returning user experience
  • Modular Link (UK/EU only)
Errors and troubleshooting
  • Troubleshooting
  • Handling an invalid Link Token
  • Institution status in Link
Plaid logo
Docs
Close search modal
Ask Bill!
Ask Bill!
Hi! I'm Bill! You can ask me all about the Plaid API. Try asking questions like:
    Note: Bill isn't perfect. He's just a robot platypus that reads our docs for fun. You should treat his answers with the same healthy skepticism you might treat any other answer on the internet. This chat may be logged for quality and training purposes. Please don't send Bill any PII -- he's scared of intimacy. All chats with Bill are subject to Plaid's Privacy Policy.
    Plaid.com
    Log in
    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.

    • iOS Video Tutorial: OAuth section
    • OAuth overview and guide for web
    • OAuth video guide for Android

    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, which includes several of the largest banks in the US. OAuth setup can be skipped only if your Plaid integration is limited to products that do not connect to financial institutions (Enrich, Identity Verification, Monitor, and Document Income).

    OAuth is an industry-standard framework for authorization. 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 authorize data sharing 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

    OAuth is supported on all platforms on which Link is supported.

    Beginning January 1, 2024, Chase will no longer support in-process webview traffic via OAuth. The process described in this guide for webview integrations will walk you through creating compliant, out-of-process webview integrations. To learn more about how to convert existing in-process webview integrations, see the in-process webview deprecation notice.

    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 a full list of institutions, call /institutions/get endpoint with your desired country_codes and the oauth option set to true. Note that for an institution where a migration to OAuth is in progress, some Items may use OAuth, while other Items at the same institution may not.

    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.

    If you later need to update your company information or application display information, you can do so at any time via the Dashboard. If your company's name changes, in addition to updating the Dashboard, you will also need to contact your Account Manager in order for the change to be reflected in the OAuth flows for certain institutions, such as Charles Schwab and Capital One. If you do not have an Account Manager, you can contact support.

    • 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 or contact support 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 it may take some time for Plaid to review, it is recommended that you submit this questionnaire as early as possible in the integration process. If your Plaid integration process is otherwise complete but your security questionnaire has not yet been approved, contact your account manager or submit a Support ticket.

    Implementing OAuth support

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

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

    Additional required steps for mobile implementations
    1. Create and register a redirect URI

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

    3. (Mobile web and webview integrations only) Support sessions launched in embedded browsers by reinitializing Link at your redirect URI

    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.html to the allowlist permits https://oauth1.example.com/oauth.html, https://oauth2.example.com/oauth.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.html is not a valid subdomain wildcard. Redirect URIs do not support hash routing, so your URI cannot contain a '#' symbol.

    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 & mobile web

    OAuth flows will function properly on web even if you don't set up a redirect URI. Desktop web and mobile web integrations will always try to open the OAuth bank's website in a new pop-up window if possible (or in a new tab on mobile web), regardless of whether a redirect_uri is provided. However, not providing a redirect URI will prevent mobile web users from using your integration through a webview browser (a browser launched via Mail, Facebook, Google Maps, etc.) because those browsers often do not support pop-ups. To provide the best experience for end users on mobile web, always specify a redirect URI and reinitialize Link.
    Setting a redirect_uri is still required for Link web SDK integrations within a mobile application (e.g within a webview) because those integrations still use the redirect OAuth flow.

    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.1 of the React Native SDK (released January 2023) by January 1, 2024.

    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
    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 required, but recommended in order to maximize Link conversion
    WebviewYes
    iOS SDKNo
    React Native (iOS)No
    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.

    Desktop and mobile web sessions do not require Link reinitialization by default.

    However, not supporting Link reinitialization will prevent mobile web users from using your integration through a webview (an embedded browser launched via Mail, Facebook, Google Maps, etc.). For these sessions, 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
    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 // pass in the received redirect URI, which contains an OAuth state ID parameter that is required to
    20 // re-initialize Link
    21 receivedRedirectUri: window.location.href,
    22 onSuccess,
    23 onExit,
    24 };
    25
    26 const { open, ready, error } = usePlaidLink(config);
    27
    28 // automatically reinitialize Link
    29 useEffect(() => {
    30 if (ready) {
    31 open();
    32 }
    33 }, [ready, open]);
    34
    35 return <></>;
    36};
    37
    38export default OAuthLink;
    1<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
    2 <script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>
    3 <script>
    4 (function ($) {
    5 var linkToken = localStorage.getItem("link_token");
    6 var handler = Plaid.create({
    7 token: linkToken,
    8 // pass in the received redirect URI, which contains an OAuth state ID parameter that is required to
    9 // re-initialize Link
    10 receivedRedirectUri: window.location.href,
    11 onSuccess: function (public_token) {
    12 $.post(
    13 "/api/set_access_token",
    14 { public_token: public_token },
    15 function (data) {
    16 location.href = "https://example.com";
    17 }
    18 );
    19 },
    20 });
    21 handler.open();
    22 })(jQuery);
    23 </script>

    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.

    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 January 1, 2024, 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 to support certain 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.

    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. Note that any unsafe ASCII characters in the receivedRedirectUri in the webview query string must be URL-encoded; for improved readability, the example below is shown prior to URL encoding.

    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 January 1, 2024, 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

    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 January 1, 2024.

    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
    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.

    App-to-App behavior can be tested in the Sandbox environment. If App-to-App does not function as intended, 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.

    React Native on iOS

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

    An example React Native client implementation for OAuth on iOS can be found in the Tiny Quickstart.

    React Native on iOS uses universal links for OAuth. You will need to create and register a redirect URI and configure your Link token with your redirect URI in order for OAuth to work correctly.

    Android SDK and Android on React Native

    Example code for implementing OAuth on Android can be found on GitHub in the Android SDK. An example React Native client implementation for OAuth on Android can be found in the Tiny Quickstart.

    When using the Android SDK or Android on React Native, 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
    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 in 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 select any bank that supports OAuth (this includes institutions like Chase, U.S. Bank, Wells Fargo, and others) or use the Platypus OAuth Bank (ins_127287). If you are in Europe, you can select Flexible Platypus Open Banking (ins_117181).

    These institutions will 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.

    The Platypus OAuth flow includes two optional "consent" checkboxes that reflect what a user might need to select in order to opt in to Auth and Identity. However, these checkboxes are not functional -- your application will receive the proper Auth and Identity data, even if you don't select those boxes during testing.

    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). To test app-to-app in Sandbox, use First Platypus Bank as the institution; see App-to-App authentication for more details.
    • Without the OAuth institution app installed
    • In update mode, by using /sandbox/item/reset_login in the Sandbox environment

    All environments, including Sandbox, use the pop-up flow on desktop and mobile web, unless the page is accessed through a mobile webview. To test the redirect flow, you can use your browser's developer tools to simulate running your application in a webview browser, such as Chrome WebView. On Chrome, for example, select the "Toggle Device Toolbar" option from within Chrome's Developer Tools and create a new virtual device configuration with a WebView user agent.

    1Mozilla/5.0 (Linux; Android 5.1.1; Nexus 5 Build/LMY48B; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.65 Mobile Safari/537.36

    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 a more 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 no longer work, and you will get an R04 ACH return code when attempting to use them. For more details on how to avoid ACH returns due to permission revocation, see Tokenized account numbers.

    Update mode cannot be used to remove accounts or permissions from a Chase Item. If your end user wishes to revoke or limit Plaid's access to a Chase account, they must do so via the Chase Security Center within the Chase online banking portal. This occurs even across Items; if a Chase Item is deleted and a new Item is created for your app using the same credentials, the previously selected permissions will persist to the new Item.

    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

    When calling /accounts/balance/get for a Capital One non-depository account, such as a credit card or loan account, 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 PRODUCTS_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:

    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:

    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

    Link does not 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.

    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 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.

    A user may also 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 a user revokes access to an Item or an account, we recommend giving them the opportunity to either verify that they intended to remove it or to indicate that the revocation was unintentional. If the user did not mean to revoke access, they can re-authorize access by going through the standard update mode flow. If the user verifies that their action was intentional or does not respond after a few days, delete the associated data, and, in the case of a removed Item, use /item/remove to delete the Item altogether.

    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.

    Before handing the user off to the institution's OAuth flow, Plaid will provide guidance within Link recommending which permissions the user needs to grant based on which products you have initialized Link with. In Production and Development, this guidance will be tailored to use the same wording that the institution's OAuth flow uses. This guidance will appear both on initial link and during the update mode flow. For more details on the exact appearance and messaging used, see the OAuth Guide within the Dashboard.

    If an end user chooses not to share data that is required by your Link token's products or required_if_supported_products configuration, or does not share access to any accounts, Link will show an error, and they will be prompted 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 you do not have the product-specific OAuth permissions required to use a specific endpoint with an Item, you will receive an ACCESS_NOT_GRANTED error. If you are missing permissions for an account on the Item, you may receive a product-specific error indicating that a compatible account could not be found, such as NO_AUTH_ACCOUNTS, NO_INVESTMENT_ACCOUNTS, or NO_LIABILITY_ACCOUNTS.

    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 First Platypus Bank - OAuth App2App (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. On iOS, you must use the Plaid Link SDK version 5.1.0 or later to test App-to-App in Sandbox.

    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.

    QR Code authentication example

    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
    Discord
    Discord