

Users connect their bank accounts and credit cards through Plaid Link, an OAuth-based flow embedded directly in the onboarding experience. When a user completes the Link flow, the frontend receives a public_token which is exchanged at the backend exchange endpoint for a persistent access_token stored per user in MongoDB.
The system supports multiple cards per user from the ground up, each connected institution produces its own access_token and item_id. The Connected Accounts page renders all linked cards with institution name, account type, masked card number, and live connection status.
When a Plaid Item expires or a bank forces re-authentication, the system catches the error code from Plaid's API response and surfaces a "Reconnect" prompt on both the dashboard attention cards and the Connected Accounts page. A dedicated reconnect endpoint handles re-linking without disrupting previously synced transaction history.
item_id is detected for the user, the system updates the token rather than creating a new record, preserving all historical transaction data.



Once accounts are linked, the system fetches up to 2 years of transaction history using Plaid's /transactions/sync endpoint, which uses a cursor-based pagination model. Each sync call stores a cursor per linked item in MongoDB, so subsequent syncs only retrieve net-new, modified, or removed transactions — not the full history on every run.
Transactions are stored per user with all relevant fields and served to the Connected Account Details screen in the frontend, which provides a paginated, filterable transaction history view. Users can search by merchant, filter by date range, and drill down per account.
To handle Plaid's per-item API rate limits during periods of high concurrent user activity, the sync was moved to a batched execution model. Transactions are processed in defined batch sizes, and the cron-driven sync jobs are spread across users with staggered scheduling to avoid synchronized spikes in API consumption.
/transactions/recurring/get after initial transaction sync. Plaid analyzes transaction history to detect patterns by merchant, frequency, and amount consistency.The /transactions/recurring/get endpoint returns structured data for each recurring transaction stream, including merchant name, frequency (weekly, monthly, annual), average and last amount, and status — either active or early detection (fewer than 3 occurrences observed).
This data powers the Subscriptions tab, with filters for All, Active, and Cancelled states. The subscription view was designed to surface the distinction between two different types of recurring activity that users often conflate.
Plaid does not natively provide a "paused" or "cancelled" status, it only reflects what it can detect from the raw transaction stream. A subscription that stops charging simply stops appearing with an active next-date prediction.




Email Merchants are entities created automatically when the AI parsing pipeline extracts a merchant name from a refund email. Each record stores the normalized name, aliases, logo URL fetched from logo.dev, and a list of source users — the users whose emails produced this merchant — so reliability can be assessed before linking.
Plaid Merchants are raw merchant names from bank statement data, which typically use abbreviated, bank-statement-style formats that differ significantly from the brand name a user would recognize.
The matching engine runs an extensive string and fuzzy match algorithm combining exact match, tokenized partial match, and Levenshtein distance scoring with a final confidence value. This runs automatically every 24 hours to pick up new merchant data from fresh syncs, and can also be triggered manually on demand from the admin portal.
Once a Plaid merchant is linked to an email merchant, the system uses the pre-built alias map for all future transaction matching — eliminating the need for a Gemini AI call to resolve the merchant name at runtime. In production load testing, this resulted in a 90.3% DB match rate, meaning only 9.7% of merchant lookups required AI fallback.

