Home About Who We Are Team Services Startups Businesses Enterprise Case Studies Blog Guides Contact Connect with Us
Back to Guides
Finance 17 min read

How to Connect QuickBooks to OpenClaw: Bookkeeping AI Agent

How to Connect QuickBooks to OpenClaw: Bookkeeping AI Agent

QuickBooks is where your money lives. OpenClaw is where your AI agent lives. Connecting the two means your agent can pull invoices, flag overdue payments, categorize expenses, and generate financial summaries without you logging into QuickBooks once.

The catch: QuickBooks uses OAuth 2.0 for authentication, which is more involved than the API key approach you might know from HubSpot or Slack integrations. You need to create a developer app on Intuit’s portal, handle an authorization redirect, exchange codes for tokens, and manage token refresh since access tokens expire every 60 minutes. This guide walks through every step. If OpenClaw is already running on your machine, expect about 30 to 40 minutes for the full setup.


What This Integration Does

Once connected, your OpenClaw agent becomes a conversational interface to QuickBooks Online. You message the agent in Telegram, WhatsApp, or Slack and it handles the API calls.

Practical examples of what this enables:

  • Invoice lookups: “Show me all unpaid invoices over $1,000”
  • Expense queries: “What did we spend on software subscriptions last month?”
  • Overdue payment alerts: A daily heartbeat that flags invoices past their due date
  • Financial snapshots: “Pull the profit and loss report for Q1”
  • Customer and vendor management: “Create an invoice for Acme Corp, 10 hours of consulting at $200/hr, net 30”

The agent calls the QuickBooks Online REST API (v3) directly. No third-party middleware or paid connector. Data flows between your machine, Intuit’s servers, and your AI model provider.


Before You Start

You need three things before connecting QuickBooks to OpenClaw:

  1. OpenClaw installed and running. If you have not set it up yet, follow our OpenClaw setup guide. That guide covers installation, workspace configuration, memory, and Telegram setup.

  2. A QuickBooks Online account. Any plan works for API access: Simple Start, Essentials, Plus, or Advanced. Intuit provides OAuth 2.0 access on all tiers. If you want to test without touching live data, you can use the sandbox company that comes with your Intuit developer account.

  3. A text editor for writing the skill file. VS Code, Cursor, or anything that handles Markdown.

One important difference from our HubSpot integration guide: HubSpot uses a Private App token (a static string you paste into .env). QuickBooks uses OAuth 2.0 with short-lived access tokens and refresh tokens. This means more setup upfront, but the security model is stronger.


Step 1: Create a QuickBooks Developer App

Register on the Intuit Developer Portal

Go to developer.intuit.com and sign in with your Intuit account. If you do not have a developer account, create one. It is free and separate from your QuickBooks subscription.

Once logged in, you land on the Dashboard. This is where you manage your apps and sandbox companies.

Create the App and Set Scopes

  1. Click Create an app on the Dashboard
  2. Select QuickBooks Online and Payments as the platform
  3. Name the app something descriptive: OpenClaw Bookkeeping Agent
  4. Under Scopes, select:
ScopeWhat It Enables
com.intuit.quickbooks.accountingFull read/write access to invoices, bills, expenses, customers, vendors, accounts, reports
com.intuit.quickbooks.paymentPayment processing (optional, add only if you need it)

The accounting scope is the only one required. It covers every endpoint we use in this guide. Skip the payment scope unless you plan to process payments through the API.

  1. Click Create app

Configure the Redirect URI

After creating the app, go to Keys & OAuth in the left sidebar.

You need a redirect URI where Intuit sends the authorization code after the user approves access. For local development, use:

https://developer.intuit.com/v2/OAuth2Playground/RedirectUrl

This is Intuit’s built-in OAuth Playground redirect. It works for initial token generation. Later, if you build a web-based token management flow, you can add your own URI.

Copy Your Credentials

On the Keys & OAuth page, you will find:

  • Client ID: A long alphanumeric string
  • Client Secret: Shown once when you create the app; copy it immediately

Store both in your .env file:

# ~/.env or ~/openclaw/.env
QBO_CLIENT_ID=ABc123xYz456...
QBO_CLIENT_SECRET=dEf789gHi012...
QBO_REDIRECT_URI=https://developer.intuit.com/v2/OAuth2Playground/RedirectUrl

