Direct API to Link Transition Guide

Overview

Transitioning

Plaid's legacy API will be deprecated on September 30, 2018. Transitioning from Plaid's legacy API to the current API is simple. On the client-side, users are onboarded through Plaid Link, a drop-in module that provides a secure, elegant authentication flow for each institution that Plaid supports. Link makes it secure and easy for users to connect their bank accounts to Plaid. On the back-end, we have reorganized and added to the server-side API to make it even easier to use Plaid.

This guide walks through what has changed and how to update your integration to take advantage of the current API.

Looking for legacy docs? Head here. Looking for the current docs? Head here.

Already using Link? Check out our Link transition guide.

Notable changes

  • Product, endpoint, and API environment names and URLs have changed
  • New users are authenticated through Plaid Link
  • Existing users can be transitioned to the current API without having them re-authenticate
  • Error types and codes have been streamlined and simplified
  • Client libraries and docs are updated with the new endpoints
  • Stateful Sandbox - test MFA flows, errors, webhooks, and more

API Environments

New Environment Notes
Sandbox https://sandbox.plaid.com
Development https://development.plaid.com – analogous to the legacy tartan environment
Production https://production.plaid.com – analogous to the legacy api environment

Your existing API keys will work across all three current API environments as well as the legacy API.

If you want to disable legacy API access, please open a case from your Dashboard.

Glossary

In the current API, terms and definitions remain the same, and we also introduce the concept of an Item.

  • Item: A set of credentials at a financial institution; each Item can have many Accounts, and some Accounts have Transactions associated with them. An Item's data can be accessed using its corresponding access_token
  • client_id and secret: two private API keys; used in conjunction with an access_token to access data for an Item
  • public_key: a public API identifier; used to initialize Link to create or update existing Items
  • access_token: A rotatable token unique to a single Item; used to access data for that Item
  • public_token: A short-lived token that can be exchanged for an access_token or used to initialize Link in update mode for an Item

Server-side integration

We recommend beginning your transition to the current API by updating your server-side API calls. In order to utilize the current API endpoints, you will need to upgrade your existing Items' access_tokens.

Transitioning existing Items

You can transition your users’ existing Items to the current API via the /item/access_token/update_version endpoint. A new access_token will be generated for each Item that can be used with our current API. The previous access_token will still be valid in our legacy API environment.

Note: You’ll begin receiving updated webhooks and stop receiving legacy API webhooks as soon as you generate an updated access_token for an Item.

Update access_token version request

curl -X POST https://sandbox.plaid.com/item/access_token/update_version \
  -H 'content-type: application/json' \
  -d '{
    "client_id": String,
    "secret": String,
    "access_token_v1": String
  }'
# generate an updated access token for the legacy token
response = client.item.access_token.update_version("LEGACY_API_ACCESS_TOKEN")
# The response includes an access token compatible with Plaid's new API and
# the item ID for the access_token, which is used to identify the Item in 
# webhook payloads from Plaid.
# The old access token will still work with Plaid's legacy API endpoints.
# Store the new access_token and the item_id in a persistent, secure data store.
newAccessToken = response['access_token']
itemId = response['item_id']
# generate an updated access token for the legacy token
response = client.Item.access_token.update_version("LEGACY_API_ACCESS_TOKEN")
# The response includes an access token compatible with Plaid's new API and
# the item ID for the access_token, which is used to identify the Item in 
# webhook payloads from Plaid.
# The old access token will still work with Plaid's legacy API endpoints.
# Store the new access_token and the item_id in a persistent, secure data store.
newAccessToken = response.access_token
itemId = response.item_id
// Generate an updated access token for the legacy token
client.updateAccessTokenVersion("LEGACY_API_ACCESS_TOKEN", (err, result) => {
  // Handle err
  // The response includes an access token compatible with Plaid's new API and
  // the item ID for the access_token, which is used to identify the Item in 
  // webhook payloads from Plaid.
  // The old access token will still work with Plaid's legacy API endpoints.
  // Store the new access_token and the item_id in a persistent, secure data store.
  const newAccessToken = result.access_token;
  const itemId = result.item_id;
});
// Generate an updated access token for the legacy token
Response<ItemAccessTokenUpdateVersionResponse> response = client().service().itemAccessTokenUpdateVersion(
  new ItemAccessTokenUpdateVersionRequest("LEGACY_API_ACCESS_TOKEN"))
  .execute();

