Skip to main content
manufacturing

ERP to GoHighLevel CRM Integration

How Rogue built a bidirectional ERP to GoHighLevel CRM integration for refrigerated van manufacturer CoolKit, syncing 100,000+ deals and quotes in near real time.

Visit Coolkit
100,000+
Deals & quotes synced

37,153 deals and 65,549 quotes reconciled between the ERP and GoHighLevel in the historical backfill

98%
Backfill coverage

Share of historical deals and quotes matched automatically during the CRM backfill

~6 sec
Sync latency

A new GoHighLevel contact reaches the ERP tables in about six seconds, well under ten, with no overnight batch

Live & reversible
In production

Running on real customer, quote, and deal data with a documented go-live governance pack and one-command reversibility

The Challenge

CoolKit ran a GoHighLevel CRM alongside a legacy MS SQL Server and Access ERP, but the two never talked to each other. Sales worked in the CRM while quotes, deals, and customer records lived in the ERP, so data went stale, contacts duplicated, and no one had a single accurate view of a 35,000-customer book.

The Solution

We built a bidirectional integration that keeps the on-prem SQL Server ERP and the GoHighLevel CRM in near-real-time sync. A Vercel-hosted webhook bridge writes contacts, opportunities, custom objects, and notes into GoHighLevel via its v2 API, while an on-prem QueueProcessor and SQL Server triggers push ERP changes straight back. A dedup-safe resolution chain and a full historical backfill reconciled the two systems.

The challenge: a CRM and an ERP that never talked

CoolKit builds custom refrigerated van conversions for UK fleet operators, dealers, and direct buyers, a business of roughly 35,000 customers. It ran a GoHighLevel CRM for sales on one side and a legacy MS SQL Server and Access ERP for quoting and operations on the other.

The two systems had no connection. Sales updated the CRM while quotes, deals, and customer records were created and changed in the ERP, so records drifted out of date, contacts duplicated, and neither system held the full truth about a customer.

What we built: bidirectional near-real-time sync

We built an integration that keeps the on-prem ERP and GoHighLevel continuously in sync, in both directions:

  • Webhook bridge: a Vercel-hosted service that calls the GoHighLevel v2 API to create and update contacts, opportunities, custom-object records, and notes.
  • On-prem QueueProcessor: a TypeScript service under PM2 that polls a SQL Server queue plus a neutral Supabase queue, then writes results back to SQL Server.
  • SQL Server triggers: ERP changes are emitted onto the queue the moment they happen, so updates flow to the CRM without a batch window.
  • Dedup-safe resolution: a create-or-match chain (person id, then customer id, then email, then phone) that resolved a real duplicate-contact incident and stops the CRM re-forking records.

We also configured the Sales (6 stages), Operations (7 stages), and Customer Service pipelines in GoHighLevel, and ran a full historical backfill so the CRM opened with the ERP’s real deal and quote history rather than a blank slate.

The result

The backfill reconciled 37,153 deals and 65,549 quotes, over 100,000 records, at 98% automatic-match coverage. Day to day, a change on either side lands on the other in about six seconds. It runs in production on live data, backed by a go-live governance pack and one-command reversibility.

Running fragmented sales and ERP systems? Let’s talk.

Facing similar challenges?

Tell us what you're working on and we'll show you how we'd approach it.