LoopFour
IntegrationsAccounting

QuickBooks Online

Accounting integration for invoices, payments, and financial data

QuickBooks Online

Connect to QuickBooks Online to automate invoice creation, payment processing, customer management, and financial reporting.

Overview

QuickBooks Online is a cloud-based accounting platform for small to medium businesses. The integration supports:

  • Customer Management - Create, update, and search customers
  • Invoicing - Create, send, void, and track invoices
  • Payments - Record and manage customer payments
  • Bills (AP) - Create and manage vendor bills
  • Vendors - Manage vendor records
  • Chart of Accounts - Access and create accounts
  • Financial Reports - Run P&L, Balance Sheet, and more
  • Custom Queries - Execute custom queries

Prerequisites

  • QuickBooks Online account (Plus, Essentials, or Simple Start)
  • Admin access to configure OAuth connection
  • Company file (Realm ID) for API access

Authentication

QuickBooks uses OAuth 2.0 for authentication via Nango.

Connect QuickBooks

# Get OAuth URL
curl "http://localhost:3000/api/v1/connections/quickbooks/auth-url" \
  -H "x-api-key: YOUR_API_KEY"

Required Scopes

ScopeDescription
com.intuit.quickbooks.accountingFull accounting access

Available Actions

Customer Actions

createCustomer

Create a new customer in QuickBooks.

{
  "id": "create-customer",
  "type": "action",
  "action": "quickbooks.createCustomer",
  "config": {
    "displayName": "{{input.companyName}}",
    "firstName": "{{input.firstName}}",
    "lastName": "{{input.lastName}}",
    "companyName": "{{input.companyName}}",
    "email": "{{input.email}}",
    "phone": "{{input.phone}}",
    "billingAddress": {
      "line1": "{{input.address.street}}",
      "city": "{{input.address.city}}",
      "state": "{{input.address.state}}",
      "postalCode": "{{input.address.zip}}",
      "country": "{{input.address.country}}"
    }
  }
}

Parameters:

FieldTypeRequiredDescription
displayNamestringYesDisplay name (unique identifier)
firstNamestringNoFirst name
lastNamestringNoLast name
companyNamestringNoCompany name
emailstringNoPrimary email address
phonestringNoPhone number
mobilestringNoMobile number
billingAddressobjectNoBilling address
notesstringNoInternal notes
activebooleanNoActive status (default: true)

getCustomer

Get a customer by ID.

{
  "action": "quickbooks.getCustomer",
  "config": {
    "customerId": "{{input.customerId}}"
  }
}

updateCustomer

Update an existing customer.

{
  "action": "quickbooks.updateCustomer",
  "config": {
    "customerId": "{{steps.lookup.output.id}}",
    "email": "{{input.newEmail}}"
  }
}

findCustomerByEmail

Find a customer by email address.

{
  "action": "quickbooks.findCustomerByEmail",
  "config": {
    "email": "{{input.email}}"
  }
}

listCustomers

List customers with optional filters.

{
  "action": "quickbooks.listCustomers",
  "config": {
    "active": true,
    "companyName": "Acme",
    "limit": 50,
    "offset": 0
  }
}

Invoice Actions

createInvoice

Create a new invoice.

{
  "id": "create-invoice",
  "type": "action",
  "action": "quickbooks.createInvoice",
  "config": {
    "customerId": "{{steps.customer.output.Customer.Id}}",
    "lines": [
      {
        "description": "Professional Services",
        "amount": 1500.00,
        "quantity": 10,
        "unitPrice": 150.00
      },
      {
        "description": "Software License",
        "amount": 500.00,
        "quantity": 1,
        "unitPrice": 500.00,
        "itemId": "123"
      }
    ],
    "dueDate": "2024-02-15",
    "invoiceDate": "2024-01-15",
    "invoiceNumber": "INV-001",
    "customerMemo": "Thank you for your business!",
    "email": "{{input.customerEmail}}"
  }
}

Parameters:

