QuickBooks Online and BILL integration
BILL runs your accounts payable and expense workflows. QuickBooks Online runs your general ledger and accounting records. Connecting the two keeps your vendors, bills, and payments aligned across both systems. Vendor records created or updated in BILL flow into QuickBooks Online, and bill data follows the same path so your expense accounting stays current without manual data entry or reconciliation delays.
What moves between them
The primary data flow runs from BILL into QuickBooks Online. Vendor records created or updated in BILL are read by ml-connector and posted as Vendor entities in QuickBooks Online. Bill data from BILL flows into QuickBooks Online as Purchase Orders, mapped to the matching QuickBooks Online Vendor and Account. Payments and recurring bills are tracked and synced on a schedule you define, typically daily or weekly depending on your AP cycle. Because both systems support webhooks, ml-connector listens for change events on both sides and backs them up with periodic polling to catch any missed or duplicate events.
How ml-connector handles it
ml-connector stores BILL session credentials encrypted and refreshes the session on demand before each API call, with automatic re-login if the session expires after 35 minutes of inactivity. On the QuickBooks Online side, it exchanges the OAuth refresh token for a new access token every 55 minutes (well before the 60-minute expiration) and handles the 24-26 hour refresh token rotation by detecting 401 responses and re-triggering the full OAuth flow if needed. BILL webhooks trigger immediate syncs of vendor and bill data, while QuickBooks Online webhooks trigger validation that the records exist in both systems. All vendor and bill mappings are stored with the QuickBooks Online realm_id and BILL organization_id so switching between sandboxes and production is straightforward. BILL imposes a maximum of 10 webhook subscriptions per organization, so ml-connector consolidates events across vendor, bill, and payment entity types into a single subscription. Webhook payloads from both systems contain only the entity ID, so ml-connector always fetches the full record via GET to ensure all fields are present. The HMAC-SHA256 signature is verified against the x-bill-sha-signature header with base64 encoding, and the QuickBooks Online webhook payloads are validated with the realm_id embedded in the URL path. Retries use exponential backoff on both sides, and every record is logged with full audit trail so failed syncs can be manually replayed after root cause is fixed.
A real-world example
A mid-sized software services firm uses BILL for vendor payments and expense tracking across four locations and 40 team members, and uses QuickBooks Online for accounting and tax reporting. Before the integration, the finance team received vendor setup and bill data from BILL and re-entered it into QuickBooks Online by hand each week, creating lag between the time invoices were received in BILL and when they appeared in the GL. Reconciliation required cross-checking vendor names and bill amounts against both systems. With BILL and QuickBooks Online connected, new vendors appear in QuickBooks Online within minutes of creation in BILL, and bills sync automatically on a daily schedule. Month-end GL reconciliation now starts with AP already clean, and the manual data-entry step is eliminated entirely.
What you can do
- Sync vendors from BILL to QuickBooks Online as Vendor records, keeping vendor names, addresses, and tax IDs aligned across both systems.
- Post bills from BILL into QuickBooks Online as Purchase Orders, with line items and GL accounts mapped correctly to track expenses by department or cost center.
- Handle OAuth 2.0 token refresh on the QuickBooks Online side and session token refresh on the BILL side, maintaining authenticated connections without manual intervention.
- Verify BILL webhook signatures with HMAC-SHA256 and validate QuickBooks Online webhook payloads against your realm_id to prevent data corruption from unsigned requests.
- Detect and recover from webhook outages or missed events by polling both BILL and QuickBooks Online on a schedule and replaying failed records with full audit trail.
Questions
- Which direction does data move between BILL and QuickBooks Online?
- The primary flow is from BILL into QuickBooks Online. Vendors created or updated in BILL sync as Vendor records in QuickBooks Online, and bills sync as Purchase Orders. QuickBooks Online is treated as the system of record for GL accounts and chart structure, so ml-connector does not write chart changes back to BILL from QuickBooks Online.
- How does the integration handle BILL's 35-minute session timeout and QuickBooks Online's 1-hour token expiration?
- ml-connector refreshes the BILL session token on demand before each API call and detects expiration by checking for 401 responses on login calls. On the QuickBooks Online side, it proactively refreshes the access token every 55 minutes, well before the 60-minute expiration. It also monitors the 24-26 hour refresh token rotation and handles token revocation by re-triggering the full OAuth flow when needed.
- Why does ml-connector validate BILL webhook events with GET calls if webhooks already provide the data?
- BILL webhook payloads contain only the entity ID, name, and operation type, so the full record must be fetched separately to ensure all fields are present. Additionally, webhooks can arrive out of order or be duplicated, and BILL recommends not treating webhooks as the only source of truth. ml-connector verifies every webhook event with a GET call to prevent data gaps or conflicts.
Related integrations
More QuickBooks Online integrations
Other systems that connect to BILL
Connect QuickBooks Online and BILL
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started