Transactions webhooks

Listen for Transaction webhooks to learn when transactions are ready for retrieval or when transactions have been updated.


Webhooks are a critical part of the Transactions product, as Plaid uses webhooks to tell you when transactions are ready to be retrieved, when new transactions have been added, or when old ones have changed. This guide will explain how to handle all four transaction webhooks to make sure you have access to a user's full and up-to-date transaction history.

Configuring webhooks

Before you can listen to webhooks, you must first set up an endpoint and tell Plaid where to find it. To tell Plaid where to send its webhooks, send your webhook endpoint URL as an optional argument via the webhook parameter within your client-side Link configuration.

var handler = Plaid.create({
webhook: '',

Pulling transactions

When you first connect an Item in Link, transactions data will not immediately be available. INITIAL_UPDATE and HISTORICAL_UPDATE are both webhooks that fire shortly after an Item has been initially linked and initialized with the Transactions product. These webhooks will let you know when your transactions are ready. INITIAL_UPDATE fires first, after Plaid has successfully pulled 30 days of transactions for an Item. The HISTORICAL_UPDATE webhook fires next, once all historical transactions data is available. It typically takes about 10 seconds for INITIAL_UPDATE to fire and 1-2 minutes for HISTORICAL_UPDATE to fire.

If you attempt to call /transactions/get before INITIAL_UPDATE has fired, you will get a PRODUCT_NOT_READY error. If you attempt to call /transactions/get after INITIAL_UPDATE has fired, but before HISTORICAL_UPDATE has fired, you will only be able to receive the last 30 days of transaction data. If you did not initialize the Item with Transactions, your first call to /transactions/get will result in a PRODUCT_NOT_READY error and kick off the process of readying transactions. You can then listen for the INITIAL_UPDATE or HISTORICAL_UPDATE webhooks to begin receiving transactions.

Updating transactions

Plaid fires two types of webhooks that provide information about changes to transaction data: DEFAULT_UPDATE and TRANSACTIONS_REMOVED.

Adding new transactions

The DEFAULT_UPDATE webhook fires when new transactions are available. Typically, Plaid will check for transactions once every 6 hours, but may check less frequently (such as once every 24 hours) depending on factors such as the institution and account type. If new transactions are available, the DEFAULT_UPDATE webhook will fire.

To reflect up-to-date transactions for a user in your app, handle the DEFAULT_UPDATE webhook by fetching more transactions. Typically, we recommend fetching about 7-14 days of transactions in response to DEFAULT_UPDATE. This is typically enough history to ensure that you haven't missed any transactions, but not so much history that performance or rate limiting is likely to be a problem. Once you've fetched these transactions, you will then need to identify which transactions are new and which are duplicates of existing transactions data that you have. You should not rely on the number in the webhook's new_transactions field to identify duplicates, since it can be unreliable. For example, new transactions may arrive between your receipt of the webhook and your call to /transactions/get. Instead, compare the transaction_id field of each newly fetched transaction to the transaction_id field of your most recent existing transaction, and stop adding transactions once you've found a match.

Removing stale transactions

The TRANSACTIONS_REMOVED webhook fires when transactions have been removed. The most common reason for this is in the case of pending transactions. In general, transactions start out as pending transactions and then move to the posted state one to two business days later. When Plaid detects that a transaction has moved from pending to posted state, the pending transaction itself as returned by /transactions/get is not modified. Instead, the pending transaction is removed, and a new transaction is added, representing the posted transaction. For a detailed explanation of pending and posted transactions and how they are handled by Plaid, see Transaction states. Pending transactions can also be removed when they are cancelled by the bank or payment processor. In rare situations, posted transactions can also be removed.

The TRANSACTIONS_REMOVED webhook contains the transaction IDs of the removed transactions, which you can use to identify and remove the corresponding transactions in your own application to avoid presenting duplicated or inaccurate data. If you encounter any problems with the webhook, you can also manually query transaction history for deleted transactions using logic similar to that recommended for handling the DEFAULT_UPDATE webhook.

Example webhook code in Plaid Pattern

For a real-life example of handling webhooks that illustrates how to handle all four transaction webhook types, see handleTransactionsWebhook.js, which contains the webhook handling code for the Node-based Plaid Pattern app.

Forcing transactions refresh

Sometimes, checking for transactions a few times a day is not good enough. For example, if your user just fixed an outdated password that was preventing your app from fetching transactions for several days, you might want to immediately check for removed and updated transactions. Or you might want to build a refresh button in your app that allows your user to check for updated transactions on-demand. Calling the /transactions/refresh endpoint will force DEFAULT_UPDATE and TRANSACTIONS_REMOVED to check for updates and fire if there are any changes for them to report. It's a recommended practice to call /transactions/refresh when your user exits the Link flow in update mode. When fetching transactions after updating an Item in Link, you should fetch transactions for at least 1-2 days beyond the number of days the Item was in an error state, or at least 90 days of transactions if you aren't tracking the number of days that the Item was disconnected.

Verifying webhooks

Before you launch your app to the world in Production, it's a good idea to add logic that verifies Plaid's webhooks to make sure that the webhook is coming from Plaid, and not from a third party impersonator. You can do this by verifying the webhook using the /webhook_verification_key/get endpoint.