FieldTypeRequiredDescription
customerIdstringYesCustomer ID
linesarrayYesLine items (at least one)
lines[].descriptionstringNoLine item description
lines[].amountnumberYesLine amount
lines[].quantitynumberNoQuantity (default: 1)
lines[].unitPricenumberNoUnit price
lines[].itemIdstringNoProduct/Service ID
dueDatestringNoDue date (YYYY-MM-DD)
invoiceDatestringNoInvoice date (default: today)
invoiceNumberstringNoCustom invoice number
customerMemostringNoMemo for customer
privateNotestringNoInternal note
emailstringNoEmail to send invoice to

getInvoice

Get an invoice by ID.

{
  "action": "quickbooks.getInvoice",
  "config": {
    "invoiceId": "{{input.invoiceId}}"
  }
}

sendInvoice

Send an invoice to the customer via email.

{
  "action": "quickbooks.sendInvoice",
  "config": {
    "invoiceId": "{{steps.create-invoice.output.Invoice.Id}}",
    "email": "{{input.alternateEmail}}"
  }
}

voidInvoice

Void an invoice.

{
  "action": "quickbooks.voidInvoice",
  "config": {
    "invoiceId": "{{input.invoiceId}}"
  }
}

updateInvoice

Update an existing invoice.

{
  "action": "quickbooks.updateInvoice",
  "config": {
    "invoiceId": "{{input.invoiceId}}",
    "dueDate": "2024-03-01",
    "customerMemo": "Updated payment terms"
  }
}

listInvoices

List invoices with optional filters.

{
  "action": "quickbooks.listInvoices",
  "config": {
    "customerId": "{{input.customerId}}",
    "balance": 0,
    "balanceOperator": ">",
    "txnDateAfter": "2024-01-01",
    "limit": 100
  }
}

Payment Actions

createPayment

Record a customer payment.

{
  "id": "record-payment",
  "type": "action",
  "action": "quickbooks.createPayment",
  "config": {
    "customerId": "{{input.customerId}}",
    "amount": 1500.00,
    "paymentDate": "2024-01-20",
    "paymentMethodId": "1",
    "invoiceIds": ["{{input.invoiceId}}"],
    "referenceNumber": "CHK-12345"
  }
}

Parameters:

FieldTypeRequiredDescription
customerIdstringYesCustomer ID
amountnumberYesPayment amount
paymentDatestringNoPayment date (default: today)
paymentMethodIdstringNoPayment method reference
depositAccountIdstringNoAccount to deposit to
invoiceIdsarrayNoInvoices to apply payment to
referenceNumberstringNoCheck/reference number

getPayment

Get a payment by ID.

{
  "action": "quickbooks.getPayment",
  "config": {
    "paymentId": "{{input.paymentId}}"
  }
}

voidPayment

Void a payment.

{
  "action": "quickbooks.voidPayment",
  "config": {
    "paymentId": "{{input.paymentId}}"
  }
}

Bill (AP) Actions

createBill

Create a vendor bill (accounts payable).

{
  "id": "create-bill",
  "type": "action",
  "action": "quickbooks.createBill",
  "config": {
    "vendorId": "{{input.vendorId}}",
    "lines": [
      {
        "description": "Office Supplies",
        "amount": 250.00,
        "accountId": "54",
        "billableStatus": "NotBillable"
      }
    ],
    "dueDate": "2024-02-28",
    "billNumber": "BILL-001"
  }
}

getBill / updateBill / deleteBill

{
  "action": "quickbooks.getBill",
  "config": { "billId": "{{input.billId}}" }
}

Vendor Actions

createVendor

Create a new vendor.

{
  "action": "quickbooks.createVendor",
  "config": {
    "displayName": "{{input.vendorName}}",
    "companyName": "{{input.companyName}}",
    "email": "{{input.email}}",
    "is1099": true,
    "taxId": "{{input.taxId}}"
  }
}

Account Actions

getAccountList

Get the chart of accounts.

{
  "action": "quickbooks.getAccountList",
  "config": {
    "active": true,
    "accountType": "Expense",
    "classification": "Expense"
  }
}

Account Types: Bank, Accounts Receivable, Other Current Asset, Fixed Asset, Accounts Payable, Credit Card, Other Current Liability, Long Term Liability, Equity, Income, Cost of Goods Sold, Expense, Other Income, Other Expense

createAccount

Create a new account in the chart of accounts.