Do not paste these into your skill file or any workspace document. Environment variables only.


Step 2: Complete the OAuth 2.0 Flow

This is the part that trips people up. QuickBooks OAuth requires a browser-based authorization step before you can make API calls. You do it once, then your refresh token keeps things working for 100 days.

Build the Authorization URL

Construct this URL and open it in your browser:

https://appcenter.intuit.com/connect/oauth2?client_id=YOUR_CLIENT_ID&response_type=code&scope=com.intuit.quickbooks.accounting&redirect_uri=YOUR_REDIRECT_URI&state=randomstring123

Replace YOUR_CLIENT_ID and YOUR_REDIRECT_URI with the values from Step 1. The state parameter can be any random string; it prevents CSRF attacks.

When you open this URL, Intuit shows a consent screen asking you to authorize the app. Select your QuickBooks company and click Connect.

Intuit redirects you to your redirect URI with two parameters in the URL:

  • code — the authorization code (valid for about 10 minutes)
  • realmId — your QuickBooks company ID (you will need this for every API call)

Copy both values immediately.

Exchange the Code for Tokens

Run this curl command to exchange the authorization code for access and refresh tokens:

curl -X POST "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer" \
  -H "Accept: application/json" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "$QBO_CLIENT_ID:$QBO_CLIENT_SECRET" \
  -d "grant_type=authorization_code&code=YOUR_AUTH_CODE&redirect_uri=$QBO_REDIRECT_URI"

A critical detail: the token endpoint expects application/x-www-form-urlencoded body data, not JSON and not query parameters. We lost an hour debugging this on our first QuickBooks integration. If you send JSON, you get a cryptic invalid_request error with no useful message. The error response does not tell you the content type is wrong.

The response contains:

{
  "access_token": "eyJhbGciOi...",
  "refresh_token": "Q011546...",
  "token_type": "bearer",
  "expires_in": 3600,
  "x_refresh_token_expires_in": 8726400
}

The access token expires in 3,600 seconds (1 hour). The refresh token lasts 8,726,400 seconds (about 100 days).

Store Your Tokens Safely

Add the tokens and realm ID to your .env file:

QBO_ACCESS_TOKEN=eyJhbGciOi...
QBO_REFRESH_TOKEN=Q011546...
QBO_REALM_ID=1234567890

Your .env file now has five QuickBooks variables: Client ID, Client Secret, Redirect URI, Access Token, and Realm ID (plus the Refresh Token). Keep this file outside your OpenClaw workspace directory.


Step 3: Write the OpenClaw QuickBooks Skill

Create the Skill Directory

mkdir -p ~/.openclaw/workspace/skills/quickbooks

Write the SKILL.md File

Create ~/.openclaw/workspace/skills/quickbooks/SKILL.md with this content:

---
name: quickbooks
description: Read and write QuickBooks Online data. Manage invoices, expenses, customers, vendors, bills, and financial reports via the QuickBooks REST API.
tools:
  - shell
---

# QuickBooks Online Skill

## Authentication

Use these environment variables for all API requests:
- QBO_ACCESS_TOKEN — Bearer token for authorization
- QBO_REFRESH_TOKEN — Used to obtain new access tokens
- QBO_CLIENT_ID and QBO_CLIENT_SECRET — App credentials for token refresh
- QBO_REALM_ID — QuickBooks company ID

Base URL for all API calls:
https://quickbooks.api.intuit.com/v3/company/$QBO_REALM_ID

All requests require these headers:
- Authorization: Bearer $QBO_ACCESS_TOKEN
- Accept: application/json
- Content-Type: application/json

## Token Refresh

Access tokens expire every 60 minutes. Before making any API call, check if the token has expired. If you receive a 401 response, refresh the token:

curl -X POST "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "$QBO_CLIENT_ID:$QBO_CLIENT_SECRET" \
  -d "grant_type=refresh_token&refresh_token=$QBO_REFRESH_TOKEN"

Parse the new access_token and refresh_token from the response. Update the .env file with the new values. The refresh token rotates on each use, so always save the latest one.

## Available Operations

