Blog

Syncing QuickBooks job costs into Autodesk Build

Your bookkeeper already codes every dollar to a job in QuickBooks. Your PM already manages the budget in Autodesk Build. The integration's only job is to carry the first into the second without either person changing how they work — and without creating a second version of the truth.

If you run a construction company with a bookkeeper in QuickBooks and project managers in Autodesk Build, you've had this conversation: the PM asks what's been spent on a job, and the answer is a spreadsheet somebody exported on Friday. Cost Management in Autodesk shows the budget beautifully and knows almost nothing about actual spend, because actual spend lives in the accounting file.

This post is the mechanic of joining those two, written for the person who signs the checks. It's the design we ship in the QuickBooks–Autodesk sync, but the reasoning matters more than the product — build it yourself and these are the same walls.

Why the same dollar lives in two systems

Be precise about who owns what — almost every failed integration in this category got this wrong.

QuickBooks owns the dollar. A receipt from a lumber yard, a rental invoice, a fuel charge — the bookkeeper enters it, attaches it to a customer:job, tags it with a class, and posts it to an expense account. In most construction files, that chart of accounts is already job-aware: there's a COGS block for project costs, a Job Materials account that absorbs the big-box store runs, separate lines for rentals and fuel. That account is the category; the class is the code your bookkeeper actually says out loud. This is a real ledger with a tax return hanging off the end of it, and nothing should ever write to it except a human who is responsible for it.

Autodesk Build owns the budget. Cost Management holds the budget structure, the cost codes, the contracts, the change orders. The PM's job is to know whether the concrete line is tracking. They don't want to know what an expense account is, and they shouldn't have to.

The gap between them isn't data, it's classification. The bookkeeper classifies for the tax return. The PM classifies against the budget. Those are different taxonomies, and any tool that pretends they're one taxonomy will force somebody to lie.

The actual workflow, step by step

Here is the whole thing, and the point is how boring it is:

  1. The bookkeeper codes spend in QuickBooks exactly as she does today. Customer:job, class, expense account. No new screen, no second entry, no "also log it in the other system." If the integration adds one step to her day, it will be abandoned by month three.
  2. A job in Eco Ops maps a QuickBooks customer to an Autodesk project. One row: this customer:job is that ACC project. This is the only piece of setup that requires judgment, and it is done once per job.
  3. An hourly sync reads the newly coded transactions and, for each one on a mapped job, creates an Expense on that project's Cost Management. It lands unclassified — attached to the project, with the vendor, amount, date, and a link back — but not assigned to a budget line.
  4. The PM classifies it against the budget inside Autodesk, in the screen they already use, with the cost codes they already built. The expense they're classifying is a real dollar from the real ledger, not a number somebody typed twice.

That fourth step is the part people push back on: "can't it just pick the budget line?" It can guess, and it will be wrong often enough that the PM stops trusting the feed — and a cost report nobody trusts is worse than none, because it gets argued with in meetings. Landing unclassified is a feature: it puts the decision in front of the one person who can make it, in the tool where it belongs, and costs them four seconds.

One-way flow from the QuickBooks ledger to Autodesk Cost Management The bookkeeper codes a transaction in QuickBooks; a ledgered sync creates an unclassified expense on the mapped Autodesk project; the project manager classifies it against the budget. Unmapped transactions go to a review queue instead of being dropped. QuickBooks Bookkeeper codes spend customer:job + class + expense account OWNS THE DOLLAR Sync ledger Job map: customer → project Marks the txn id BEFORE it pushes anything Autodesk Build Expense appears on the project, UNCLASSIFIED PM assigns the budget line OWNS THE BUDGET No job mapping yet Held as pending and shown in a review queue — never dropped Nothing ever writes back into the accounting ledger.
One direction only: the ledger feeds the cost system, the cost system never feeds the ledger.

Why the sync must be one-way

The obvious feature request is two-way sync. Resist it, and understand why, because the reason is not technical laziness.

A two-way sync between an accounting ledger and a cost-management system creates conflicts that no one has the authority to adjudicate. Suppose the PM reclassifies a $4,200 expense from Site Work to Concrete inside Autodesk. What should happen in QuickBooks? The class? The expense account? Neither — the bookkeeper chose that account for tax reasons that have nothing to do with the budget structure. Now suppose she recodes the same transaction the following week during month-end review. Which edit wins? The later timestamp? The human with more seniority? There is no correct answer, which means whatever the software picks will silently overwrite somebody's deliberate decision. And because both systems are then "authoritative," neither person can ever be sure what they're looking at.

