Intuit Bank Feeds
Setting up an Intuit Bank Feeds Workflow with Rutter
Introduction
Rutter API enables you to get listed as a financial institution in the Intuit ecosystem. This allows your customers to sync bank or credit card transactions from the accounts they hold with you into their Intuit systems, enabling easy, automated reconciliaton and financial automation.
With a single implementation, you gain access to the following Intuit platforms:
- QuickBooks Online
- QuickBooks Desktop
- Quicken
- Credit Karma
No additional development work is required to support each individual Intuit product.
The workflow involves three main steps:
- Get listed as a financial institution within Intuit's ecosystem.
- Onboard your customers within their Intuit products to establish a connection between their bank or card account and their Intuit instance.
- Continuously sync transaction data into Rutter's systems to enable your customers to pull it into their Intuit products.
End User Setup Process
Here's an example of the setup flow within QuickBooks Online.
Or, see an example of the setup flow in Quicken.
Platform Setup
Data Sync Configuration
Make sure to include these Rutter Objects in your Data Sync Configuration through the Rutter dashboard.
- Bank Feed Account
- Bank Feed Transaction
Get listed as a bank within Intuit's ecosystem
When your customer wants to set up a Bank Feed between their Intuit instance (QuickBooks Online, QuickBooks Desktop, Quicken, or Credit Karma) and their bank account, they will need to select you from a list of financial institutions within Intuit's "Link Account" flow.
To get listed, please contact your Rutter customer support representative.
Prerequisites
In order to proceed, you will need to create two Rutter organizations, one for production and one for staging/testing. This allows you to better separate those environments, as well as allowing Intuit to create separate staging and production banks for your use. Your Rutter staging environment will connect to your Intuit test bank, and your production environment will connect to your official listing with Intuit.
To set up your second Rutter instance, just head to Rutter's Sign up page. You'll need to use a different email than on your primary Rutter organization. For example, if you used john.doe@rutterapi.com
to sign up for your primary Rutter organization, you could create a new staging organization using the email john.doe+staging@rutterapi.com
.
Once done, reach out to your Rutter Success Manager to guide you through the rest of the process.
There is also one prerequisite setting for your end users. For QuickBooks accounts where the primary currency is not USD, multicurrency must be enabled in order to use Bank Feeds. To turn on multicurrency, follow Intuit's guide.
Implementation Steps
Redirect Customers to Your Login Flow
Step 1: Provide a Redirect URL to Rutter
You need to supply Rutter with a redirect URL that points to a user-facing login page on your platform (e.g., my-website.com/login
). This URL should be a webpage, not an API endpoint.
To supply Rutter with this URL, in your Rutter Dashboard, head to Platforms > Bank Feeds > Intuit Bank Feeds. Then click "Configure".
Please note: this webpage must not have a Cross-Origin-Opener-Policy header set, as this blocks Intuit's ability to maintain state during the login flow.
Step 2: Rutter Redirects to Your Login URL
When your customer attempts to connect within any Intuit product (QuickBooks Online, QuickBooks Desktop, Quicken, or Credit Karma), Rutter will redirect them to the login URL you provided (e.g., my-website.com/login
). This will appear as a pop-up screen within the Intuit interface.
Step 3: Handling the Redirect URI
When Rutter redirects to the login URL you provide, Rutter will append a redirect_uri
parameter to the login URL. After your customer successfully logs in, you will need to redirect to this URL.
For example, if your login URL is my-website.com/login
, Rutter would redirect your user to that URL to log in, and append query parameters to it like this: my-website.com/login?challenge=f0208784-584e-4419-be3e-f34a743a9904&redirect_uri=https://link.rutterapi.com/ibf_redirect?challenge=f0208784-584e-4419-be3e-f34a743a9904
Appended to Rutter's redirect_uri
is a challenge
parameter. You do not need to store or use the challenge
parameter beyond passing it back to Rutter as part of the redirect URI. The challenge
parameter uniquely identifies the connection between your customer's Intuit account and Rutter. The redirect URI and associated challenge expire after 10 minutes.
For additional security, we recommend you implement validation on your side to ensure the redirect_uri
belongs to the domain link.rutterapi.com
.
Alternatively, for a more secure option, you can use the redirect_uri
returned as part of the POST /bank_feeds/otp response (see step Enable the Bank Feed Authentication Flow
below.) In this case you will need to temporarily store the challenge
passed from the Rutter redirect, and append this to the redirect_uri
as a query parameter along with the OTP when directing back to Rutter.
Step 4: Customer Login
Your customers will log in through your flow (hosted at, e.g. my-website.com/login
), during which you can handle any two-factor authentication (2FA) or other security requirements.
Please note: Intuit needs to maintain state during the login flow. For this reason, your login flow must use the same domain throughout the process (i.e., do not redirect users from one domain to another during the flow), and must not have a Cross-Origin-Opener-Policy header set.
Rutter does not have visibility into, or requirements for, the specifics of your login flow. All that is needed is for you to redirect to the correct URL with the appropriate parameters after a successful login.
Link a Rutter Intuit Bank Feeds Connection to Your Customer's Intuit Account
After the customer successfully logs in, follow these steps.
Step 1: Create or Retrieve a Rutter IBF Connection
Create a new Intuit Bank Feeds connection (if one does not already exist for this customer) by calling our Create Connection API with this JSON body:
1{
2 "platform": "INTUIT_BANK_FEEDS"
3}
You must track which IBF connections belong to which users on your end. For example, you might maintain a table that maps your customers to Rutter connection IDs:
CUSTOMER_ID | RUTTER_IBF_CONNECTION_ID |
---|---|
123 | abcd-1234-qwerz-5678 |
- If a connection already exists, move to the next step.
Use the access token returned from the API to make the API requests in the next several steps.
1{
2 "connection": {
3 "id": "00000000-0000-0000-0000-000000000000",
4 "access_token": "00000000-0000-0000-0000-000000000000",
5 "link_url": "https://link.rutterapi.com/connection/00000000-0000-0000-0000-000000000000",
6 "name": "Example Connection"
7 }
8}
Step 2: Create Bank Feed Accounts
Use Rutter's POST /bank_feeds/accounts API endpoint to supply the bank accounts your customer would like to set up with a Bank Feed. Your customer will be able to select any of the accounts you supply through this endpoint during the Intuit Bank Feed authentication flow.
1{
2 "bank_feed_account": {
3 "account_id": "00000000-0000-0000-0000-000000000000",
4 "internal_bank_account_id": "0674101002388",
5 "parent_bank_feed_account_id": "00000000-0000-0000-0000-000000000000",
6 "transaction_start_date": "2023-02-02T00:00:00.000Z",
7 "bank_account_type": "bank",
8 "currency_code": "USD",
9 "name": "Regan's Bank Account",
10 "available_balance": 1546.23,
11 "bank_account_number": "182237382",
12 "current_balance": 1833.21,
13 "line_of_business": "small business",
14 "routing_number": "123456789",
15 "additional_fields": {
16 "override_existing": true
17 }
18 }
19}
1{
2 "bank_feed_account": {
3 "id": "00000000-0000-0000-0000-000000000000",
4 "account_id": "00000000-0000-0000-0000-000000000000",
5 "internal_bank_account_id": "0674101002388",
6 "parent_bank_feed_account_id": "00000000-0000-0000-0000-000000000000",
7 "last_statement_date": null,
8 "next_payment_date": null,
9 "transaction_start_date": "2023-02-02T00:00:00.000Z",
10 "bank_account_type": "bank",
11 "feed_status": "inactive",
12 "available_balance": 1546.23,
13 "available_credit": null,
14 "bank_account_number": "182237382",
15 "credit_limit": null,
16 "currency_code": "USD",
17 "current_balance": 1833.21,
18 "finance_charges": null,
19 "last_statement_balance": null,
20 "line_of_business": "small business",
21 "minimum_payment_amount": null,
22 "name": "Regan's Bank Account",
23 "next_payment_amount": null,
24 "past_due_amount": null,
25 "purchases_apr": null,
26 "routing_number": "123456789",
27 "last_synced_at": "2023-01-02T02:34:56.000Z",
28 // ...
29 }
30 }
Step 3: Sync Bank Feed Transaction Data
Once you've created the user's bank feed accounts, you should immediately sync historical transaction data using the POST /bank_feeds/transactions API. Syncing the transactions immediately after account creation ensures the transactions will be ready for your users once they finish the linking flow.
For the initial call to POST /bank_feeds/transactions, Intuit's recommendation is to send over 3 months to a maximum of 2 years of historical transactions. Note that for Intuit, a maximum of 1000 transactions can be sent over in each request. If you have more than 1000 transactions to send over, you should batch 1000 transactions at a time.
Sending Over Transactions
For accounts with large amounts of transactions, it may take some time to finish syncing these to Rutter. To prevent incomplete data from appearing in your customer's Intuit product, you must wait until all transactions are successfully sent to Rutter before proceeding to the redirect in step 4. Consider implementing a loading screen or progress indicator during this process to keep users informed while transactions are being synced.
If you plan to build out multiple bank feed integrations, we recommend that your code checks the authentication status of a Bank Feed Account before syncing transaction data by calling GET /bank_feeds/accounts API, and checking for "transaction_ready": true
. For Intuit, this will always be true
as soon as the bank feed account is successfully created. However, having your code check for "transaction_ready": true
before sending over transactions ensures cross-platform compatibility if you build out additional bank feed integrations with Rutter, as some integrations may have additional action needed before transactions can be synced.
The "feed_status"
field will be "inactive"
until the user completes the authentication flow and Intuit has begun syncing transactions for this account from Rutter.
1{
2 "bank_feed_account": {
3 "id": "00000000-0000-0000-0000-000000000000",
4 "account_id": "00000000-0000-0000-0000-000000000000",
5 "internal_bank_account_id": "0674101002388",
6 "parent_bank_feed_account_id": "00000000-0000-0000-0000-000000000000",
7 "transaction_start_date": "2023-02-02T00:00:00.000Z",
8 "bank_account_type": "bank",
9 "transaction_ready": "true",
10 "feed_status": "active",
11 // ...
12 }
13 }
After the initial sync is complete, you should sync all posted transactions in real time. Do not send non-posted transactions, as there is a higher chance of them changing and negatively impacting your customers' reconciliation process.
When syncing transactions, the balance on the account in Intuit will only be updated if:
- the
current_balance
field is provided - transactions are provided in the request
- at least one transaction is more recent than the previously posted batch of transactions
If any of these criteria are not met, the account balance will not be updated automatically.
A Note on Transaction Limits
For Intuit, a maximum of 1000 transactions can be sent over in each request. If you have more than 1000 transactions to send over, you should batch 1000 transactions at a time.
1{
2 "bank_feed_transactions": {
3 "bank_feed_account_id": "00000000-0000-0000-0000-000000000000",
4 "current_balance": 1234.56,
5 "transactions": [
6 {
7 "transaction_id": "ACRAF23DB3C4",
8 "posted_at": "2023-02-02T02:34:56.000Z",
9 "transaction_date": "2023-02-02T02:34:56.000Z",
10 "amount": -300,
11 "description": "Office supplies",
12 "memo": "Staples",
13 "transaction_type": "debit",
14 "debit_credit_memo": "DEBIT",
15 }
16 ]
17 }
18 }
If the Bank Feed Transaction input is valid, transactions will be synced to the accounting system the next time the end user requests updated transactions for this account in their Intuit product by opening the bank account's feed page.
If
response_mode=async
is specified in the request, the response will include a job ID which can be used to check the status of the POST request using Fetch a Job API. If the job completes successfully, your input was valid and the response will show transactions withplatform_ingested: false
, meaning the transactions have not yet been ingested by Intuit (thus will not yet appear in the accounting instance). You can check theplatform_ingested
status of the transactions through GET /bank_feeds/transactions to confirm whether the transactions have synced into the accounting instance or not. If a Bank Feed Account isfeed_status: active
, thelast_synced_at
corresponds with the last time Intuit synced transactions for this account.Note: 255 characters is the length limit for the
description
field on Bank Feed Transactions. This field maps to the Bank Detail field in QuickBooks.
If the job fails, you should retry the POST request after fixing the error described in the job response.
Step 4: Enable the Bank Feed Authentication Flow
After completing the steps above to create bank accounts and sync transaction data to them, finish redirecting to the Rutter-provided redirect URL. To authenticate the connection, you'll need to generate an OTP and append that to the redirect URL as an additional parameter. The redirect URL already includes a challenge ID as a query parameter. All you need to do is add one more query parameter with the OTP (&otp=OTP_GOES_HERE
). For example:
1https://link.rutterapi.com/ibf_redirect?challenge=f0208784-584e-4419-be3e-f34a743a9904&otp=123456789
The OTP should not be displayed to the user. It is passed back to Rutter so Rutter can link the correct user's Intuit account to the correct Rutter connection.
To generate the OTP, use Rutter's POST /bank_feeds/otp API. This endpoint will also return a redirect_uri
which can be used in place of the original redirect_uri
passed from Rutter. Note that if the redirect_uri
from the POST /bank_feeds_otp response is used, the challenge
passed from Rutter will need to be appended as a query parameter.
1{
2 "bank_feed_otp": {
3 "expires_at": "2023-01-10T00:00:00.000Z",
4 "otp": "00000000-0000-0000-0000-000000000000"
5 }
6}
Once you redirect to Rutter, your customer will be able to finish linking their bank accounts within their Intuit product (QuickBooks Online, QuickBooks Desktop, Quicken, or Credit Karma).
Cross-Platform Compatibility
An important advantage of Rutter's Intuit Bank Feeds implementation is that a single connection works across the following Intuit platforms:
- QuickBooks Online
- QuickBooks Desktop
- Quicken
- Credit Karma
This means:
- No additional development work is required to support each individual platform
- Connections are shared between platforms—a customer can access their transactions in multiple products via a single Rutter connection
- Your customers can access their bank feeds from any Intuit product they use
Transaction ID Requirements and Duplicate Handling
Unique Transaction IDs Across All Accounts
Important: Transaction IDs must be unique across all bank feed accounts within a single Rutter connection, not just within individual accounts. This is an Intuit requirement.
For example, if you:
- Send a transaction with
transaction_id: "1"
forbank_feed_account_id: "12345"
- Later send another transaction with
transaction_id: "1"
forbank_feed_account_id: "67890"
The second transaction will be marked as a duplicate (is_duplicate: true
) and will not be persisted, even if the transaction details are completely different. Additionally, the bank_feed_account_id
field returned in the response for the second transaction will be set to the original account ID ("12345"
).
Duplicate Transaction Behavior
When a duplicate transaction ID is detected:
- The API will return a
200
status code - The response will include
is_duplicate: true
- The response will reference the original bank feed account where the transaction ID was first used
- The duplicate transaction will not be saved or synced to Intuit
This means that if you submit transactions with the same ID but different details, only the first transaction will be preserved, potentially causing silent data loss.
Best Practices
To avoid issues with duplicate transaction IDs:
- Always check the
is_duplicate
field in API responses when creating bank feed transactions - Use globally unique transaction IDs across all accounts for a customer (e.g., include account identifier in the transaction ID)
- Implement proper error handling for duplicate responses to ensure data integrity
- Monitor for missing transactions that may result from unintentional ID conflicts
Preventing Silent Data Loss
Since duplicate transactions return a successful HTTP status but are not actually persisted, always verify the is_duplicate
field in your API responses. Consider implementing logging or alerts when duplicates are detected to identify potential data synchronization issues.
Timezone Handling
When sending transactions to Rutter, the transaction_date
should be in UTC. When QuickBooks pulls those transactions from Rutter, it adjusts the time to match the timezone of the company's address in QuickBooks, not the user’s local browser time.
For example, if the company address is in San Francisco, all transactions will show in the timezone America/Pacific Time, no matter where the user is located.
In QuickBooks, the Company Address can be found by going to Settings -> Account and settings -> Company.
How QuickBooks Determines Timezone
QuickBooks sets the company’s timezone based on:
- Setup Info: During company setup, users provide location details (like country/region), which set defaults like currency, date formats, and tax rules.
- Regional Versions: QuickBooks offers region-specific versions (e.g., US, Canada, UK), which apply local settings by default.
- User Input: Users may be asked again to confirm or update regional details when entering financial or tax data.
Make sure the correct region is set in QuickBooks to ensure proper timezone handling and compliance with local regulations.
Disconnection Handling
Disconnection Behavior
Customers can disconnect bank feed accounts at any time within any Intuit product.
When an account is disconnected:
- The account remains visible in the Intuit product's chart of accounts
- New transactions can no longer sync to the account
- Other connected Rutter bank feed accounts for the same customer are not affected
- The Rutter bank feed connection stays active
- No webhook or notification is sent to indicate the disconnection, as this information is not available via Intuit's API
If a customer needs to reconnect a disconnected account, they must complete the original linking process again. When this happens, check for an existing Rutter IBF connection for that customer and reuse it rather than creating a new one, as described above.
Note that if a customer reconnects a disconnected account to the same Intuit GL account, Intuit will not re-pull historical transactions. Instead, only transactions going forward will be synced. To re-pull historical transactions, the customer must create a new GL account.
Managing Disconnected Accounts
Since Rutter doesn't receive disconnection notifications from Intuit, you can use the last_synced_at
field to monitor the last time the user synced transactions. Consider implementing automated deletion for connections that haven't synced in 6+ months to manage costs. If you implement this deletion functionality, you may want to warn customers in your product that they'll need to go through the connection process again if they haven't synced transactions in an extended period.
Transaction Syncing Rules
- You must provide at least one transaction per sync request
- Only posted transactions should be submitted.
- Each transaction must have a unique identifier (
transaction_id
). The identifier for a transaction must never change. The same transaction identifier should not occur more than one time for a Bank Feed Account.