ml-connector
QuickBooks DesktopBrex

QuickBooks Desktop and Brex integration

QuickBooks Desktop runs the books on a local company file. Brex runs corporate cards, expenses, and bill pay in the cloud. Connecting the two moves coded Brex spend into QuickBooks without re-keying. After Brex finishes coding a card transaction or bill payment, the amount, merchant, and GL coding post into QuickBooks Desktop as a bill or journal entry against the right account, and vendors stay aligned across both sides. ml-connector handles the very different shapes of each API and moves the data on a cadence you control.

How QuickBooks Desktop works

QuickBooks Desktop has no hosted REST endpoint. It is reached through the QuickBooks Web Connector, a free Windows agent that polls your SOAP service on a schedule set in a .qwc file while QuickBooks is open. The service exchanges QBXML messages such as VendorQuery, BillAdd, BillPaymentCheckAdd, JournalEntryAdd, and AccountQuery, using Add, Query, Mod, and Void operations. Authentication is a SOAP handshake: the agent calls authenticate with a username and password and your service returns a session ticket carried on every later call. There are no webhooks, so changes are found by polling with a ModifiedDateRangeFilter, and every update needs the current EditSequence to avoid overwriting concurrent edits.

How Brex works

Brex exposes its data through a REST API over HTTPS with JSON bodies. Calls authenticate with a bearer token, either a static user token generated in the Brex dashboard or an OAuth2 access token for partner apps that expires hourly and is refreshed with the offline_access scope. The relevant surfaces are the Accounting Records API, which holds transactions coded with a gl_account_id and custom dimension fields and an export_status, plus the Vendors, Transfers, and Expenses APIs. List endpoints use cursor pagination, transfers require an Idempotency-Key header, and Brex can push Svix-signed webhooks including ACCOUNTING_RECORD_READY_FOR_EXPORT when a record is ready to send to an ERP.

What moves between them

The flow runs from Brex into QuickBooks Desktop. When a Brex accounting record is coded and ready for export, ml-connector reads it and posts the spend into QuickBooks Desktop as a bill or journal entry, mapping the Brex gl_account_id and dimension fields to the matching QuickBooks account, then sets the Brex record export_status to EXPORTED so it is never posted twice. Vendors are kept aligned in both directions so card merchants and bill-pay payees match the QuickBooks vendor list. Brex transactions and accounting records are the source of truth for spend, so ml-connector treats them as read-only for amounts and does not write financial entries back into Brex. Because QuickBooks Desktop has no webhooks, posts are queued and delivered on the next Web Connector cycle.

How ml-connector handles it

ml-connector stores both credential sets encrypted. It sends the Brex bearer token on every REST call, refreshing the OAuth2 token before it expires, and on the QuickBooks side it answers the Web Connector authenticate call with the per-customer username and password and validates the session ticket on each SOAP method. Brex can fire an ACCOUNTING_RECORD_READY_FOR_EXPORT webhook, verified with its Svix signature, and a scheduled poll backfills anything a webhook missed, since QuickBooks Desktop is pull-only and only processes work while it is open. Each coded record becomes a QuickBooks bill or journal entry with the GL account and dimensions resolved first, so every line lands on a valid account. Merchant names from Brex rarely match QuickBooks vendor names, so a fuzzy match and cache layer resolves the right VendorRef. Because QuickBooks has no idempotency key, ml-connector records the returned TxnID and re-queries the EditSequence before any update, and Brex rate limits return HTTP 429, so it backs off and retries. Every record carries a full audit trail and can be replayed if a post fails.

A real-world example

A 90-person creative agency keeps its books in QuickBooks Desktop Enterprise and gives staff Brex cards for software, travel, and client costs, with a few recurring vendors paid through Brex bill pay. Before the integration, the controller exported a Brex transaction report each week and hand-entered the totals into QuickBooks as bills and journal entries, guessing at the right expense account and matching merchant names to vendors one line at a time. With QuickBooks Desktop and Brex connected, each coded Brex record posts into QuickBooks on the next Web Connector cycle, already mapped to the correct account and vendor, and the export status on the Brex side shows what has landed. The weekly re-keying disappears and month-end close starts with card spend already on the books.

What you can do

  • Post coded Brex card spend and bill payments into QuickBooks Desktop as bills and journal entries on the right GL accounts.
  • Mark each Brex accounting record EXPORTED after it lands in QuickBooks so nothing posts twice.
  • Keep Brex vendors and the QuickBooks vendor list aligned, fuzzy matching merchant names that do not match exactly.
  • Bridge the Brex bearer token to the QuickBooks Web Connector SOAP session and ticket.
  • Receive Brex export-ready webhooks and backfill with a scheduled poll, since QuickBooks Desktop cannot be pushed to.

Questions

Which direction does data move between QuickBooks Desktop and Brex?
The flow is Brex into QuickBooks Desktop. Coded accounting records, card spend, and bill payments move from Brex into QuickBooks as bills and journal entries, and vendors are aligned in both directions. Brex is treated as the read-only source for spend, so ml-connector does not write financial amounts back into Brex.
How does the integration reach QuickBooks Desktop if it has no cloud API?
QuickBooks Desktop is reached through the QuickBooks Web Connector, a Windows agent that polls a SOAP service while QuickBooks is open and exchanges QBXML messages. ml-connector answers the Web Connector authenticate call, returns a session ticket, and posts coded Brex records on each sync cycle. Because there are no webhooks on the QuickBooks side, work is queued and delivered on the next cycle rather than in real time.
How are Brex merchants matched to QuickBooks vendors?
Brex merchant names rarely match QuickBooks vendor names exactly, so ml-connector runs a fuzzy match against the QuickBooks vendor list and caches the result. When a confident match is found it reuses the existing VendorRef, and when no vendor exists it can create one so the bill or journal entry posts to a valid payee.

Related integrations

Connect QuickBooks Desktop and Brex

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

Get started