### Query Invoices

Find unpaid or overdue invoices:

curl -s -H "Authorization: Bearer $QBO_ACCESS_TOKEN" \
  -H "Accept: application/json" \
  "https://quickbooks.api.intuit.com/v3/company/$QBO_REALM_ID/query?query=SELECT * FROM Invoice WHERE Balance > '0' ORDERBY DueDate" \
  | jq '.QueryResponse.Invoice[] | {id: .Id, customer: .CustomerRef.name, total: .TotalAmt, balance: .Balance, due: .DueDate}'

### Create an Invoice

curl -s -H "Authorization: Bearer $QBO_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -X POST "https://quickbooks.api.intuit.com/v3/company/$QBO_REALM_ID/invoice" \
  -d '{
    "Line": [{
      "Amount": AMOUNT,
      "DetailType": "SalesItemLineDetail",
      "SalesItemLineDetail": {
        "ItemRef": {"value": "ITEM_ID"},
        "Qty": QUANTITY,
        "UnitPrice": UNIT_PRICE
      }
    }],
    "CustomerRef": {"value": "CUSTOMER_ID"},
    "DueDate": "YYYY-MM-DD"
  }' | jq '.Invoice | {id: .Id, total: .TotalAmt, due: .DueDate}'

### Query Expenses

Find recent expenses (Purchase entities):

curl -s -H "Authorization: Bearer $QBO_ACCESS_TOKEN" \
  -H "Accept: application/json" \
  "https://quickbooks.api.intuit.com/v3/company/$QBO_REALM_ID/query?query=SELECT * FROM Purchase WHERE TxnDate > 'START_DATE' ORDERBY TxnDate DESC" \
  | jq '.QueryResponse.Purchase[] | {id: .Id, vendor: .EntityRef.name, amount: .TotalAmt, date: .TxnDate, account: .AccountRef.name}'

### Get Profit and Loss Report

curl -s -H "Authorization: Bearer $QBO_ACCESS_TOKEN" \
  -H "Accept: application/json" \
  "https://quickbooks.api.intuit.com/v3/company/$QBO_REALM_ID/reports/ProfitAndLoss?start_date=START_DATE&end_date=END_DATE" \
  | jq '.Rows'

### Get Balance Sheet

curl -s -H "Authorization: Bearer $QBO_ACCESS_TOKEN" \
  -H "Accept: application/json" \
  "https://quickbooks.api.intuit.com/v3/company/$QBO_REALM_ID/reports/BalanceSheet?date=END_DATE" \
  | jq '.Rows'

### Look Up a Customer

curl -s -H "Authorization: Bearer $QBO_ACCESS_TOKEN" \
  -H "Accept: application/json" \
  "https://quickbooks.api.intuit.com/v3/company/$QBO_REALM_ID/query?query=SELECT * FROM Customer WHERE DisplayName LIKE '%SEARCH_TERM%'" \
  | jq '.QueryResponse.Customer[] | {id: .Id, name: .DisplayName, email: .PrimaryEmailAddr.Address, balance: .Balance}'

### Look Up a Vendor

curl -s -H "Authorization: Bearer $QBO_ACCESS_TOKEN" \
  -H "Accept: application/json" \
  "https://quickbooks.api.intuit.com/v3/company/$QBO_REALM_ID/query?query=SELECT * FROM Vendor WHERE DisplayName LIKE '%SEARCH_TERM%'" \
  | jq '.QueryResponse.Vendor[] | {id: .Id, name: .DisplayName, email: .PrimaryEmailAddr.Address, balance: .Balance}'

## Rules

- Always refresh the token if you receive a 401 Unauthorized response. Run the token refresh command, update .env, then retry the original request.
- Confirm before creating or updating any financial record. Show the user what will be created and ask for approval.
- When querying invoices or expenses, default to the current month if no date range is specified.
- For reports, always specify start_date and end_date explicitly.
- Respect rate limits: QuickBooks allows 500 requests per minute per company. If you receive a 429 response, wait 60 seconds and retry.
- Never log access tokens, refresh tokens, or client secrets in responses or memory files.
- When creating invoices, always verify the CustomerRef ID exists before submitting.

How Token Refresh Works in This Skill

