On initial sync, call /transactions/sync with the access_token and no cursor; receive added[], modified[], removed[], and a next_cursor; persist the cursor per item in your database
If has_more is true in the response, immediately call /transactions/sync again with the returned next_cursor; continue until has_more is false — all pages must be consumed before the cursor advances to the final stable state
Register a webhook URL on the Plaid item; listen for SYNC_UPDATES_AVAILABLE (transactions.sync_updates_available) with webhook_type=TRANSACTIONS — this fires when new data is ready
On receiving the webhook, call /transactions/sync with the stored cursor to fetch only the delta; apply added to insert, modified to upsert, and removed to soft-delete by transaction_id
Handle the TRANSACTIONS_REMOVED webhook separately if using legacy mode; in sync mode, removals appear in the removed[] array of /transactions/sync
Store the raw transaction objects including personal_finance_category (PFC v2) and counterparty fields for downstream categorization
Known gotchas
Never discard a cursor mid-pagination — if you stop consuming pages partway through, the cursor is in an intermediate state and subsequent calls will re-replay data; always paginate to has_more=false before persisting
The SYNC_UPDATES_AVAILABLE webhook may fire multiple times in rapid succession for the same item; deduplicate by checking whether your stored cursor has already advanced past the data referenced in the webhook before re-calling the API
Transactions can be modified or removed days after they first appear (pending-to-posted transitions, bank corrections); your data model must support upsert on transaction_id and logical deletion, not just append
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp