Introduction
Note: Plaid's legacy API was deprecated on September 30, 2018. If you are already using Link, head to the Link Transition Guide to read about transitioning to the current API. If you are not using Link, head to the Direct API to Link Transition Guide instead.
The fastest way to get started with Plaid is by integrating with Plaid Link, a drop-in module that offers a secure, elegant authentication flow for each institution that Plaid supports. Read on to get started, or jump to the API reference, explore some sample apps, or tinker with the demo to see Link in action.
Glossary
Most Plaid API calls involve three pieces of information: a client_id
, secret
, and an access_token
. All three of these are considered private information - they are not meant to be shared or hard coded directly into an app or site. This poses a problem for Plaid Link, as a user will be onboarding directly in the browser. To address this, Plaid client accounts now have an additional identifier: a public_key
.
The public_key
- Associates users that onboard through Plaid Link with your
client_id
andsecret
- Cannot be used to make authenticated Plaid API calls (i.e. retrieving account and routing numbers for a user)
The public_token
Once a user has successfully onboarded via Plaid Link, the module will provide a public_token
. This is in contrast to typical Plaid API requests, which return an access_token
.
- Is safe to expose in an app or browser
- Cannot be used to retrieve account and routing numbers (for auth) or transactions (for connect) directly
- Can be exchanged for a Plaid
access_token
via the/exchange_token
endpoint.
The getting started guide below illustrates how to use your public_key
to get up and running with Plaid Link. The guide also covers how to exchange a public_token
for an access_token
.
Getting started
There are two different integrations:
- Simple The simple integration provides a customizable "Link your Bank Account" button and handles submitting a Plaid
public_token
to a server endpoint that you specify. - Custom The custom integration lets you trigger the Plaid Link module via client-side Javascript. You specify your own callback function to be called with the
public_token
once a user has authenticated.
Step 1: Get your public_key
Your public_key
is available from the Plaid dashboard. Your public_key
is a less privileged version of your client_id
and secret
. It simply associates accounts you create using Plaid Link with your client_id
. All Plaid API requests must be made using your private client_id
and secret
.
Step 2: Simple integration
Include the following markup (the <form>
and <script>
tags) in your site or web application:
<!-- A hidden input named public_token will be appended to this form
once the user has completed the Link flow. Link will then submit the
form, sending the public_token to your server. -->
<form id="some-id" method="POST" action="/authenticate"></form>
<!-- See the Parameter Reference for additional documentation. -->
<script
src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"
data-client-name="Client Name"
data-form-id="some-id"
data-key="test_key"
data-product="auth"
data-env="tartan">
</script>
See the parameter reference for complete documentation on possible configurations.
The injected "Link your Bank Account" button has the ID plaid-link-button
and can be styled with CSS:
#plaid-link-button {
border: 10px solid pink;
}
Step 3: Custom integration
The custom integration allows you to decide, with a few lines of client-side Javascript, when the module is triggered. See below:
<button id='linkButton'>Open Link - Institution Select</button>
<button id='bofaButton'>Open Link - Bank of America</button>
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>
<script>
var linkHandler = Plaid.create({
env: 'tartan',
clientName: 'Client Name',
key: 'test_key',
product: 'auth',
onLoad: function() {
// The Link module finished loading.
},
onSuccess: function(public_token, metadata) {
// Send the public_token to your app server here.
// The metadata object contains info about the institution the
// user selected and the account ID, if selectAccount is enabled.
},
onExit: function(err, metadata) {
// The user exited the Link flow.
if (err != null) {
// The user encountered a Plaid API error prior to exiting.
}
// metadata contains information about the institution
// that the user selected and the most recent API request IDs.
// Storing this information can be helpful for support.
}
});
// Trigger Link's institution select view
document.getElementById('linkButton').onclick = function() {
linkHandler.open();
};
</script>
See the parameter reference for complete documentation on possible configurations.
Plaid.create
accepts one argument, a configuration Object
, and returns an Object
with two functions, open
and exit
, and one property, institutions
. open
accepts either no arguments or an optional institution type. If no argument is provided, the "Institution Select" view is opened. If a valid institution type is provided, the login form for that particular institution is opened. The exit function allows you to programatically close Link.
The exposed institutions
property is an Array
of Object
s in the form:
[{
name: 'Bank of America',
type: 'bofa',
auth: true,
connect: true
},
...]
The institutions
property will be populated with all supported institutions for a given product. That is, the list of institutions will be different for auth
and connect
. Use the institutions
property to dynamically generate a list of supported institutions for your Link integration - by doing so, your app will support new institutions and products automatically.
Step 4: Write server-side handler
The Link module handles the entire onboarding flow securely and quickly but does not actually retrieve account or transaction data for a user. Instead, the Link module returns a public_token
that is safe to expose in the browser.
This public_token
must be exchanged for a Plaid access_token
using the /exchange_token
API endpoint. To do so, you must add a server side handler. A sample node.js server-side handler is provided below - full application samples can be found in the Examples section below.
With the simple integration, the public_token
will be appended to the form specified by data-form-id
as a hidden input. This form will be automatically submitted once a user has completed onboarding.
With the custom integration, the callback
you specified in Plaid.create
will be called with one argument, the public_token
. It is your responsibility to send it to your app server.
In the example above, the form some-id
had action="/authenticate"
. So we'll add a /authenticate
route to our server side code that expects a POST
request with a field named public_token
in the request body. We'll then use that public_token
along with our private client_id
and secret
to retrieve a Plaid access_token
(via the /exchange_token
endpoint). This access_token
should be saved in a database and used to retrieve account and transaction data. Below is a sample server-side handler using Express and the plaid-node library:
var express = require('express');
var plaid = require('plaid');
var app = express();
var plaidClient = new plaid.Client(process.env.PLAID_CLIENT_ID,
process.env.PLAID_SECRET,
plaid.environments.tartan);
app.post('/authenticate', function(req, res) {
var public_token = req.body.public_token;
// Exchange a public_token for a Plaid access_token
plaidClient.exchangeToken(public_token, function(err, exchangeTokenRes) {
if (err != null) {
// Handle error!
} else {
// This is your Plaid access token - store somewhere persistent
// The access_token can be used to make Plaid API calls to
// retrieve accounts and transactions
var access_token = exchangeTokenRes.access_token;
plaidClient.getAuthUser(access_token, function(err, authRes) {
if (err != null) {
// Handle error!
} else {
// An array of accounts for this user, containing account
// names, balances, and account and routing numbers.
var accounts = authRes.accounts;
// Return account data
res.json({accounts: accounts});
}
});
}
});
});
Check out the Examples for more sample code and complete example apps.
Step 5: Test with sandbox credentials
The Link module has a sandbox mode that works with the Plaid API sandbox. To enable the sandbox, set data-key
or key
to test_key
(for simple and custom integrations, respectively). This lets you see the flow for each individual institution Plaid supports, including the multi-factor authentication process when applicable.
For simple integrations:
<!-- A hidden input named public_token will be appended to this form
once the user has completed the Link flow. Link will then submit the
form, sending the public_token to your server. -->
<form id="some-id" method="POST" action="/authenticate"></form>
<script
src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"
data-client-name="Client Name"
data-form-id="some-id"
data-key="test_key"
data-product="auth"
data-env="tartan">
</script>
For custom integrations:
<button id="plaidLinkButton">Open Plaid Link</button>
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>
<script>
var sandboxHandler = Plaid.create({
env: 'tartan',
clientName: 'Client Name',
key: 'test_key',
product: 'auth',
onSuccess: function(public_token, metadata) {
console.log(public_token, metadata);
},
});
document.getElementById('plaidLinkButton').onclick = function() {
// Trigger the "Institution Select" view
sandboxHandler.open();
};
</script>
If you are having trouble using the module in sandbox mode, check the developer console in your browser for error messages.
Updating existing accounts
When a user changes their username, password, or MFA credentials with a financial institution or is locked out of their account, they must update their credentials with Plaid as well.
Link's update mode makes this process secure and painless and is available in both the simple and custom integrations. To use update mode, initialize Link with the public_token
for the user you wish to update.
For the simple integration add the data-token
attribute as follows:
<!-- A hidden input named public_token will be appended to this form
once the user has completed the Link flow. Link will then submit the
form, sending the new public_token to your server. -->
<form id="some-id" method="POST" action="/authenticate"></form>
<script
src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"
data-client-name="Client Name"
data-form-id="some-id"
data-key="test_key"
data-product="auth"
data-env="tartan"
data-token="test,chase,connected">
</script>
The custom initializer takes a similarly-named token
added to the parameter hash:
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>
<script>
var linkHandler = Plaid.create({
env: 'tartan',
clientName: 'Client Name',
key: 'test_key',
product: 'auth',
token: 'test,chase,connected', // <- token to patch
onLoad: function() {
// The Link module finished loading.
},
onSuccess: function(public_token, metadata) {
// Send the public_token to your app server here.
// The metadata object contains info about the institution the
// user selected and the account ID, if selectAccount is enabled.
},
onExit: function(err, metadata) {
// The user exited the Link flow.
if (err != null) {
// The user encountered a Plaid API error prior to exiting.
}
// metadata contains information about the institution
// that the user selected and the most recent API request IDs.
// Storing this information can be helpful for support.
},
});
// Trigger the authentication view
document.getElementById('linkButton').onclick = function() {
// Link will automatically detect the institution type associated with the
// public token and present the credential pane to your user.
linkHandler.open();
};
</script>
Link will automatically detect the institution type associated with the public_token
and present the appropriate credential pane to your user.
Note: Calling open
with an institution type as an argument (e.g.: open('chase')
) is not supported when Link is initialized in update mode.
Test update mode with sandbox tokens
For update mode a suitable sandbox public token can be generated by inserting the desired institution type into the string test,{institution_type},connected
.
For example:
test,chase,connected
test,usaa,connected
test,wells,connected
Reference
/exchange_token Endpoint
The /exchange_token
endpoint is available in both the tartan
(https://tartan.plaid.com
) and production (https://api.plaid.com
) environments.
Method | Endpoint | Required Parameters | Optional Parameters |
---|---|---|---|
POST | /exchange_token |
client_id , secret , public_token |
account_id |
The /exchange_token
endpoint has already been integrated into the plaid-node, plaid-go, plaid-ruby, and plaid-python client libraries. Support for plaid-java is coming soon.
If you are working with a library that does not yet support the /exchange_token
endpoint you can simply make a standard HTTP request:
curl -X POST https://tartan.plaid.com/exchange_token \
> -d client_id="$plaid_client_id" \
> -d secret="$plaid_secret" \
> -d public_token="$public_token_from_plaid_link_module"
For a valid request, the API will return a JSON response similar to:
{
"access_token": "foobar_plaid_access_token"
}
For possible error codes, see the full listing of Plaid error codes.
Simple integration
Parameter | Required | Description |
---|---|---|
data-client-name |
required | Displayed once a user has successfully linked their account. |
data-form-id |
required | The DOM ID associated with form that the Link module will append the public_key to as a hidden input and submit when a user completes the onboarding flow. |
data-product |
required | The Plaid product you wish to use: auth , connect , info , or income . |
data-key |
required | The public_key associated with your account; available from the dashboard. |
data-env |
required | The Plaid API environment on which to create user accounts. For development and testing, use tartan . For production use, use production .Note: all production requests are billed. |
data-webhook |
optional | Specify a webhook to associate with a user. |
data-token |
optional | Specify an existing user's public token to launch Link in update mode. This will cause Link to open directly to the authentication step for that user's institution. |
Custom integration
Parameter | Required | Description |
---|---|---|
clientName |
required | Displayed once a user has successfully linked their account. |
product |
required | The Plaid product you wish to use: auth , connect , info , or income . |
key |
required | The public_key associated with your account; available from the dashboard. |
env |
required | The Plaid API environment on which to create user accounts. For development and testing, use tartan . For production use, use production .Note: all production requests are billed. |
onSuccess |
required | A function that is called when a user has successfully onboarded their account. The function should expect two arguments, the public_token and a metadata object. |
onExit |
optional | A function that is called when a user has specifically exited the Link flow. The function should expect two arguments, a nullable error object and a metadata object. See onExit. |
onLoad |
optional | A function that is called when the Link module has finished loading. Calls to plaidLinkHandler.open() prior to the onLoad callback will be delayed until the module is fully loaded. |
webhook |
optional | Specify a webhook to associate with a user. |
token |
optional | Specify an existing user's public token to launch Link in update mode. This will cause Link to open directly to the authentication step for that user's institution. |
selectAccount |
optional | Set to true to launch Link with the 'Select Account' pane enabled. This allows users to select an individual account once they've authenticated. The Plaid Account ID of this account is provided in the metadata object of the onSuccess callback under the key account_id .Note: If you are using Link with Connect, all accounts will be listed on the Select Account pane. If you are using Link with Auth, only depository accounts will be listed. |
isWebview |
optional | Set to true if launching Link within a WebView. |
onSuccess callback
The onSuccess
callback should take two arguments, the public_token
and a metadata
object. The metadata
object provides the following information:
Parameter | Description |
---|---|
institution |
An Object with two properties: - name : The full institution name, such as 'Bank of America'.- type : The institution type, such as 'bofa'. |
account |
The Plaid Account of the account selected by the user. - id : the account id selected- name : the name of the selected accountNote: Only applicable when the selectAccount is true . |
onExit callback
The onExit
callback is called when a user exits the Link flow. It takes two arguments, a nullable error
object and a metadata
object.
Parameter | Description |
---|---|
error |
A nullable object that contains the API error code and message of the error that was last encountered by the user. If no error was encountered, error will be null . |
metadata |
An object containing information about the user's Link session, including Link and API request IDs and the name and type of the institution selected by the user. |
If present, the error
argument will return an Object
in the form of:
{
code: String,
message: String,
}
If no error was encountered, the error
argument will be null
.
The metadata
parameter is always present, though some values may be null
:
{
institution: {name: String, type: String},
link_request_id: String,
plaid_api_request_id: String,
status: String,
}
The value of the status
key indicates the point at which the user exited the Link flow. status
may be one of the following values:
Status | Description |
---|---|
connected | User completed the Link flow |
requires_questions | User was prompted to answer security question(s) |
requires_selections | User was prompted to answer multiple choice question(s) |
requires_code | User was prompted to provide a one time passcode. |
choose_device | User was prompted to select a device at which to receive a one-time passcode. |
requires_credentials | User was prompted to provide credentials for the selected financial institution or has not yet selected a financial institution |
The arguments in the onExit
function are meant to help you guide your users after they have exited Link. We recommend storing the error and metadata information server side in a way that can be associated with the user. Please include this and other relevant information in any support requests for the user.
exit() function
The exit
function allows you to programmatically close Link. Calling exit
will trigger either the onExit
or onSuccess
callbacks. exit
takes a single, optional argument, a configuration Object
. The configuration options are:
Option | Required | Description |
---|---|---|
force |
optional | Boolean. If true , Link will exit immediately. If false , or the option is not provided, an exit confirmation screen may be presented to the user. |
For example:
// Initialize Link
var linkHandler = Plaid.create(...)
// Force exit - Link exits immediately
linkHandler.exit({ force: true })
// Graceful exit - Link may display a confirmation screen
// depending on how far the user is in the flow
linkHandler.exit()
// This is equivalent to the above:
linkHandler.exit({ force: false })
exit()
works on desktop and mobile but is not supported for WebView integrations. To exit Link in a WebView, you must programmatically close the iOS or Android WebView.
Security
All data sent to Plaid is encrypted using a secure HTTPS connection with our servers. While you can use the module on a non-HTTPS site (all data sent to Plaid operates in an entirely different context and connection), we strongly recommend using HTTPS at all times.
More information about Plaid's security policies and practices can be found on our website.
Browser support
Desktop