The skill instructs the agent to handle 401 responses by running the token refresh curl command automatically. When the agent gets a 401, it refreshes the token, updates the .env file, and retries the original request. This happens transparently.

The refresh token itself rotates with each use. Every time you refresh, QuickBooks issues both a new access token and a new refresh token. The old refresh token becomes invalid. Your agent must save the new refresh token every time, or you lose access and have to redo the OAuth consent flow.

In practice, if you use OpenClaw daily, the token refresh happens seamlessly. The 100-day expiration on the refresh token only becomes a problem if your agent sits idle for more than three months.


Step 4: Test the Connection

Restart OpenClaw to load the new skill:

openclaw gateway restart

Open your chat with the OpenClaw agent and test with increasingly complex queries:

Read test (invoices):

“Show me all unpaid invoices in QuickBooks”

The agent should run the invoice query, parse the JSON, and return a list with customer names, amounts, and due dates.

Read test (reports):

“Pull the profit and loss report for March 2026”

The agent should call the ProfitAndLoss endpoint with the correct date range and summarize the results.

Write test:

“Create an invoice for Acme Corp, 5 hours of consulting at $150/hr, due in 30 days”

The agent should show you the invoice details and ask for confirmation before creating it.

If something fails, check these common issues:

SymptomLikely CauseFix
401 UnauthorizedExpired access tokenAgent should auto-refresh; if not, manually run the refresh curl command
401 after refreshExpired refresh token (idle for 100+ days)Redo the OAuth consent flow from Step 2
400 Bad RequestInvalid entity reference (customer ID, item ID)Query the entity first to get the correct ID
403 ForbiddenWrong scope or sandbox/production mismatchCheck your app scopes; ensure you are hitting the correct environment
Empty query resultsSQL-like syntax error in queryQuickBooks query language is specific; check field names in Intuit docs

What to Automate First

Same principle we recommend for every integration: start read-only, build trust, then expand.

Week 1: Read-Only Queries

Use the agent for quick financial lookups during your workday:

  • “What invoices are overdue?”
  • “How much did we spend on AWS last month?”
  • “Show me the cash flow report for Q1”
  • “Who are our top 5 customers by outstanding balance?”

This lets you verify the agent’s responses against what you see in QuickBooks. Catch any data mismatches before you give the agent write permissions.

Week 2: Write Operations

Once read queries feel reliable, start creating and updating records:

  • “Send an invoice to Globex for the March retainer, $3,500, net 15”
  • “Record a $250 expense to Office Supplies from the business checking account”
  • “Update the payment terms on invoice #1042 to net 45”

The skill file’s confirmation rule ensures the agent always shows you what it plans to create before executing. If it does not ask for confirmation, strengthen the Rules section in SKILL.md.

Week 3: Scheduled Automations

Add recurring checks to your heartbeat.md file:

## Overdue Invoice Monitor
Check QuickBooks for invoices where the due date has passed and the balance
is greater than zero. If any are found, send me a summary with customer name,
invoice number, amount due, and days overdue. Group by customer.
## Weekly Expense Summary (runs every Monday at 9:00 AM)
Pull all expenses from the previous 7 days in QuickBooks.
Group by account category. Flag any expense over $500 that I have not
explicitly approved. Send the summary to Telegram.
## Monthly Cash Position (runs 1st of every month)
Pull the Profit and Loss report and Balance Sheet for the previous month.
Calculate net income, total expenses, and current cash position.
Compare to the prior month and highlight significant changes (more than 10%).

Security and Token Management

QuickBooks contains your financial data. Treat these credentials with more care than a CRM integration.

Token storage. All five QuickBooks environment variables (Client ID, Client Secret, Access Token, Refresh Token, Realm ID) belong in .env, not in your workspace files. The skill file references environment variables by name; it never contains the actual values.

Scope discipline. Only enable com.intuit.quickbooks.accounting. Do not add payment scopes unless you actively need to process payments through the API. You can add scopes later without recreating the app.

Confirmation rules. The skill requires agent confirmation before any write operation. This prevents misunderstood instructions from creating incorrect invoices or expenses. For an extra layer, you could limit write operations to specific customers or amount thresholds in the Rules section.

