Connecting QuickBooks Online

Connecting QuickBooks Online turns an approved invoice into a bill in your company file, coded to the vendor, the account and the property you chose, with the QuickBooks ID recorded against the document.

On Xero instead? There is a direct connector for that too — see connecting Xero. On any other ledger none of this is required: export produces a CSV whose columns you define yourself, which is covered in the exports reference.

Before you start

  • Be an Admin. Connecting, the destination switches, mapping and disconnecting are all admin-only, and the API refuses them whatever the screen offers. A Controller Approver or an AP Specialist sees the control greyed out with the reason on it. Running the export afterwards is an Admin or a Controller Approver.
  • Have the QuickBooks sign-in for the company file the bills belong in. inletAP never sees your QuickBooks password.
  • Check the edition of that company file. This is the one check worth doing before anything else, because it decides what is possible rather than how tidy the result is:
    • EasyStart in Canada, Simple Start in the United States. No Accounts Payable, so the file cannot hold a bill at all and nothing can post. Export as CSV and bring the file into your books that way until the company is upgraded.
    • Essentials. Bills post with vendor, account, amount and tax. Lines cannot carry a class, so the property does not travel with the cost.
    • Plus and Advanced. Bills post and each line can carry its property as a class, provided class tracking is switched on in the company file.
  • Have your vendors and GL codes in inletAP already. Step 4 matches what you hold against what QuickBooks holds; it does not invent either side. Importing your data loads them from a spreadsheet.

inletAP reads those capabilities from the company file itself rather than from the plan name, and says so on the connection when something is missing. A company on Plus with class tracking switched off looks identical to Essentials in the data, so the edition decides which of the two you are told — the cheaper explanation is never assumed.

1. Start the connection

Open Settings → Connectors. The QuickBooks Online card reads "Not connected yet" and says what pressing the button does before you press it. Press Connect QuickBooks Online.

The same button sits on Exports → Ledger setup while no ledger is connected. Either one works, and you come back to whichever screen you started from.

2. Authorize, and choose the company file

inletAP sends you to QuickBooks. You sign in there and choose the company to post into. inletAP never sees your password; what comes back is an authorization token for the company you selected.

One round trip carries one company. A second company is a second connection — and once a QuickBooks connection exists the big card is gone, so look for the Connect another set of books row under the cards and press QuickBooks Online there.

Where you land. Back on the screen you started from, with a QuickBooks Online connected message and a card naming the company, its country and its edition. The card also carries the connection's state: Connected, Action required when the authorization needs renewing, or Disconnected when it was revoked or has expired. If the round trip failed — cancelled at QuickBooks, an expired link, a company on a plan without Accounts Payable — the reason is reported in words rather than as a code, and nothing about your workspace has changed.

3. Turn the company on as a destination

Connecting a company authorizes inletAP to write into it. Whether it actually receives bills is a separate switch: Post approved bills here, on the connection card. Approved invoices post to every ledger that is turned on — one bill in each.

Your first QuickBooks company is turned on for you, because "did you mean to post here" has only one sensible answer then. A second one is not. Connect it, then switch it on deliberately. Xero is counted separately and behaves the same way.

With two QuickBooks companies switched on, also mark one of them Unrouted bills go here. An invoice that names no ownership entity has to land in one set of books, and with no default marked inletAP does not guess: it parks the invoice with no_default_ledger rather than record the same expense in both companies. Routing an ownership entity to a particular company is on Settings → Split coding, in the Ownership entities → ledgers table — see posting to several companies.

How many ledgers may be switched on at once is a plan limit, counted across QuickBooks and Xero together. Connecting is never capped; switching on is. The exports reference has the numbers.

4. Read and match vendors, accounts and classes

A bill cannot post without a vendor and an account, so an unmatched vendor is a blocked invoice rather than an untidy list.

Open Exports → Ledger setup. If you hold more than one connection, pick this one in the Editing bar at the top: everything below it belongs to the ledger named there. Press Read lists from QuickBooks Online to pull in the company's vendors, accounts, classes, locations, customers, tax codes and terms. Rows that match by name are matched for you; ties are left for a person, because guessing between two similarly named accounts is exactly the sort of help nobody wants. Show gaps only narrows the tables to what is still outstanding.

In inletAPIn QuickBooksWhat it becomes on the bill
VendorA vendorWho the bill is posted against.
GL codeAn expense accountThe account on the bill line.
PropertyA classThe class on the line, so the cost lands on the building. Offered only when the file tracks classes.

Four defaults sit above that list, because they answer questions the invoice does not:

  • Default expense account — what a bill line uses when the invoice carries no GL code. Without it, an uncoded invoice cannot post at all, so it counts as a blocking gap.
  • Accounts payable account — which A/P account the bill is owed from. Optional. If the company has exactly one A/P account, reading the lists claims it for you; with two or more it is left for a person, and unset means QuickBooks uses the company's own.
  • Sales tax expense account — US company files only. Where the sales tax a vendor charged you is expensed. Optional: leave it unset and the tax is coded to the same account as the largest line on the bill.
  • Default purchase tax code — every company file outside the US. The code an invoice gets when it states tax but names no code of its own. Under it, By province or state gives each province or state where you have properties a code of its own. A property's province or state code comes first. The workspace default covers the rest only while all your properties are in one province or state. With properties in more than one, a province or state with no code of its own gets no default, and a person picks the tax code on the invoice screen. A code a person chose never changes. Without a tax code, a taxed invoice waits; Pick a tax code on the Exports screen opens it.

