An asphalt paving contractor came to Tiempo with a problem a lot of trade businesses have. Sales and marketing lived in GoHighLevel, operations lived in JobTread, and the two were held together by a white-labelled GoHighLevel install with an integration that copied every JobTread job status into the sales pipeline. That gave the sales pipeline more than twenty stages. Staff weren’t sure which system to edit, so they edited both, and over time the two drifted apart. We replaced it with a stock GoHighLevel sub-account, a JobTread-first setup, and a connector between the two that we built and run.
This post is about what it takes to keep two systems of record in agreement every day, with non-technical staff working in both. It goes a fair bit past connecting a Zapier trigger.
What it does
| Stage of the customer lifecycle | Where it happens | What the connector does |
|---|---|---|
| Lead comes in | GoHighLevel (contact and deal in the Sales pipeline) | Nothing yet. Junk gets filtered in the CRM, not the ops system. |
| Deal reaches “Ready for Estimate” | A rep drags the card | Creates the customer, the site and the job in JobTread in one shot, and links the records on both sides. |
| Site visit booked | GoHighLevel calendar | Moves the deal and sets the JobTread status to “Appointment Set”. A cancellation in JobTread flags the deal and opens a task for the rep. |
| Proposal sent, approved, signed | JobTread documents | Proposal approval marks the deal Won, stamps the signature time, creates a Project record in GoHighLevel, and hands the job to ops. |
| Job in production | JobTread | Status, schedule, actual dates, contract value and balance due mirror into the Project. Sales can see it, and can’t edit it. |
| Job complete | JobTread status “Send Review” | Computes the property’s next maintenance date from the service type, so the marketing side can run its own reminders. |
| Lost | Either system | Lost in GoHighLevel needs a reason. Lost in JobTread shows up in GoHighLevel as “Set in JobTread”. Nothing is ever deleted. |
It also mirrors every message with the customer (SMS, email, call notes) into the JobTread job as a comment, so the crew can read the sales history without a CRM login.
The rule that made it work: one owner per field
Copying everything in both directions means the two systems will eventually disagree, and then nobody knows which one is right. So the design here starts from a single question for every field: who owns it?
- JobTread owns companies, contacts, properties, and everything about a job after it exists: status, dates, value, invoices.
- GoHighLevel owns the sales pipeline before signature, and all the marketing attributes. Tags, source, campaigns, do-not-disturb.
- The connector owns the links between records and the values it derives, like the next maintenance date.
Every synced field has a named owner, written down in one place. If someone edits a field in the wrong system, the connector puts it back and opens a task on the contact saying where that edit belongs. We would rather the software enforce this than ask staff to remember a rule.
A status map, not a status copy
JobTread has close to twenty job statuses. Sales does not need that many stages. The Sales pipeline has nine: New Lead, Contacted, Ready for Estimate, Site Visit Scheduled, Estimating, Proposal Sent, Follow-Up, Won, Lost.
The mapping between the two lives in one approved list, and it’s a lookup, not a sequence. Deals can skip stages in either direction. Each row says which side is allowed to drive it. Some statuses only flow JobTread to GoHighLevel (ops detail sales doesn’t need), a few flow both ways, and “Won” is set by the connector only, never by a human on either side. When several JobTread statuses map to one stage, one of them is marked canonical and that’s what gets written when the change comes from the CRM.
Post-signature, the deal is frozen and a separate Project record takes over. One deal can produce several Projects when a job gets split. Keeping the sales stage and the production status separate is most of what makes this work.
Nothing fails silently
JobTread was live with real customers for the entire build, so the connector was only ever allowed to change what had been agreed in advance, one kind of change at a time. Every change it makes, and every one it skips, is written down where we can see it. A nightly check compares the two systems and lists anything that has drifted, so a mismatch gets caught the next morning instead of the next quarter.
When this is worth doing, and when it isn’t
Reach for a custom connector like this when:
- Both tools are staying. GoHighLevel for sales and marketing, JobTread for estimating and production, and the business has real reasons for each.
- Staff aren’t technical and need the two systems to simply agree, without anyone being the human sync.
- The existing integration is a status copy and it’s already causing double entry and stale boards.
If you have one system and a single feed, you don’t need this. A Zap or a small script will do. And if the business hasn’t decided which system owns what, that conversation comes before any code. It’s the part we spend the most time on with the client.
If you run GoHighLevel and JobTread
We’ve now built the full round trip between the two: leads to jobs, bookings to appointments, proposals to Won, production to Projects, messages to job comments, and the nightly check that the two still agree. If you’re on that pair of tools and someone on your staff is currently the sync, drop me a line.