String newAccessToken;
String itemId;
if (response.isSuccessful()) {
  // The response includes an access token compatible with Plaid's new API and
  // the item ID for the access_token, which is used to identify the Item in 
  // webhook payloads from Plaid.
  // The old access token will still work with Plaid's legacy API endpoints.
  // Store the new access_token and the item_id in a persistent, secure data store.
  newAccessToken = response.body().getAccessToken();
  itemId = response.body().getItemId();
}

Update access_token version response

http code 200
{
  "access_token": "access-production-8acd3678-3aa8-411e-bf5a-ee7851e0c75d",
  "item_id": "XkW36J3gewh9wE69VkyzSxyXwEBewBio4wwJ3",
  "request_id": "c92aB"
}

During the transition process, we recommend storing both the legacy and updated versions of all access_tokens in your database. This will allow you to maintain your existing user-authentication logic for legacy access_tokens through the transition period and to then easily upgrade them for use with the current API.

API endpoints

Plaid’s API endpoint names have changed. We’ve reorganized the API to make it easier to use, provide more information about your users' Items, and made it simpler to access multiple products. All of our official client libraries (Node, Python, Ruby, and Java) have been updated to support these current endpoints. This guide provides an overview and reference for the changes. All API endpoints have documented, consistent request and response schemas.

Previous endpoint Notable changes
/<product> and /<product>/step Removed; credential authentication is now handled through Link.
/upgrade Removed; there is no need to use /upgrade before accessing a product endpoint.
/connect/get Now /transactions/get; the endpoint is now paginated by default but still supports searching by date ranges. Pending transactions are returned by default.
/auth/get No change.
/info/get Now /identity/get.
/institutions/all/search Now /institutions/search.

We’ve also introduced a few new endpoints to make it easier to work with the API and your Items:

Endpoint Notes
/item/webhook/update Update the webhook associated with an Item. Triggers an acknowledgement webhook in response.
/item/get Retrieve information about an Item, including the institution type, error status, available and billed products, and webhook information.

To complete the server-side transition to the current API, you will also need to update the way you handle API errors and webhooks, as we have streamlined the error and webhook schema in the current API.

Once you have fully integrated the new API endpoints and error/webhook handling, you can begin upgrading the access_token version for newly-authenticated users as well.

Client-side integration

With the server-side API calls integrated, the next step is to replace your direct API integration with Link on the client-side to seamlessly authenticate and onboard new users. Before you get started, explore some sample apps, or tinker with the demo to see Link in action.

Plaid Link Auth Flow

Link can be integrated via client-side Javascript, initialized with parameters that you specify. These parameters will be used to create an Item once a user has successfully authenticated their credentials through Link. Check out the current docs for the full parameter reference.

<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>
<button id="link-button"> Open Link </button>
<script>
var linkHandler = Plaid.create({
  env: 'production',
  apiVersion: 'v2',
  clientName: '<CLIENT_NAME>',
  // Replace '<PUBLIC_KEY>' with your own `public_key`
  key: '<PUBLIC_KEY>',
  product: ['auth','transactions'],
  // Use webhooks to get transaction and error updates
  webhook: '<WEBHOOK_URL>',
  onSuccess: function(public_token, metadata) {
    // Send the public_token to your app server here.
    // The metadata object contains info about the
    // institution selected and, if the Select Account
    // view is enabled, information about the account(s)
    // the user selected too.
  },
  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.
  },
  onEvent: function(eventName, metadata) {
    // Optionally capture Link flow events, streamed through
    // this callback as your users connect an Item to Plaid.
  },
});
// Trigger the standard institution select view
document.getElementById('link-button').onclick = function() {
  linkHandler.open();
};
 </script>

You'll want to ensure that you've set the apiVersion parameter to v2 in order to make Link compatible with your updated server-side integration. With Link, you no longer need to handle MFA flows and error flows - Link handles the entire user authentication process from end-to-end and passes back a public_token in the onSuccess callback once a user successfully connects to their bank. This public_token can then be exchanged server-side for an access_token via the /item/public_token/exchange endpoint, with which you can then begin accessing the new API endpoints as normal.

When a user's bank credentials, MFA, or security settings have changed, you would have received an 120X error webhook in the legacy API. In the current API, any error that requires the user to re-authenticate will trigger an ITEM_LOGIN_REQUIRED webhook.

