GoHighLevel API & Webhooks: Custom Objects & Approval Flows
The GoHighLevel API is where the platform stops being a CRM and starts being a system you can shape. Connect it well and you can sync records to your own database, push data into billing tools, model business objects that don’t fit a contact, and route risky actions through a human before anything sends. Connect it badly and you get duplicate contacts, leaked tokens, and automations firing messages nobody approved.
This is a developer-leaning guide, but you don’t need to be a backend engineer to follow it. We’ll cover the API v1 sunset and the move to v2, when to use OAuth 2.0 versus Private Integration Tokens, how inbound and outbound webhooks actually work, what Custom Objects unlock, and—most importantly—how to build an approval gate so your automations never auto-send something they shouldn’t.
The API v1 sunset and the move to v2
If you built anything against the GoHighLevel API before 2025, this matters to you. API v1 reached end-of-support on 31 December 2025. Existing v1 connections may still respond, but there are no fixes, no new endpoints, and no support behind them. Anything you build today should target API v2.
API v2 isn’t just a version bump. It uses a modern authorization model, exposes far more of the platform (Custom Objects, conversations, payments, and more), and is the only surface that will keep getting attention. If you’re still running v1 integrations, treat migration as overdue maintenance rather than a someday project—each one is a silent single point of failure.
OAuth 2.0 vs Private Integration Tokens
API v2 gives you two ways to authenticate, and choosing the right one saves a lot of pain later.
- OAuth 2.0 is for marketplace apps and anything that needs to act across many sub-accounts. The app owner installs it, you receive access and refresh tokens, and your code refreshes them on a schedule. This is the path when you’re building a product other agencies will install, or any integration that spans multiple locations.
- Private Integration Tokens (PIT) are static tokens scoped to a single sub-account (or the agency level). They behave like a fixed OAuth 2.0 access token, but they do not auto-refresh—you rotate them manually. They’re ideal for internal tools, a single client’s automations, or a server script that only ever touches one location.
The rule of thumb: if it’s your own internal build for one account, reach for a PIT. If it’s a distributable app or it spans accounts, use OAuth 2.0. A few practical notes on PITs—you can create up to five per level, you put the token in the Authorization header like any access token, and you should rotate them on a schedule (every 90 days is a sensible default). Because they don’t expire on their own, a leaked PIT stays valid until you revoke it, so store them as secrets, never in client-side code or a public repo.
Webhooks: inbound triggers and outbound actions
Webhooks are how GoHighLevel talks to the rest of your stack in real time, and there are two directions to keep straight.
- Inbound webhooks (to start a workflow): an external system POSTs to a GoHighLevel webhook URL, which fires a workflow trigger. This is how you let a form on your own site, a payment processor, or a third-party app kick off automation inside GHL without a single manual step.
- Outbound webhooks (to push data out): a workflow runs a webhook action that POSTs contact and event data to an endpoint you control. Use this to sync a new lead into your warehouse, notify a Slack channel, trigger a billing event, or hand off to a custom service that does work GHL can’t do natively.
For heavier logic, GoHighLevel’s custom code action lets you run JavaScript inside a workflow—reshaping a payload, calling an external API, or computing a value before the next step. Treat it like any other code: validate inputs, handle the case where a field is missing, and don’t assume the upstream system always sends clean data. Whenever you accept an inbound webhook, verify it’s genuinely from the source you expect rather than acting on any POST that arrives.
Custom Objects: modeling what contacts can’t
Out of the box, GoHighLevel thinks in contacts and opportunities. That’s fine until your business revolves around something else entirely. Custom Objects let you model records that aren’t people—each with their own fields, and linked back to the contacts they relate to.
- Properties: a real-estate operation can track listings as records—address, price, status, beds, square footage—and associate each with buyers and sellers.
- Vehicles: a dealership or service shop can store VIN, make, model, mileage and service history against the owner contact.
- Policies: an insurance agency can model policies with carrier, premium, renewal date and coverage type, then automate renewal reminders off those fields.
- Projects: an agency or contractor can track projects with scope, stage, budget and deadline, linked to the client and the team.
The payoff is that automations and reporting can run on the real object instead of being crammed into contact custom fields. A renewal workflow that reads a policy’s renewal date is far cleaner—and far harder to break—than one juggling a dozen text fields on a contact.
Build an approval workflow so automations never auto-send
Here’s the failure mode that costs agencies real trust: an automation fires a text or email to a client, a contract, or a high-value lead—without anyone reviewing it. Once it sends, it’s sent. The fix is a human-in-the-loop gate, and GoHighLevel gives you everything you need to build one inside a workflow.
The pattern looks like this:
- Stop before the risky step: instead of sending the message immediately, the workflow first sends an internal notification to the team—an email, an internal SMS, or a Slack ping via outbound webhook—with the record details and what’s about to go out.
- Wait for a decision: add a wait step and a condition that checks a status field, for example an Approval Status custom field set to ‘Approved’. The workflow holds until that flag flips.
- Flip the flag manually: a team member reviews the record and changes the status field (or clicks an approval link that updates it). Only then does the condition pass and the send proceed. If it’s set to ‘Rejected’ or the wait times out, the workflow branches away from sending entirely.
This is the single most valuable safeguard we add to client systems. It turns ‘the automation sent something wrong’ into ‘the automation paused and asked.’ For anything irreversible—outbound client messages, payment actions, contract delivery—the approval gate should be the default, not an afterthought.
Best practices
- Migrate off v1: build new work on API v2 and retire any lingering v1 calls before they fail quietly.
- Match auth to scope: PIT for single-account internal tools, OAuth 2.0 for multi-account or marketplace apps.
- Treat tokens as secrets: never expose a PIT client-side, rotate on a schedule, and revoke immediately if one leaks.
- Make webhooks idempotent: the same event can arrive twice, so design endpoints that won’t double-create records.
- Gate risky sends: put an approval condition in front of any outbound message or irreversible action.
- Validate everything: in custom code, handle missing fields and verify inbound payloads before you act on them.
FAQ
Is GoHighLevel API v1 completely shut off?
It reached end-of-support at the end of 2025. Some calls may still respond, but there are no fixes or support behind them, so you should migrate to v2 and not rely on v1 for anything new.
Do I need OAuth if I’m only working with one account?
No. For a single sub-account, a Private Integration Token is simpler and avoids the refresh-token cycle. Save OAuth 2.0 for multi-account and marketplace builds.
Can I really stop an automation from sending without review?
Yes. A wait step plus a condition on a status field creates a reliable approval gate, so nothing sends until a human flips the flag.
If you want the GoHighLevel API, webhooks, Custom Objects and approval workflows built properly—secure, v2-native, and safe from runaway sends—that’s exactly what our Vibe Coding custom development service is for. Tell us what you’re trying to model and automate, and get in touch—we’ll scope a build that does it right the first time.
Need help implementing this in GoHighLevel?
Our team builds, automates, and scales GoHighLevel systems for agencies every day. Book a free call and we'll map out exactly what to ship next.
Book a free call