Transactions Sync migration guide
Learn how to migrate from the /transactions/get endpoint to the /transactions/sync endpoint
/transactions/sync is a newer endpoint that replaces
/transactions/get and provides a simpler and easier model for managing transactions updates. While
/transactions/get provides all transactions within a date range,
/transactions/sync instead uses a cursor to provide all new, modified, and removed transactions that occurred since your previous request. With this cursor-based pagination, you do not need to worry about making redundant API calls to avoid missing transactions. Updates returned by
/transactions/sync can be patched into your database, allowing you to avoid a complex transaction reconciliation process or having to keep track of which updates have already been applied.
Looking for an example in code? Check out Pattern on GitHub for a complete, best-practice implementation of the Transactions Sync API within a sample app.
Update your client library
If you are using client libraries, you may need to update your current library to use
/transactions/sync. The following are the minimum Plaid client library versions required to support
/transactions/sync for each language:
- Python: 9.4.0
- Node: 10.4.0
- Ruby: 15.5.0
- Java: 11.3.0
- Go: 3.4.0
Detailed upgrade notes are language-specific may be found in the README and Changelog of the specific library. See the library's repo on the Plaid GitHub for more information.
Update callsites and pagination logic
Replace all instances of
/transactions/sync has a slightly different call signature from
/transactions/get and does not have the
count parameter inside the
options object and uses a
cursor instead of a
end_date. Pagination logic is also different and relies on the
has_more flag instead of the
transactions_count value. Note that when requesting paginated updates with
/transactions/sync, unlike when using
/transactions/get, it is important to retrieve all available updates before persisting the transactions updates to your database.
Update callsites for account and Item data
/transactions/sync does not return an account object or Item object. If your app relies on getting account data, such as balance, from the
/transactions/get call, use
/accounts/get to instead retrieve this information. If it relies on Item data, such as Item health status, use
Update webhook handlers
/transactions/sync, you should not listen for the webhooks
TRANSACTIONS_REMOVED. While these webhooks will still be sent in order to maintain backwards compatibility, they are not required for the business logic used by
Update initial call trigger
/transactions/get webhooks, the
SYNC_UPDATES_AVAILABLE webhook will not be fired for an Item unless
/transactions/sync has been called at least once for that Item. For this reason, you must call
/transactions/sync at least once before any sync webhook is received. After that point, rely on the
/transactions/sync will not return the
PRODUCT_NOT_READY error if transactions data is not yet ready when
/transactions/sync is first called. Instead, you will receive a response with no transactions and a null cursor. Even if no transactions data is available, this call will still initialize the
SYNC_UPDATES_AVAILABLE webhook, and it will fire once data becomes available.
The first call to
/transactions/sync once historical updates are available will often have substantially higher latency (up to 8x) than the equivalent call in a
/transactions/get-based implementation. Depending on your application's logic, you may need to adjust user-facing messaging or hard-coded timeout settings.
Update transaction reconciliation logic
The response to
/transactions/sync includes the patches you will need to apply in the
modified arrays within its response. You should apply these to your transactions records. Any additional logic required to fetch or reconcile transactions data can be removed.
Test your integration
You can perform basic testing of your integration's business logic in Sandbox, using the
/sandbox/item/fire_webhook endpoint to simulate
SYNC_UPDATES_AVAILABLE. If this testing succeeds, you should then test your integration with internal test accounts in Development or Production before releasing it to your full Production userbase.