Refresh token rotation. Every token refresh invalidates the previous refresh token. If the agent’s .env update fails mid-rotation, you lose the valid refresh token and must redo the OAuth consent flow. Keep a backup of your current refresh token before relying on automated rotation.

Audit logging. QuickBooks logs all API activity. Check Settings > Audit Log in QuickBooks Online periodically to verify your agent is making the calls you expect and nothing else.

For broader OpenClaw security practices, see Step 9 in our OpenClaw setup guide.


Frequently Asked Questions

Does QuickBooks charge for API access?

Intuit changed their API pricing in 2025. Core API calls (creating invoices, recording payments, updating records) remain free and unlimited. CorePlus API calls (queries, fetching reports, reading account data) are now metered. For a small business running a few dozen queries per day through OpenClaw, the cost is minimal. Check Intuit’s current App Partner Program pricing for exact per-call rates.

Why is QuickBooks OAuth harder than HubSpot’s API key?

HubSpot Private Apps give you a static token that never expires. QuickBooks uses OAuth 2.0 with access tokens that expire every 60 minutes and refresh tokens that expire in 100 days. OAuth adds complexity upfront, but it prevents stolen tokens from working indefinitely. Once your skill handles token refresh, the day-to-day experience is identical to using an API key.

What happens if my refresh token expires?

If your OpenClaw agent goes unused for more than 100 days, the refresh token becomes invalid. You will need to redo the OAuth consent flow from Step 2: open the authorization URL in your browser, approve access, and exchange the new code for fresh tokens. There is no way around this; it is a security measure from Intuit.

Can I use the sandbox to test before touching real data?

Yes. Your Intuit developer account comes with a sandbox company pre-loaded with sample data. Use the sandbox base URL (https://sandbox-quickbooks.api.intuit.com instead of https://quickbooks.api.intuit.com) and the sandbox Realm ID. Once you are confident, switch the base URL and Realm ID to production. The skill file structure stays the same.

Can OpenClaw pay bills or process payments through QuickBooks?

Recording a payment against an invoice (marking it as paid) works with the standard accounting scope. Processing actual payment transactions (charging a credit card, initiating ACH) requires the com.intuit.quickbooks.payment scope and additional Intuit approval. For most bookkeeping use cases, recording payments is sufficient.

What QuickBooks plan do I need?

Any QuickBooks Online plan supports API access: Simple Start ($38/month), Essentials ($75/month), Plus ($115/month), or Advanced ($275/month). The API capabilities are the same across all tiers. Plan differences affect what features are available in the QuickBooks UI, not what the API can access.

How do I handle multiple QuickBooks companies?

Each QuickBooks company has its own Realm ID. To manage multiple companies, store a separate set of tokens and Realm ID for each one. You can create multiple skill files (e.g., quickbooks-companyA/SKILL.md and quickbooks-companyB/SKILL.md) or use a single skill with a company selector in the Rules section.


Key Takeaways

  • QuickBooks uses OAuth 2.0, not a static API key. Plan for the authorization flow and token refresh in your skill file.
  • Create a developer app at developer.intuit.com, select the com.intuit.quickbooks.accounting scope, and complete the OAuth consent flow to get your initial tokens.
  • Access tokens expire every 60 minutes; refresh tokens last 100 days. Your skill handles this by catching 401 responses and refreshing automatically.
  • The token exchange endpoint requires application/x-www-form-urlencoded content type. Sending JSON is the most common integration mistake.
  • Start with read-only queries (invoices, expenses, reports) before enabling write operations. Use heartbeat instructions for recurring financial monitoring.
  • Store all credentials in .env, require confirmation for write operations, and audit your API activity in QuickBooks regularly.
  • For other OpenClaw integrations, see our guides on connecting Slack, Google Sheets, and Notion.

Last Updated: Apr 6, 2026

SL

SFAI Labs

SFAI Labs helps companies build AI-powered products that work. We focus on practical solutions, not hype.

Need Help Setting Up OpenClaw?

  • VPS deployment, SSL, and security hardening done for you
  • Integration configuration — connect your tools on day one
  • Custom skill development for your specific workflows
Get OpenClaw Setup Help →
No commitment · Free consultation

Related articles