ml-connector
QuickBooks DesktopBILL

QuickBooks Desktop and BILL integration

This connection links BILL, the cloud accounts payable platform, with QuickBooks Desktop, the on-premise book of record. Bills and vendors created or approved in BILL flow into QuickBooks Desktop so the general ledger reflects what is owed without re-keying invoices. Payments BILL makes to vendors post back into QuickBooks Desktop as bill payment checks against the right open bills. Vendor master data stays aligned on both sides so every bill references a vendor that already exists. ml-connector handles the very different transports on each side and moves the data on a schedule the Web Connector controls.

How QuickBooks Desktop works

QuickBooks Desktop has no hosted API. Integration runs through the QuickBooks Web Connector, a Windows agent that polls a SOAP web service on a configurable interval (commonly five to fifteen minutes) while QuickBooks is open, exchanging QBXML request and response blobs. Authentication is a session ticket: the Web Connector calls authenticate with a username and password, and every later call carries the returned ticket. Key entities reach the GL through QBXML messages such as VendorAdd, BillAdd, BillPaymentCheckAdd, Account, and JournalEntry. There are no webhooks, so changes are found by polling queries filtered by a modified-date range, and updates require the current EditSequence on each record.

How BILL works

BILL exposes its data through the BILL v3 REST API at gateway.prod.bill.com, using JSON over standard HTTP verbs. Authentication is a session token: a POST to the login endpoint with a developer key, organization id, username, and password returns a sessionId that scopes calls to one organization and expires after thirty-five minutes of inactivity. Vendors, bills, payments, invoices, and chart-of-accounts records each have their own endpoint, with offset-based pagination capped at one hundred records per page. BILL can also push vendor, bill, and payment events to a registered endpoint, signed with HMAC-SHA256, though it limits an organization to ten subscriptions.

What moves between them

The main flow runs from BILL into QuickBooks Desktop. Bills approved in BILL are written into QuickBooks Desktop as Bill records against the matching vendor and expense accounts, and payments BILL issues post back as bill payment checks applied to those open bills. Vendor records are aligned in both directions so a bill always references a vendor that exists on both sides. The cadence follows the Web Connector schedule rather than a push: each sync cycle reads what changed in BILL since the last successful run and applies it to the company file. QuickBooks Desktop stays the book of record, so ml-connector does not move GL accounts back into BILL beyond keeping the expense accounts both systems share in agreement.

How ml-connector handles it

ml-connector stores both credential sets encrypted. On the BILL side it performs the session login, caches the sessionId, and re-authenticates whenever a call returns a 401, since BILL signals an expired session as a plain auth error rather than a clear code. On the QuickBooks side it answers the Web Connector authenticate handshake, issues a session ticket, and feeds QBXML to QuickBooks during each sync cycle. Because QuickBooks Desktop is pull-only and QuickBooks must be running for the Web Connector to work, BILL is polled on the Web Connector interval rather than driven by BILL webhooks, which the connector can still consume to know what changed before the next cycle. Vendors are mapped first, then a BILL bill becomes a QuickBooks Bill and a BILL payment becomes a bill payment check linked to the open bill. Neither system has native idempotency, so each record is tracked by its BILL id and its QuickBooks TxnID or ListID to prevent a duplicate bill, and every BillMod re-queries the current EditSequence first to avoid the error QuickBooks raises on a stale value. BILL rate limits and concurrency caps are respected with backoff, and every record carries a full audit trail and can be replayed if a call fails.

A real-world example

A forty-person commercial landscaping firm runs QuickBooks Desktop Premier as its book of record and uses BILL to route supplier invoices for approval and pay vendors by ACH. Before the integration, an office manager keyed every approved bill into QuickBooks by hand and then re-entered each payment after it cleared, which left the ledger a few days behind BILL and made month-end reconciliation a hunt for bills that existed in one system but not the other. With BILL and QuickBooks Desktop connected, approved bills and their payments post into the company file automatically on each Web Connector cycle, vendors stay aligned, and the accounts payable balance in QuickBooks matches BILL without manual entry.

What you can do

  • Post bills approved in BILL into QuickBooks Desktop as Bill records against the matching vendor and expense accounts.
  • Record BILL vendor payments in QuickBooks Desktop as bill payment checks applied to the correct open bills.
  • Keep vendor master data aligned between BILL and QuickBooks Desktop so every bill references a known vendor.
  • Bridge the BILL session login to the QuickBooks Web Connector ticket handshake and refresh the BILL session on a 401.
  • Track each record by its BILL id and QuickBooks TxnID or ListID, with retries and a full audit trail on every record.

Questions

Which direction does data move between BILL and QuickBooks Desktop?
The main flow is BILL into QuickBooks Desktop. Approved bills and the payments BILL issues post into QuickBooks Desktop, while vendor records are aligned in both directions. QuickBooks Desktop stays the book of record, so ml-connector keeps the shared expense accounts in agreement rather than rewriting the QuickBooks general ledger from BILL.
Does QuickBooks Desktop need anything installed for this to work?
Yes. QuickBooks Desktop has no cloud API, so the customer installs the free QuickBooks Web Connector on the same Windows machine and imports a configuration file pointing at the ml-connector SOAP endpoint. QuickBooks must be open on that machine for the Web Connector to process a sync, and the polling interval is set in that configuration file.
How are duplicate bills prevented when there is no idempotency key?
Neither BILL nor QuickBooks Desktop offers a native idempotency key. ml-connector records each BILL id alongside the QuickBooks TxnID or ListID returned on create, so a bill that already exists is skipped instead of re-entered. Updates re-query the current EditSequence first, which is the version counter QuickBooks requires on every modify.

Related integrations

Connect QuickBooks Desktop and BILL

Free to use. Add your credentials, ping your real systems, and see if we fit.

Get started