OAuth Guide
Configure Link to connect to institutions via OAuth
Prefer to learn by watching? Video guides are available for this topic.
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, Document Income, and Wallet Onboard).
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.

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 June 30, 2023, 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 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.
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 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
Generate a Link token and configure it with your redirect URI
Wait for OAuth approval from Plaid, which can be tracked on the OAuth institution page.
Understand institution-specific behaviors and, if necessary, update your app to support them.
Recommended, optional steps
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 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
.
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};1314try {15 const createTokenResponse = await client.linkTokenCreate(request);16 const linkToken = response.data.link_token;17} catch (error) {18 // handle error19}
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 platform | Link reinitialization required? |
---|---|
Desktop web | No |
Mobile web | Not required, but recommended in order to maximize Link conversion |
Webview | Yes |
iOS SDK | No |
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.
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.
1import React, { useEffect } from 'react';2import { usePlaidLink } from 'react-plaid-link';34const OAuthLink = () => {5 // The Link token from the first Link initialization6 const linkToken = localStorage.getItem('link_token');78 const onSuccess = React.useCallback((public_token: string) => {9 // send public_token to server, retrieve access_token and item_id10 // return to "https://example.com" upon completion11 });1213 const onExit = (err, metadata) => {14 // handle error...15 };1617 const config: Parameters<typeof usePlaidLink>[0] = {18 token: linkToken!,19 receivedRedirectUri: window.location.href, //the redirect URI with an OAuth state ID parameter20 onSuccess,21 onExit,22 };2324 const { open, ready, error } = usePlaidLink(config);2526 // automatically reinitialize Link27 useEffect(() => {28 if (ready) {29 open();30 }31 }, [ready, open]);3233 return <></>;34};3536export 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.
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 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=true2&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.
1https://cdn.plaid.com/link/v2/stable/link.html? isWebview=true2&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
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.
1// With custom configuration2let linkToken = "<#GENERATED_LINK_TOKEN#>"3let onSuccess: (LinkSuccess) -> Void = { (success) in4 // Read success.publicToken here5 // Log/handle success.metadata here6}7let linkConfiguration = LinkTokenConfiguration(linkToken: linkToken, onSuccess: onSuccess)8let handlerResult = Plaid.create(linkConfiguration)910switch handlerResult {11case .success(let handler):12 self.handler = handler13 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 June 30, 2023.
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.
1String clientUserId = "user-id";23LinkTokenCreateRequestUser user = new LinkTokenCreateRequestUser()4 .clientUserId(clientUserId)5 .legalName("legal name")6 .phoneNumber("4155558888")7 .emailAddress("email@address.com");89LinkTokenCreateRequest 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")1819Response<LinkTokenCreateResponse> response = client()20 .linkTokenCreate(request)21 .execute();2223String 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). For more details on testing app-to-app in Sandbox, see App-to-App authentication.
- Without the OAuth institution app installed
- In update mode, by using
/sandbox/item/reset_login
in the Sandbox environment
All environments, including both 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; U; Android 10; SM-G960F Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/95.0.4638.50 Mobile Safari/537.36 OPR/60.0.2254.59405
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:
1OPEN (view_name = CONSENT)2TRANSITION_VIEW view_name = SELECT_INSTITUTION)3SELECT_INSTITUTION4TRANSITION_VIEW (view_name = CREDENTIAL)5SUBMIT_CREDENTIALS6TRANSITION_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)11HANDOFF12onSuccess
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_INSTITUTION4TRANSITION_VIEW (view_name = OAUTH)5OPEN_OAUTH6...7(The user completes the OAuth flow at their bank)8...9TRANSITION_VIEW (view_name = CONNECTED)10HANDOFF11onSuccess
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_INSTITUTION2OPEN (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.
If an Item is enabled for either OAuth or Account Select v2, 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. 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 name | Institution ID |
---|---|
Bank of Scotland - Personal | ins_118274 |
Bank of Scotland - Business | ins_118276 |
Barclays (UK) - Mobile Banking: Business | ins_118512 |
Barclays (UK) - Mobile Banking: Personal | ins_118511 |
Barclays (UK) - Mobile Banking: Wealth Management | ins_118513 |
First Direct | ins_81 |
Halifax | ins_117246 |
HSBC (UK) - Business | ins_118277 |
HSBC (UK) - Personal | ins_55 |
Lloyds Bank - Business and Commercial | ins_118275 |
Lloyds Bank - Personal | ins_61 |
Monzo | ins_117243 |
Nationwide Building Society | ins_60 |
NatWest - Current Accounts | ins_115643 |
Revolut | ins_63 |
Royal Bank of Scotland - Current Accounts | ins_115642 |
Santander (UK) - Personal and Business | ins_62 |
Starling | ins_117520 |
Tesco (UK) | ins_118393 |
TSB | ins_86 |
Ulster Bank (UK) | ins_117734 |