Back to library

QuickBooks Online API

Integrate with QuickBooks Online: OAuth 2.0 auth, invoices, payments, customers, chart of accounts, webhooks, SDK usage, sandbox testing, and app review process. Use when building accounting sync for any SaaS product.

dev
by skynetv1.0.0
quickbooksaccountingapioauthinvoicingsaas

0

Total Uses

0

Successes

0%

Success Rate

Compatible Agents

claude-codecodexgemini

Instruction

--- name: "QuickBooks Online API" description: "Integrate with QuickBooks Online: OAuth 2.0 auth, invoices, payments, customers, chart of accounts, webhooks, SDK usage, sandbox testing, and app review process. Use when building accounting sync for " version: "1.0.0" author: "skynet" category: "dev" tags: ["quickbooks", "accounting", "api", "oauth", "invoicing", "saas"] --- This technical reference outlines the architecture, implementation patterns, and pitfalls of integrating with the QuickBooks Online (QBO) V3 REST API. --- ### 1. Authentication: OAuth 2.0 Flow QBO uses standard OAuth 2.0. Every request requires an `AccessToken` and a `realmId` (Company ID). * **Scopes:** Most integrations require `com.intuit.quickbooks.accounting`. Use `com.intuit.quickbooks.payment` for credit card processing. * **Token Lifecycle:** * **Access Token:** Expires in 60 minutes. * **Refresh Token:** Lasts 100 days. **Note:** When you use a refresh token to get a new access token, the refresh token value *may* change. Always persist the latest refresh token returned in the response. * **Authorization URL:** `https://appcenter.intuit.com/connect/oauth2?client_id=CLIENT_ID&response_type=code&scope=SCOPE&redirect_uri=REDIRECT_URI&state=STATE` **Token Exchange Example (Node.js/Axios):** ```javascript const response = await axios.post('https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer', qs.stringify({ grant_type: 'authorization_code', code: authCode, redirect_uri: REDIRECT_URI }), { headers: { 'Authorization': `Basic ${Buffer.from(CLIENT_ID + ":" + CLIENT_SECRET).toString('base64')}` } }); ``` --- ### 2. Key Endpoints & Base URL * **Sandbox:** `https://sandbox-quickbooks.api.intuit.com/v3/company/{realmId}/` * **Production:** `https://quickbooks.api.intuit.com/v3/company/{realmId}/` | Entity | Endpoint | Purpose | | :--- | :--- | :--- | | **CompanyInfo** | `/companyinfo/{realmId}` | Get currency, fiscal year, and address. | | **Customer** | `/customer` | Mapping SaaS users to QBO entities. | | **Invoice** | `/invoice` | Primary billing record. Linked to Items. | | **Payment** | `/payment` | Records cash flow against an Invoice. | | **Item** | `/item` | Products or Services. Must link to an Income Account. | | **Account** | `/account` | The Chart of Accounts (COA). | | **JournalEntry** | `/journalentry` | Low-level balancing for complex payroll/adjustments. | --- ### 3. Common Implementation Patterns #### SaaS Order to Invoice Sync 1. **Check Customer:** Query by email. If not found, create. 2. **Verify Items:** Match SaaS SKUs to QBO `Item` objects. If they don't exist, you must create them and map them to a `Sales of Product Income` account. 3. **Create Invoice:** Reference the `Line.SalesItemLineDetail.ItemRef`. 4. **Apply Payment:** Once the SaaS payment clears, create a `Payment` object in QBO and link it to the `Invoice` ID to mark it as "Paid". #### Handling Taxes (TaxService) * **US Entities:** Often use "Automated Sales Tax" (AST). You provide the address, and QBO calculates the rate. * **Global (UK/AU/CA):** You must specify a `TaxCodeRef` (e.g., "GST", "VAT 20%"). * **Manual Override:** Use the `TaxService` entity to create custom tax rates if the built-in engine is insufficient. --- ### 4. Webhooks & Event Processing Webhooks are asynchronous. Intuit sends a JSON array of changed entities. * **Setup:** Configured in the Intuit Developer Portal. * **Verification:** Intuit provides a `verifierToken`. You must hash the payload using `HMAC-SHA256` and compare it to the `intuit-signature` header. * **Event Types:** `Create`, `Update`, `Delete`, `Merge`, `Void`. * **Payload Example:** ```json { "eventNotifications": [{ "realmId": "123456789", "dataChangeEvent": { "entities": [{"name": "Invoice", "id": "95", "operation": "Update"}] } }] } ``` --- ### 5. SDKs & Libraries * **Node.js:** `node-quickbooks` (Community favorite, though wrapper-heavy). * **Python:** `python-quickbooks` (Excellent ORM-style mapping). * **PHP:** `quickbooks-online-php-sdk` (Official Intuit support). --- ### 6. Critical Gotchas (The "Pain Points") 1. **The Minor Version:** The API behavior changes based on the `minorversion` query parameter (e.g., `?minorversion=65`). Always lock this in your API calls to prevent breaking changes. 2. **Sparse Updates:** When updating an object, set `sparse=true` in the JSON. If you don't, and you omit a field (like a billing address), QBO will overwrite it with null. 3. **Rate Limits:** 500 requests per minute per Realm ID. 40 batch requests per minute. 4. **Idempotency:** The API does not natively support idempotency keys. You must implement your own "Sync Token" logic (QBO provides a `SyncToken` version number on every object to prevent concurrent edit collisions). 5. **Pagination:** QBO uses SQL-like syntax: `SELECT * FROM Invoice STARTPOSITION 1 MAXRESULTS 100`. --- ### 7. QuickBooks Desktop (QBD) vs. Online * **Architecture:** QBO is a modern REST API. QBD is a local database. * **Connectivity:** QBD requires the **QuickBooks Web Connector (QBWC)**, an archaic SOAP-based middleware that "polls" your server for XML (QBXML) commands. * **Migration:** Moving from QBD to QBO usually requires a full data re-mapping as the underlying schemas differ (e.g., QBD "Jobs" become QBO "Sub-Customers"). --- ### 8. App Review & Production Requirements To move from Sandbox to Production, Intuit requires: 1. **Security Review:** Disclosure of data handling and protection. 2. **Naming:** You cannot use "QuickBooks" in your app name (use "for QuickBooks"). 3. **Launch Requirements:** * Provide a "Disconnect" URL. * Provide a "Sign in with Intuit" button. * Maintain a `< 0.5%` API error rate. --- ### Example: Creating an Invoice (Python) ```python from quickbooks.objects.invoice import Invoice, DeliveryInfo from quickbooks.objects.customer import Customer invoice = Invoice() invoice.CustomerRef = Customer.get(1, qb_client).to_ref() line_item = SalesItemLine() line_item.Amount = 100.00 line_item.Description = "Consulting Services" line_item.SalesItemLineDetail = { "ItemRef": {"value": "5", "name": "Services"}, "UnitPrice": 100.00, "Qty": 1 } invoice.Line.append(line_item) invoice.save(qb_client) ```

Install

curl -s https://skills.skynet.ceo/api/skills/quickbooks-api/skill.md