{
  "action": "quickbooks.createAccount",
  "config": {
    "name": "Software Subscriptions",
    "accountType": "Expense",
    "accountSubType": "SubscriptionFees",
    "description": "SaaS and software subscriptions"
  }
}

Report Actions

runReport

Run a financial report.

{
  "id": "monthly-pnl",
  "type": "action",
  "action": "quickbooks.runReport",
  "config": {
    "reportType": "ProfitAndLoss",
    "startDate": "2024-01-01",
    "endDate": "2024-01-31",
    "accountingMethod": "Accrual",
    "summarizeBy": "Month"
  }
}

Available Reports:

ReportDescription
ProfitAndLossIncome statement
BalanceSheetBalance sheet
CashFlowCash flow statement
TrialBalanceTrial balance
GeneralLedgerGeneral ledger detail
AgedReceivablesAR aging summary
AgedPayablesAP aging summary
CustomerIncomeRevenue by customer
VendorExpensesExpenses by vendor

Query Action

query

Execute a custom QuickBooks query.

{
  "action": "quickbooks.query",
  "config": {
    "query": "SELECT * FROM Invoice WHERE Balance > '0' ORDER BY TxnDate DESC MAXRESULTS 50"
  }
}

Webhook Triggers

QuickBooks webhooks can trigger workflows on data changes.

{
  "trigger": {
    "type": "webhook",
    "provider": "quickbooks",
    "events": ["Invoice", "Customer", "Payment"]
  }
}

Event Types: Customer, Invoice, Payment, Bill, Vendor, Account, Purchase, SalesReceipt, Estimate

Example Workflow

Complete invoice workflow triggered by Stripe payment:

{
  "name": "Stripe to QuickBooks Invoice",
  "trigger": {
    "type": "webhook",
    "provider": "stripe",
    "events": ["invoice.paid"]
  },
  "steps": [
    {
      "id": "find-customer",
      "type": "action",
      "action": "quickbooks.findCustomerByEmail",
      "config": {
        "email": "{{input.data.object.customer_email}}"
      }
    },
    {
      "id": "check-customer",
      "type": "condition",
      "config": {
        "conditions": {
          "left": "{{steps.find-customer.output.QueryResponse.Customer}}",
          "operator": "exists"
        },
        "then": ["create-invoice"],
        "else": ["create-customer"]
      }
    },
    {
      "id": "create-customer",
      "type": "action",
      "action": "quickbooks.createCustomer",
      "config": {
        "displayName": "{{input.data.object.customer_name}}",
        "email": "{{input.data.object.customer_email}}"
      }
    },
    {
      "id": "create-invoice",
      "type": "action",
      "action": "quickbooks.createInvoice",
      "config": {
        "customerId": "{{steps.find-customer.output.QueryResponse.Customer[0].Id || steps.create-customer.output.Customer.Id}}",
        "lines": [
          {
            "description": "{{input.data.object.lines.data[0].description}}",
            "amount": "{{input.data.object.amount_paid / 100}}"
          }
        ]
      }
    },
    {
      "id": "record-payment",
      "type": "action",
      "action": "quickbooks.createPayment",
      "config": {
        "customerId": "{{steps.find-customer.output.QueryResponse.Customer[0].Id || steps.create-customer.output.Customer.Id}}",
        "amount": "{{input.data.object.amount_paid / 100}}",
        "invoiceIds": ["{{steps.create-invoice.output.Invoice.Id}}"],
        "referenceNumber": "{{input.data.object.id}}"
      }
    }
  ]
}

Rate Limits

LimitValue
API calls per minute500
Batch operations30 records per batch
Query results1000 records max
Concurrent connections10

Troubleshooting

Common Errors

ErrorCauseSolution
realmId is requiredMissing company IDEnsure realmId is set in context or config
SyncToken mismatchConcurrent updatesRefetch record before update
Business validation errorInvalid dataCheck field formats and requirements
ThrottledRate limit exceededImplement exponential backoff

Required Context Variables

QuickBooks actions require realmId (company ID) which can be provided via:

  1. Workflow variables: Set in workflow definition
  2. Step config: Pass explicitly in each step
  3. Connection metadata: Stored with OAuth connection
{
  "variables": {
    "realmId": "1234567890"
  }
}