GoHighLevel connection (run for you, not by you)

Each account is bound to its own GoHighLevel sub-account with its own location id and private integration token, wired by the platform operator so the builder never has to touch the CRM.

What it is

Two credentials — a location id and a private integration token — stored encrypted on the account row. Every GHL call anywhere in the app resolves them per-account, so one builder's contacts, media and conversations can never be read or written with another's identity. Legacy env-var credentials exist only as a bootstrap fallback for the original single-tenant account.

Also called: GHL integration · connect my CRM · HighLevel sub-account · location id and token

See it
GoHighLevel connection (run for you, not by you)
🔒ridgelinepostframe.com/project/gohigh762
Hobby Shop
Framing · on schedule
Settings → Integrations GoHighLevel card with a masked token, a green connected dot, and a 'Verified against location' line. Rendered by src/components/settings/IntegrationsTab.tsx. Sample data — no customer information appears here.
How it works
  1. 1Operator (or an admin, if the section is visible) enters the location id and private integration token.
  2. 2The token is verified against the claimed location before anything is stored.
  3. 3The token is AES-encrypted and written to the account row.
  4. 4Every GHL caller resolves credentials through getOrgGhlCredentials with a 60-second cache.
  5. 5Saving invalidates the cache so the next call uses the new values.
Why we built it

GoHighLevel has no API to mint a per-location token, which shapes the whole flow — ghlAgency.ts records it: 'HighLevel has no API to create a per-location Private Integration Token (PIT). After the location exists, WE (the platform operator) create a PIT in the new sub-account UI and paste it into the tenant's GHL setup panel.' The same file explains why the builder never gets a CRM login: 'We intentionally do NOT create a GHL *user* for the builder — GHL auto-sends new users a GHL-branded welcome email with no API flag to suppress it, and our builders never see GHL (we operate it for them).'

The problem
  • Multi-tenant CRM access needed per-account credentials, not one shared key.
  • Builders should not have to operate a CRM to use the platform.
Sound familiar?
What you get
Each builder's CRM data is reached with their own identity only.
The builder never sees or logs into the CRM.
Credentials can be rotated without a deploy.
What's inside
Hide an integration without disconnecting it
The platform operator can hide the GoHighLevel, Stripe, SmartBuild or QuickBooks sections from a builder's Settings screen while the connection keeps working underneath.
A CRM token is checked against the account it claims
Before a CRM token is ever stored, it is called against the location id it was entered with — a token belonging to a different business is rejected outright.
One-click CRM wiring with automatic stage mapping
Pasting the sub-account token wires the whole integration: it finds the sales pipeline, name-matches every stage onto the platform's stages, and flips the account to connected with no dropdowns to fill in.
CRM sub-account created from a template at signup
A new builder gets their own CRM sub-account created through the agency API with the template snapshot loaded, so their pipeline and stages exist before anyone logs in.
Server-side CRM proxy, scoped per account
All CRM traffic goes through a single authenticated server route that injects the caller's own location id and token, so credentials never reach the browser and calls can never be aimed at another account.
Photos filed into the CRM media library, in folders
Images uploaded from the platform land in the account's own CRM media library, organised into a folder path that is created on demand and cached.
One engine pulling new CRM leads onto the board
A single scheduled job pulls every connected account's CRM sales pipeline, takes only the opportunities sitting in that account's mapped new-lead stage, and mints the ones not already held.
Your board is the source of truth, not the CRM
Pipeline state flows one way — leads and messages come in from the CRM, but stage, value and lifecycle are owned here and never written back.
Customer email and texts sent from the builder's own CRM identity
When GoHighLevel carries a channel, the message goes out through that builder's own CRM location — their sender identity, their deliverability, their conversation thread.
Prove the CRM connection works before trusting it
A validation step fetches contacts and opportunities for both pipelines with the new credentials and reports the counts, so a connection is confirmed end to end rather than assumed.

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 →