For Plaid integration, your Sure instance needs to be accessible from the internet behind a domain with working SSL. See additional context in maybe-finance/maybe#2419.
Prerequisites
Before setting up Plaid:- Your Sure instance must be publicly accessible via HTTPS
- You need a valid domain with working SSL certificate
- You must be comfortable with technical configuration
- You should review Plaid’s terms of service for personal use
Creating a Plaid account
- Go to dashboard.plaid.com and register for a new account
- Complete the registration process
- Request production access based on your bank type (see below)
Requesting production access
The process differs depending on whether your bank requires OAuth authentication.For banks without OAuth
- On the Home page, find “Learn how to build with Plaid” and click Unlock real data
- Enter your real name and phone number
- In the description box, write:
This is for personal use only on a self-hosted version of the Sure Finance software. I am only using it to manage my finances, sync my bank accounts, track my spending, and create a budget.
- Leave “Additional products” unchecked
- Click Request Access
- Wait for approval (may take more than 24 hours)
For banks with OAuth
Per Plaid Support as of July 2025, certain banks have extended OAuth approval timelines:
- Chase Bank: 3-4 months
- Schwab: Up to 2 months
- In the left sidebar, click Get production access
- Enter your real address
- For business profile, write:
This is for personal use only on a self-hosted version of the Sure Finance software. I am only using it to manage my finances, sync my bank accounts, track my spending, and create a budget.
- Leave company website blank
- Enter your real name, phone number, email, and date of birth
- Click Next
- Indicate:
- 0 employees
- Your country of data access
- You do not sell data
- No security breach in past 12 months
- Click Next
- Select industry: Budgeting and financial management tools
- Click Next
- Enter any name for your application
- Upload a logo (1024x1024px, under 4MB)
- Leave brand color as #22CCEE
- Set Website URL to:
https://github.com/we-promise/sure - In “Reason for data access”, enter:
This is for personal use only on a self-hosted version of the Sure Finance software. I am only using it to manage my finances, sync my bank accounts, track my spending, and create a budget.
- Enter your real email as support email
- Click Next
- Enter your country for “Where do you want to launch?”
- For products:
- Payments: Check only Auth and Balance
- Credit Underwriting: Leave all unchecked
- Fraud & Compliance: Leave all unchecked
- Financial Management: Check all products
- Click Next
- For use cases:
- Payments: Select Consumer bill pay
- Financial Management: Select Personal budgeting and financial advice for all products
- Click Next
- Select Pay As You Go plan
- Click Next
- Enter billing details and check agreement boxes
- Click Next
- Click Start Security Practices Questionnaire
- For each question:
- Select Other - please see comments
- Write in notes:
This is for personal use only on a self-hosted version of the Sure Finance software. I am only using it to manage my finances, sync my bank accounts, track my spending, and create a budget.
- Continue through all sections, repeating step 28
- Click Submit
- Wait for approval (may take more than 24 hours)
Configuring Sure
After your Plaid account is approved:- Go to dashboard.plaid.com/developers/api or click Developers > API
- Click Configure next to Allowed redirect URIs
- Click Add new URI
- Enter your domain with
/accountsappended (e.g.,https://budget.yourdomain.com/accounts) - Click Save changes
- Go to dashboard.plaid.com/developers/keys or click Developers > Keys
- Copy your
client_idand Productionsecretkey
Complete Plaid Link customization
After production access is approved, finish the Plaid Link configuration before testing bank connections:- In the Plaid Dashboard, go to Link > Link Customization
- Add Track and manage your finances as a use case
- Publish the changes
Docker Compose configuration
In yourdocker-compose.yml file, add these environment variables:
Environment variables
In your.env file, add:
Restart Sure
After updating your configuration, restart your Sure instance. You should now see the Link account option in the Sure UI.Member-owned connections
By default, only family admins can connect and manage provider integrations. Plaid is an exception: because a Plaid Link session authenticates only the person completing the flow, a family member can safely connect their own bank without exposing any other member’s credentials.Who can connect Plaid
A member who connects a bank can re-authenticate it, sync it, and delete it. They cannot edit or delete connections created by other members or by an admin.
An admin always has full visibility and management over every Plaid connection in the family, regardless of who created it.
What members see on a shared connection
When a member owns a Plaid connection, the connection card shows only the accounts they have access to. Accounts that were shared and later had sharing revoked are no longer shown on that member’s card, even if they remain on the underlying connection. Admins see all accounts on every connection.Moving between families
When a member accepts an invitation to join a different family, their Plaid connections move with them if all of the accounts on that connection belong to the member. Connections that include accounts belonging to other family members stay behind, with ownership released and the connection reverting to admin-managed. If a member is demoted to guest, they lose the ability to manage their Plaid connections. The connections are not deleted, but only an admin can manage them until the member’s role is restored.Duplicate institution warning
When you complete a Plaid Link flow for an institution you already have connected, Sure detects the overlap before creating a second connection and shows a warning dialog. This prevents duplicate connections, which consume a Plaid Item slot that cannot be recovered on the Trial plan even if the duplicate is later removed. Sure compares the accounts Link reported with your existing connections by account name and last-four mask, then offers different actions depending on what it finds.All accounts already connected
If every account in the new Link session matches an existing connection, Sure shows a “Close” button only. Adding the connection would only duplicate accounts already in your family. The dialog points you to alternatives where applicable:- For a US connection you can manage and own (or a legacy connection with no owner), use Add accounts to add more accounts without creating a second connection. Plaid does not support this account-selection flow for UK/EU institutions.
- Go through Link again with a different bank login if you intended to connect a different account at the same institution.
Some accounts are new
If the new session includes both connected and new accounts, Sure offers an update action for eligible US connections you can manage and own (or legacy connections with no owner). Updating adds the new accounts through the existing connection. If the overlap is only with other members’ connections, the dialog leads with Confirm this connection instead. A Confirm this connection option is also available for cases where the overlap is explained by a different login sharing an account (such as a joint account).No accounts match
If none of the reported accounts match an existing connection, Sure treats this as a different login and leads with Confirm this connection. You can still close without adding if you changed your mind.Nothing to compare
When Sure cannot reliably compare accounts — for example, when an account has no last-four mask — it leads with Close. Confirm remains available; update actions appear only for eligible US connections you can manage and own, or legacy connections with no owner.Expired token
The held public token expires after 30 minutes. If you leave the warning dialog open past that point and then try to confirm, Sure redirects to Accounts with an alert asking you to go through Link again.Admin and member behavior
Admins can see the family’s connections in the warning. When every reported account is already connected only through other members, the warning names whose connection holds the accounts and offers Close rather than confirmation. If some accounts are new, confirmation remains available. Matches narrow the listed connections to those holding matching accounts; when there are no matches or comparison is unavailable, the dialog lists the institution’s existing connections. Members see only their own connections in the warning.Managing accounts
Adding accounts to an existing connection
If you have an existing US Plaid connection and want to add more accounts from the same institution, you do not need to create a new connection.- Go to Settings > Providers and find your Plaid connection
- Click Add accounts next to the connection
- The Plaid Link flow opens with account selection enabled
- Select the additional accounts you want to add
- Complete the flow — Sure will sync the new accounts automatically
Linking an unlinked Plaid account to an existing Sure account
If you have a Plaid account that is not yet linked to any Sure account, you can connect it to an existing account rather than creating a new one.- Go to Settings > Providers and find the account you want to link
- Open the account menu and choose the option to link to a Plaid account
- A dialog lists all unlinked Plaid accounts available in your family
- Select the Plaid account and click Link account
How Sure selects Plaid products
When you initiate a Plaid Link flow, Sure requests a specific set of Plaid products based on the type of account you are linking. Plaid filters out any institution that does not support every product in the requested set, so the product selection directly controls which institutions appear in the Link UI.
Because
liabilities is only requested when linking a liability account (credit card or loan), investment-only institutions such as E*TRADE that do not offer Plaid’s liabilities product are now visible when you link an investment account. Previously, requesting liabilities for every account type caused those institutions to be silently hidden in the Link flow.
Sure fetches liability details (minimum payment, next payment due date, APR) for all Plaid accounts with type credit, regardless of subtype. This covers both standard credit cards (credit/credit card) and PayPal Credit accounts (credit/paypal). For loan accounts, liabilities are fetched only for mortgage and student subtypes.
Plaid reports an item’s products across three lists: available_products, billed_products, and consented_products. Sure treats all three as supported. Products granted through additional_consented_products during the Link flow appear in consented_products until they are first billed — if Sure only checked the first two lists, those products would appear unsupported and their data would not be fetched.
Transaction names
Plaid returns both a cleaned merchant name and the bank’s original description. Sure combines them into a single transaction name — for example,Target - TARGET 00023 SAN MATEO CA — so distinct transactions from the same merchant stay distinguishable. If Plaid resolves no merchant, the bank’s description is used on its own.
Merchant records, logos, and reports are still built from the merchant name alone, so grouping and reporting are unaffected by the combined display name.
Rules and combined names
Rules using contains (like) automatically reach both parts of the combined name, so a rule matching “Target” still catches all Target transactions.
Rules using is (=) or is not (!=) continue to match on the merchant name alone, so an existing = "Target" rule keeps working without any changes. This applies only to Plaid transactions — manually entered transactions are not affected.
Transaction details
The transaction detail drawer shows Plaid-specific metadata under Additional details when Plaid reports it. This can include:- Original description — the bank’s own description before Plaid cleaned it
- Payment channel — how the transaction was made (in-store, online, etc.)
- Transaction code — Plaid’s payment type code
- Payment meta — reference numbers and other payment metadata
- Counterparties — merchant or financial institution details
Features
- US bank coverage: Comprehensive support for US financial institutions
- Real-time data: Access to account balances and transactions
- OAuth support: Secure authentication for supported banks
- Multiple accounts: Connect accounts from different institutions
- Investment-only institutions: Brokerages that do not offer liabilities (such as E*TRADE) can be linked as investment accounts
- Full credit liability support: Liability data (minimum payment, due date, APR) is fetched for all Plaid
creditaccount types, including PayPal Credit (credit/paypal) in addition to standard credit cards (credit/credit card)
Pricing
Plaid uses a pay-as-you-go pricing model. Check plaid.com/pricing for current rates.Limitations
- US-focused: Primarily supports US institutions, not available for European users
- Complex setup: Requires significant technical configuration
- TOS concerns: Personal use may violate Plaid’s terms of service
- Public accessibility: Requires publicly accessible HTTPS endpoint
- Long approval times: OAuth-enabled banks can take months to approve
- Technical expertise: Not recommended for non-technical users
Alternatives
Consider these alternatives to Plaid:- SimpleFIN: Simpler setup, more affordable, US-focused
- Enable Banking: Free, EU-focused, easier setup
- Lunch Flow: Global coverage, paid service
Transaction refresh behavior
Sure requests a fresh transaction pull from Plaid before reading new data in several situations, not only during manual syncs. The refresh is asynchronous: Sure sends a refresh request to Plaid, then polls for an updated transaction cursor, then triggers a follow-up sync once the cursor advances.When automatic refreshes run
A transaction refresh is requested automatically in the following cases:- Scheduled sync — the nightly background job that syncs all families
- Provider-wide sync — triggered when you sync all accounts from Settings or the accounts page
- Login sync — when auto-sync on login is enabled and Sure detects a family has not synced today
Manual sync behavior
Manual syncs also request a transaction refresh before fetching data. After sending the refresh request, Sure polls Plaid for the updated cursor and syncs once new data arrives. If no new transactions appear within the polling window (roughly 3 minutes), Sure falls back to a normal sync with whatever data Plaid currently has.Coalescing and the cache store requirement
To prevent duplicate refresh requests, Sure uses a shared cache to coalesce calls: if a refresh has already been requested for a given Plaid item within the last 5 minutes, subsequent requests are dropped and the in-progress refresh continues normally. The coalescing logic requires a shared cache store. Sure skips the Plaid refresh request (and logs a warning) if the cache store is the default file-based or in-memory store. To enable refresh on a self-hosted instance, configure one of the following:- Redis — set
REDIS_URLto a Redis connection string - Memcache — configure
MEMCACHE_SERVERS - SolidCache — enabled by default in the Docker Compose setup
Reconnect status
When Plaid requires you to re-authenticate (for example, after a password change), Sure marks the connection with a “requires update” warning. Clicking the Update button in Settings > Providers opens the Plaid Link re-authentication flow. After you complete re-authentication, the warning is not cleared immediately. Sure clears the “requires update” status only after the next full import succeeds. This means the warning may persist briefly after you reconnect — it disappears once the subsequent sync completes without a login error. If the login issue is still present, the status remains until authentication succeeds and a full import runs cleanly.Troubleshooting
If you run into Plaid errors that are not visible in Sure, check the Plaid Dashboard logs under Developers > Logs. These logs can show whether the issue is coming from Plaid Link configuration, product approval, institution support, or another Plaid-side validation error.Investment account shows unexpected cash balance after a sync
If a Plaid investment account shows a cash balance that grows or fluctuates each day even though you have not made any cash changes, one possible cause is a balance snapshot anchored on a different date from its holdings. Plaid can report an institution price date for each holding, which may be from an earlier trading session. When that total was anchored on today’s date instead, repricing the holdings for today left a gap that appeared as phantom cash. Sure now anchors the balance snapshot on the newest valid holding price date that is not in the future. Future dates are discarded individually; if no eligible date remains, Sure uses today. This reduces date-mismatch artifacts without assuming every holding has the same price date. Trigger a manual sync from the account page to pick up the corrected snapshot.Credit card or loan shows no transactions after linking
If you linked a credit card or loan account through Plaid and Sure imported balances and liabilities but no transactions, the connection was affected by a bug that is now fixed. Plaid places thetransactions product in consented_products for liability accounts until the first billing call — Sure previously only checked available_products and billed_products, so transactions appeared unsupported and the fetch was skipped.
To resolve this, trigger a manual sync from the account page. Sure will now recognize transactions as a supported product and import your transaction history.
Retracted transactions not removed
When Plaid removes a transaction (for example, a pending transaction that never settled, or a duplicate Plaid later corrects), Sure deletes the matching entry from your account during the next sync. Entries imported before theProviderImportAdapter was introduced were stored with a plaid_id field, and Sure used that field to find and delete retracted transactions. Entries imported after the adapter was introduced are stored with an external_id and a source identifier instead, leaving plaid_id empty. Because of this, retractions that targeted the newer entries were never matched and the transactions stayed in the account.
This is now fixed. Sure looks up retracted transactions by external_id and source first, then falls back to plaid_id for older entries that predate the adapter. If you have transactions that should have been removed by a Plaid retraction, trigger a manual sync from the account page — Sure will process any pending removals during that sync.
Investment holdings not syncing with encryption enabled
If your Sure instance has Active Record encryption configured and Plaid investment account syncs are failing with aNoMethodError, you were affected by a bug that is now fixed.
The raw_holdings_payload column was previously named raw_investments_payload. An invalid previous: fallback option on the encryption declaration caused ActiveRecord::Encryption::Context#attribute= to raise NoMethodError when Sure tried to decrypt holdings data using the previous scheme. The column rename preserves the stored ciphertext, and Active Record Encryption does not bind ciphertext to the attribute name, so no fallback scheme was needed.
Update to the latest Sure version and trigger a manual sync from the account page. Holdings will decrypt and sync correctly after the update.
Link modal closes with no error message
If the Plaid Link modal closes immediately when you try to open it — before any bank selection screen appears — and Sure shows no error message, a link-token creation error may be the cause. This can happen when your Plaid credentials are misconfigured, a required product is not enabled for your account, or your institution is not available in your region. Sure now shows the error as a page-level alert instead of silently closing the modal. If you see a message such as “Your account is not enabled for the following products” or a similar Plaid configuration error, follow the instructions in that message to resolve the issue in your Plaid Dashboard. If the alert is a generic connection error with no specific guidance, verify that yourPLAID_CLIENT_ID, PLAID_SECRET, and PLAID_ENV values are correct and that your Sure instance is reachable over HTTPS. Check Developers > Logs in the Plaid Dashboard for more detail on what failed.
Link popup closes after selecting a bank
If the Plaid popup closes immediately after you select a bank, and Sure shows no useful app logs, the problem may be on Plaid’s side rather than in your Sure configuration. Things to verify first:- Your instance is publicly reachable over HTTPS
- Your allowed redirect URI is set correctly in Plaid, for example
https://budget.yourdomain.com/accounts PLAID_ENV=productionwhen using Limited or Full Production access- Your
PLAID_CLIENT_IDandPLAID_SECRETare the Production credentials, not Sandbox keys
- Your Plaid environment and access tier (for example, Limited Production)
- The institution you are trying to connect (especially if it is Chase or another OAuth-heavy institution)
- Confirmation that /link/token/create succeeds (can be verified in the Activity section of your Plaid Dashboard)
- Confirmation that your redirect URI is configured correctly
- A note that the Link popup closes without completing the connection
- A request for them to verify or reprocess your client registration / onboarding