A record created in QuickBooks since the lists were last read cannot be matched yet — a match can only point at a record we have already pulled, so a typo can never become an ID no bill can post against. Read lists from QuickBooks Online again and the new record appears in the picker.

5. Prove it worked

Four checks, in the order they cost you time.

Test connection, on the card you just connected, asks QuickBooks to identify itself and answers with the company, the country and the edition it reported. That is what tells an expired token apart from a bad afternoon at Intuit.

The checklist on Exports → Ledger setup carries five steps read off the connection itself: app authorized, with the scope that was granted; company selected, by name; chart of accounts read, with the account count and the time of the last read; vendor mapping reviewed; and a test bill posted. That last step closes only when a batch has really succeeded — posting a test bill from that button arrives in a later release, so the way to close it is a real export.

The mapping panel, with nothing outstanding, reads "Everything in use is matched. Approved invoices can post to your ledger." Anything else is counted at the top of the panel and linked to the row that fixes it.

The audit trail. Audit Log carries a Connector Connected entry naming the company, recorded against System rather than a person. That is deliberate: the return leg is a browser redirect carrying no session, and naming somebody we cannot identify would be worse than admitting we cannot.

Then post something real. Approve one invoice, open Exports, and press Post approved invoices. A succeeded batch names the ledger and the bill; a failed one names the cause per invoice and offers the fix beside it.

Export history with a failed batch expanded, each held invoice naming its reason and the control that fixes it.
The first run is the real test. A batch that failed names the cause invoice by invoice — an unmatched vendor here — and a retry replays the same bills rather than posting new ones.

What a posted bill carries

The bill is created against the matched vendor, with one line per invoice line item, or a single line when the invoice has none.

The invoice date and due date read off the document become the transaction and due dates, and the invoice number becomes the reference, truncated to the 21 characters QuickBooks allows. Each line carries the account its GL code is matched to — or your default expense account — and its property as a class where the file tracks classes. A private note records an inletAP marker with the document reference and the property name. The bill header carries the ownership entity's location where the company tracks locations, and your mapped Accounts payable account where one is set. The currency is sent only when it differs from the company's home currency.

The source document goes up too, where the invoice arrived with one, and that upload is best-effort by design: a failure is logged and the bill is left exactly as it posted.

Tax splits by country. Outside the US, the stated tax is carried by a matched purchase tax code. In the US there is no purchase tax engine to work it out, so the stated tax is written as an extra bill line described "Sales tax" — coded to your sales tax expense account if you set one, and otherwise to the account of the largest line on that bill.

The arithmetic is checked before anything is sent. Line items are pre-tax and the invoice amount is the grand total, so the lines must add up to the total less tax, within a penny. If they do not, the item is held back with both figures named rather than posting a bill that settles at the wrong number. Outside the United States the same applies to stated tax with no matched tax code: your ledger works the tax out from the code, so without one posting would understate what you owe the vendor, and the invoice waits.

Held items appear in the batch with the reason and the next move — match this vendor, match the GL code, open the invoice — and the export itself is not treated as a failure for the invoices that did post.

Classes, locations and customers

inletAP sends the property as the class on each bill line. Class is a per-line field on a QuickBooks bill, which is what lets one bill carry several properties.

A location (DepartmentRef) is sent too, when the company tracks locations — but a location is a bill header field, one per bill, so it comes from the ownership entity that bill is for and cannot vary by property within a single bill. A customer reference is sent on a line only where an allocation names one. Coding a line to a unit as a sub-customer is a QuickBooks-only shape and has no equivalent in any other ledger we post to. Nothing is ever coded to a QuickBooks Project.

So if your books code properties as locations rather than classes, per-property coding cannot reach a split bill. Model properties as classes or as sub-customers, split at the entity level, or keep exporting a CSV alongside. See posting to several companies.

One invoice cannot span QuickBooks companies. Where it belongs in two sets of books, it fans out — one bill in each — and the document says so.

The external ID that comes back

When a bill is created, inletAP records the QuickBooks ID it was given against the document, along with the concurrency token and the request identifier used to post it.

That request identifier is minted before the first attempt and reused on every retry of the same post, so a dropped connection replays rather than creating a second bill. It is the difference between a connection you can retry confidently and one where a timeout means a phone call to the vendor about a double payment.

The practical effect: for any invoice you can answer "where did this end up" with an ID rather than a search.

When the connection says action required

The state is not an error message, it is a description. Reconnect from Settings → Connectors, which repeats the same authorization round trip and keeps your existing matches.

While the connection is not connected, an attempt to post is refused with a sentence saying why, rather than creating a batch full of held invoices for you to sort out afterwards. Approved invoices are not lost meanwhile; they stay approved and go into the next batch.

Recheck plan features, beside Test connection, reads the company's capabilities again. That is what you use after switching class tracking on or upgrading the edition, and the button is offered while there is a finding to clear or while the capabilities have never been read.

Where to go next

View this page as markdown

Last updated