Customers created in the books, once

A customer is resolved from cheapest to most expensive — cached id, then email, then display name — and a duplicate-name rejection resolves to the existing record instead of failing.

What it is

Two entry points: a contact-centric one that caches the accounting id back onto the contact, and a field-based core with no dependency on the contacts table, used by the project sync where the legal details come from the signed intake form. Structured legal information — display name, given and family name, company, email, phone, billing and shipping address — can be supplied to enrich the record.

Also called: duplicate customer in QuickBooks · 6240 duplicate name · find or create customer · customer already exists in quickbooks · duplicate customer name · add customer to quickbooks

See it
Customers created in the books, once
Area
Integrations
Group
QuickBooks
System
QuickBooks
Solves
3 named problems
01The cached accounting customer id on the contact is used when present — no API call.
02Otherwise a query by primary email address.
03Otherwise a query by display name, which catches customers created directly in the accounting package.
A resolution ladder graphic: cache → email → display name → create, with the duplicate branch looping back to 'matched existing'. Sample data — no customer information appears here.
How it works
  1. 1The cached accounting customer id on the contact is used when present — no API call.
  2. 2Otherwise a query by primary email address.
  3. 3Otherwise a query by display name, which catches customers created directly in the accounting package.
  4. 4Otherwise a create; a duplicate-name fault triggers a re-query that resolves to the existing record.
  5. 5Every interaction is written to the sync log.
Why we built it

The lookup order is documented as cheapest-first, and the duplicate handling is explicit: 'On the QBO "6240 Duplicate Name Exists" fault we re-query by DisplayName and resolve to the existing record, so create is idempotent under retries / races.' The second entry point exists because 'the legal info comes from the estimate form and the estimate_links.contact_id is often a GHL id that has no row in contacts.'

The problem
  • Retries and races created duplicate customer records.
  • Customers created directly in the accounting package were not matched.
  • The legal name on a signed intake form had nowhere to flow from.
Sound familiar?
What you get
One customer record per person, matched on the cheapest available signal.
The books carry the legal name and address the customer actually signed.

See it on your own jobs

Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.

or keep browsing features →