One-way sync dissolves the question. The ledger is upstream and final. Autodesk is a downstream view enriched with the PM's classification. The PM can reclassify all day; nothing lands back in the books. If a transaction is genuinely miscoded, the fix happens where the dollar lives — the bookkeeper corrects it in QuickBooks, and the corrected version flows down. One system of record, one direction, no arbitration. And "no external software writes to our general ledger" is a sentence you want to be able to say to your CPA without qualification.

Idempotency: the boring detail that decides everything

An hourly sync runs about 8,760 times a year. It will time out mid-write, get rate-limited halfway through a batch, get "sync now" clicked twice, and drop the network between "Autodesk accepted this expense" and "we recorded that it did."

If the sync keys on anything but the source transaction's own id, each of those becomes a duplicate cost. Duplicates are nasty because they're plausible — two $840 charges from the same rental yard in one week is completely normal, so nobody catches it, and the job looks over budget for reasons no one can explain.

The rule: keep a ledger row per source transaction id, and write that row before you push, not after. Mark it first, then attempt the push. If the push fails, the row is already there marked as failed and gets retried. If the process dies after the push but before the confirmation, the retry sees the existing row and does nothing. The worst case of marking first is a transaction that needs a retry; the worst case of marking after is a duplicate you'll never find. Those are not symmetrical risks.

If you want to see this running against your own QuickBooks file and your own Autodesk hub rather than a slide, book a demo — bring one job and we'll trace a single receipt end to end.

Unmatched transactions must be loud, not dropped

Every real sync has leftovers: a transaction coded to a customer:job with no Autodesk project, a job the office set up in QuickBooks on Monday that nobody created in ACC, or a name that reads as one job to a human and two strings to a computer — "Riverside HS Field 2" versus "Riverside High School — Field #2." Three things software can do with those, and only one is acceptable.

  • Drop them. Silent, and therefore the worst option. Your job cost is now quietly incomplete and you will find out during a closeout meeting.
  • Guess. Fuzzy-match the names and hope. This is how a $30,000 material buy ends up on the wrong project, and the damage is worse than dropping, because now the number is confidently wrong on two jobs at once.
  • Hold and surface. Match on an exact normalized name only. Anything ambiguous becomes a suggestion a human clicks to confirm, and anything unmapped stays pending with a visible count. When the mapping appears, the held transactions post themselves on the next pass.

That pending count is the single most useful number in the whole integration. It's the honest answer to "is my job cost complete?" — and a tool that can't show you that number is asking you to take its word for it. This is the same discipline we apply to field receipts: nothing gets guessed onto a job, and nothing disappears.

Setup traps: zero hubs and account:write

Two failures eat an afternoon each, and both look like bugs when they're actually permissions. Write them down before you start.

Your app authenticates fine and returns zero hubs

You complete the Autodesk Platform Services OAuth flow, you get a valid token, you call the hubs endpoint, and you get back an empty list. Nothing is broken. In Autodesk Construction Cloud, a third-party APS application has to be explicitly approved inside the client's own ACC account — Account Admin → Settings → Custom Integrations, where an account administrator adds the app by its client id and grants hub access. Until that happens, a perfectly valid token can see nothing, because from ACC's point of view your app isn't a participant in that account.

Same symptom, second cause: the user who authorized the connection must actually be a member of that account. A personal Autodesk login that was never added to the company account returns the same empty list.

Practical consequence: when a tool sees zero hubs it should say so in English — "this app is not approved under Custom Integrations in your ACC account; here is the client id to add" — rather than rendering an empty project list.

Creating projects needs account:write, and tokens don't upgrade themselves

Listing and importing existing ACC projects works with read-only scope. Creating a project from your side — so the office can set up a job once and have it appear in Autodesk — requires the account:write scope. The trap is that an already-connected account keeps whatever scope its token was issued with. Adding the scope to your authorization URL changes nothing for existing connections; project creation keeps returning 403 while everything else works, which is a genuinely confusing symptom.

The fix is a single human action: an ACC account administrator disconnects and reconnects Autodesk once. Plan for it in your rollout — it needs a specific person with account-admin rights, and it is worth booking five minutes of their time in advance rather than discovering the requirement during a live demo.

When you don't need this at all

Honest answer: if you run two or three jobs at a time and your bookkeeper is also the PM, a monthly QuickBooks job-cost report is fine. This integration earns its keep when the jobs outnumber what one person can hold in their head, and when the person who sees the budget isn't the person who sees the invoices — usually north of a dozen active jobs, or the first time you hire a PM without QuickBooks access.

If that's where you are: the wider shape is on the construction solution page, a contractor's month is walked through in the job-costing story, and everything else we connect to is listed under integrations.

Next step

See your own job costs land in Autodesk.

Book a 20-minute demo — we'll map one of your QuickBooks jobs to one Autodesk project and follow a single coded transaction all the way to Cost Management.

Construction is quoted per site and headcount · $500 one-time setup · no contracts