Mobile
Modern mobile browsers are supported, including most iPhone and Android devices. If you encounter any inconsistencies, open an issue.
WebView integration
Link is optimized to work within WebViews, including on iOS and Android. The Link initialization URL that's optimized for WebViews is:
The Link configuration options for a WebView integration are passed via querystring rather than via a client-side Javascript call. See the parameter reference for complete documentation. For example:
https://cdn.plaid.com/link/v2/stable/link.html
?isWebview=true
&key=test_key
&env=tartan
&product=connect
&selectAccount=true
&clientName=Plaid%20Demo
Looking to get started right away? Jump to the WebView examples for sample code! The sample code includes example code to initialize Link and process events communicated from Link to your app.
You can initialize Link in update mode within a WebView by including a token
paramter in the Link initialization URL:
https://cdn.plaid.com/link/v2/stable/link.html
?isWebview=true
&key=test_key
...
&token=test,chase,connected
Communication between Link and your app
Communication between the WebView and your app is handled by HTTP redirects rather than client-side JavaScript callbacks. These redirects should be intercepted by your app. The example apps include sample code to do this.
All redirect URLs have the scheme plaidlink
. The event type is communicated via the URL host and data is passed via the querystring. There are two supported events, connected
and exit
, which are documented below.
For example:
plaidlink://connected
?public_token=test,chase,connected
&account_id=QPO8Jo8vdDHMepg41PBwckXm4KdK1yUdmXOwK
&account_name=Plaid%20Savings
&institution_type=chase
&institution_name=Chase
connected
event
The connected
event is analgous to the onSuccess
callback and is sent when the user completes the Link flow. The following information is available from the querystring:
Field | Description |
---|---|
public_token |
Link public_token which is exchanged for an API access_token . Should be stored for use with Link's update mode. |
account_id |
The ID of the account that was selected by the user. |
account_name |
The name of the account that was selected by the user. |
institution_type |
The institution type, such as 'bofa' . |
institution_name |
The full institution name, such as 'Bank of America' . |
exit
event
The exit
event is analgous to the onExit
callback and is sent when the user exits the Link flow. The following information is available from the querystring:
Field | Description |
---|---|
status |
The user's status in the Link flow when they exited. See the possible values. |
error_code |
The Plaid API error code that the user encountered. |
error_message |
The Plaid API error message that the user encountered. |
institution_type |
The institution type, such as 'bofa' . |
institution_name |
The full institution name, such as 'Bank of America' . |
link_request_id |
The Link request ID. This can be shared with Plaid Support to expedite investigation. |
plaid_api_request_id |
The Plaid API request ID. This can be shared with Plaid Support to expedite investigation. |
WebView examples
To get your Link WebView integration started, check out our example apps, available for iOS and Android.
Each example app is runnable (on both simulators and devices) and includes code to initialize Link and process events sent from Link to your app via HTTP redirects.
Expansion
Plaid Link is currently a web-only integration. Plaid Link will offer native iOS and Android bindings in the coming months.
Support and questions
Find answers to many common integration questions and concerns at our Help Center.
If you're still stuck, open a ticket with information describing the issue that you're experiencing and we'll get back to you as soon as we can.
Examples
Check out our code samples and community-contributed resources to kickstart your Plaid Link integration!
Client Libraries
Link provides a drop-in HTML snippet for the client-side integration but does requires a server-side handler to coordinate exchanging a Link public_token
for a Plaid access_token
via the /exchange_token
endpoint.
The /exchange_token
endpoint is integrated into each of our client libraries. Check out some examples:
Sum App
We built Sum to demonstrate a sample Link client and server-side integration using our client libraries. Check out the source code in the language or framework of your choice:
Each implementation has a complete README with instructions for running the app locally!