{
  "webhook_type": "ITEM",
  "webhook_code": "ERROR",
  "item_id": "wz666MBjYWTp2PDzzggYhM6oWWmBb",
  "error": {
    "display_message": "The provided credentials were not correct. Please try again.",
    "error_code": "ITEM_LOGIN_REQUIRED",
    "error_message": "the provided credentials were not correct",
    "error_type": "ITEM_ERROR",
    "status": 400
  }
}

Instead of sending a PATCH request to re-authenticate the user, you'll prompt the user to go through Link in update mode to re-link their account and restore the Item's state. Check out the current docs on how to generate a public_token and launch Link in update mode.

For a complete walkthrough of the client-side Link integration and server-side handling of Link callbacks, head over to the current docs.

Other updates

Institutions

In the current API, all institutions IDs observe a consistent schema: numeric identifiers prefixed with ins_. Short hand institution codes (such as chase, bofa, and wells) are no longer supported. We suggest using Link's Institution Select view, which is always up-to-date, or using our Institution API endpoints if using custom initializers.

Errors

The schema for errors have changed, and we’ve reduced the total number of error types.

Field Nullable? Description
error_type
String
No A broad categorization of the error. One of: INVALID_REQUEST, INVALID_INPUT, RATE_LIMIT_EXCEEDED, API_ERROR, or ITEM.
Safe for programmatic use.
error_code
String
No The particular error code. Each error_type has a specific set of error_codes.
Safe for programmatic use.
error_message
String
No A developer-friendly representation of the error message.
This may change over time and is not safe for programmatic use.
display_message
String
Yes A user-friendly representation of the error message. null if the error is not related to user action.
Not safe for programmatic use.

Below are some of the most common error codes:

Error code Explanation
ITEM_LOGIN_REQUIRED Indicates that the user must provide updated authentication in order for Plaid to continue updating the Item. This can happen when a user changes a password, MFA information, or if the account is locked. Use Link’s update mode to resolve this.
ITEM_NOT_SUPPORTED Indicates that Plaid is unable to support the Item. This is rare but can happen for some users with restrictions on their accounts at the institution.
MFA_NOT_SUPPORTED Indicates that the Item requires a type of MFA that Plaid does not support. In some cases, a user can disable the unsupported type of MFA.
NO_ACCOUNTS Indicates that there are no longer any accounts associated with the Item.
PRODUCT_NOT_READY Indicates that the requested product is not yet ready - Plaid is still working to pull the information from the financial institution. Retry the request later or use webhooks to determine when the products is ready.

Webhooks

There are a few key changes with webhooks:

  • Schema updated
  • New field: webhook_type is a high-level categorization of the webhook
  • item_id replaces access_token in the payload as the identifier
Legacy Webhook Code New Webhook Code
0 INITIAL_UPDATE - Initial transaction pull completed
1 HISTORICAL_UPDATE - Historical transaction pull completed
2 DEFAULT_UPDATE - New transactions are available
3 REMOVED_TRANSACTIONS - Transactions have been removed
4 WEBHOOK_UPDATE_ACKNOWLEDGED - Webhook successfully updated for an Item after calling /item/webhook/update
120X ITEM_LOGIN_REQUIRED - The user needs to re-authenticate through Link in update mode

See the docs for more webhook payload examples.

Legacy Webhook Format
{
  "message": "Initial transaction pull finished",
  "access_token": "xxxxx",
  "total_transactions": 123,
  "code": 0
}
Current API TRANSACTIONS Webhook Format
{
  "webhook_type": "TRANSACTIONS",
  "webhook_code": "DEFAULT_UPDATE",
  "item_id": "wz666MBjYWTp2PDzzggYhM6oWWmBb",
  "error": null,
  "new_transactions": 3
}
Current API ITEM Webhook Format
{
  "webhook_type": "ITEM",
  "webhook_code": "ERROR",
  "item_id": "wz666MBjYWTp2PDzzggYhM6oWWmBb",
  "error": {
    "display_message": "The provided credentials were not correct. Please try again.",
    "error_code": "ITEM_LOGIN_REQUIRED",
    "error_message": "the provided credentials were not correct",
    "error_type": "ITEM_ERROR",
    "status": 400
  }
}

Sandbox

The API Sandbox environment is now a stateful testing environment, allowing you to test errors, webhooks, MFA, Link update mode, and more. Head to the docs for more info.