Integrations⏱ 4 min read

GoHighLevel API Integration: Endpoints, Webhooks & Authentication Guide

Discover what is possible with the GoHighLevel REST API and custom webhooks, from Stripe payment sync to Shopify customer creation and external CRMs.

Muhammad Bilal ShakeelWritten by Muhammad Bilal Shakeel
β€’Published: 2026-08-17β€’Updated: 2026-09-18
Advertisement

While GoHighLevel offers powerful visual workflow builders and native triggers, integrating GHL with bespoke web applications, enterprise ERPs, and custom storefronts requires leveraging the GoHighLevel REST API v2. HighLevel's modern API architecture provides programmatic control over contacts, opportunities, calendar appointments, custom values, and conversational messages. This developer implementation guide covers OAuth 2.0 authentication, Private Location API keys, core CRM endpoints, webhook subscription verification, and rate-limiting best practices.

⚑ HighLevel Developers API 2.0 Specifications

The HighLevel API 2.0 enforces modern architectural standards:

  • Base URL: https://services.leadconnectorhq.com
  • Required Header: Version: 2021-07-28
  • Standard Rate Limit: 100 requests per 10 seconds per location. Exceeding this returns HTTP 429 Too Many Requests.

1. Authentication: Private Location Keys vs. OAuth 2.0

Developers can authenticate with the API through two distinct mechanisms depending on use case:

Private Location Access Token (Direct Backend)

Generated within Settings β†’ Business Profile β†’ General β†’ API Key. Ideal for single-business custom website form integrations, cron jobs, and private webhook endpoints. Passed as a Bearer token in the Authorization header.

OAuth 2.0 App Marketplace Protocol

Required for multi-tenant SaaS applications and agency marketplace apps. Utilizes standard authorization code flow: redirecting users to approve scopes, receiving an authorization code, and exchanging it for an access token with a 24-hour expiration and rolling refresh token.

2. Core Endpoint: Upserting Contacts with Custom Fields

When synchronizing external web form leads into GHL, using the /contacts/upsert endpoint ensures existing records are updated without creating duplicate entries:

// Node.js: Upsert Contact via HighLevel API 2.0
const response = await fetch('https://services.leadconnectorhq.com/contacts/upsert', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_LOCATION_ACCESS_TOKEN',
    'Version': '2021-07-28',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    locationId: 'loc_9876543210',
    firstName: 'Alex',
    lastName: 'Reynolds',
    email: 'alex.reynolds@example.com',
    phone: '+14155552671',
    tags: ['Web Inbound', 'E-Commerce Lead'],
    customFields: [
      { id: 'custom_field_monthly_revenue', value: '$50k-$100k' },
      { id: 'custom_field_store_url', value: 'https://brandexample.com' }
    ]
  })
});
const data = await response.json();
console.log('Upserted Contact ID:', data.contact.id);

3. Rate Limiting Governance & Exponential Backoff

When syncing high-volume external data feeds into GHL, developers must handle the 100 requests / 10 seconds rate limit gracefully. Implement an exponential backoff retry loop in your API service layer:

async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const res = await fetch(url, options);
    if (res.status === 429) {
      const waitTime = Math.pow(2, attempt) * 1000 + Math.random() * 500;
      console.warn(`Rate limited (429). Retrying in ${Math.round(waitTime)}ms...`);
      await new Promise(r => setTimeout(r, waitTime));
      continue;
    }
    return res;
  }
  throw new Error('Max retries exceeded on HighLevel API request.');
}

4. Complete Python Integration Example (REST API v2)

For backend engineering teams developing microservices in Python, here is a clean, resilient integration pattern for contact synchronization:

import requests, time

API_BASE = "https://services.leadconnectorhq.com"
HEADERS = {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Version": "2021-07-28",
    "Content-Type": "application/json"
}

def upsert_ghl_contact(location_id, email, phone, name):
    payload = {
        "locationId": location_id,
        "email": email,
        "phone": phone,
        "name": name,
        "tags": ["API Inbound", "Verified Customer"]
    }
    res = requests.post(f"{API_BASE}/contacts/upsert", json=payload, headers=HEADERS)
    if res.status_code == 200:
        return res.json()
    elif res.status_code == 429:
        time.sleep(2)
        return upsert_ghl_contact(location_id, email, phone, name)
    raise Exception(f"GHL API Error {res.status_code}: {res.text}")

5. Webhook Signature Verification in Node.js

When receiving inbound webhooks from GoHighLevel in custom serverless microservices, verifying the authenticity of incoming payloads prevents unauthorized spoofing:

const crypto = require('crypto');

function verifyHighLevelWebhook(req, sharedSecret) {
  const signature = req.headers['x-ghl-signature'];
  if (!signature) return false;

  const hmac = crypto.createHmac('sha256', sharedSecret);
  const digest = hmac.update(JSON.stringify(req.body)).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest));
}

3. Private Integration Apps vs. Marketplace OAuth2 Architecture

GoHighLevel Developer Platform v2 supports two distinct integration architectures based on your application scope:

Private Integrations (Sub-Account Scoped)

Configured in Settings β†’ Custom Values / Developers. Generates a static API Bearer token scoped specifically to one location ID. Ideal for single-client proprietary scripts, bespoke internal ERP connections, or backend webhooks.

Marketplace Apps (OAuth2 Multi-Tenant)

Created in the HighLevel Marketplace Developer Portal. Implements standard OAuth2 authorization code flows with user consent dialogs. Required when distributing software to multiple agencies or sub-accounts.

4. OAuth2 Token Lifecycle & Automated Token Refresh

When building Marketplace integrations, access tokens expire every 24 hours. Your backend application must securely store the refresh_token and request fresh access credentials programmatically:

// Node.js: Exchanging Refresh Token for New Access Token
const response = await fetch('https://services.leadconnectorhq.com/oauth/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({
    client_id: process.env.GHL_CLIENT_ID,
    client_secret: process.env.GHL_CLIENT_SECRET,
    grant_type: 'refresh_token',
    refresh_token: storedRefreshToken,
    user_type: 'Location'
  })
});
const tokenData = await response.json();
// tokenData contains: access_token, expires_in (86400s), and new refresh_token

5. API Rate Limits & Exponential Backoff Handling

HighLevel enforces strict rate limits across API endpoints to ensure system stability. Standard limits permit 10 requests per second per location and 100 requests per 10 seconds per company. When processing bulk data or batch migrations, inspect response headers:

  • X-RateLimit-Limit: Total allowable requests within the current window.
  • X-RateLimit-Remaining: Remaining requests available before throttling.
  • X-RateLimit-Reset: UTC epoch timestamp when the rate limit window resets.
  • HTTP 429 Too Many Requests: When receiving status 429, pause execution and implement exponential backoff (e.g. retry after 1s, 2s, 4s) rather than immediately repeating the request.

Need Custom GoHighLevel API Integration Engineering?

Looking to connect proprietary web applications, sync external databases, or build bespoke webhooks for GHL? Explore our GoHighLevel Integration services or consult our GHL Lead Automation Guide.

Advertisement
❓

Frequently Asked Questions

What can be automated via the GoHighLevel API (v2)?

Everything: contact creation/updates, pipeline opportunity movement, appointment booking, custom field syncing, conversation messaging, sub-account snapshot provisioning, and invoice generation.

What authentication method does GoHighLevel API v2 use?

GHL API v2 uses OAuth 2.0 Bearer tokens for agency/marketplace apps and Private Location API Access Keys for single sub-account integrations.

How do you handle rate limits on the GoHighLevel API?

GHL enforces a rate limit of 100 requests per 10 seconds per location. Implement exponential backoff retry logic and queue payloads for high-volume data syncs.

Muhammad Bilal Shakeel (Goofy Developer)

Founder of Build With Goofy. Specializing in bespoke Shopify Liquid development, Core Web Vitals & mobile performance engineering, and automated GoHighLevel CRM workflows for clients across the USA, Canada, UK, and worldwide.

πŸš€ GoHighLevel CRM Automation

Need This Workflow Built in Your Account?

Request a fixed-price implementation quote with turnkey GoHighLevel snapshots, Twilio SMS routing, and automated sales pipelines.

πŸ’¬ WhatsApp Bilal Directly

Related Developer Guides & Systems

View all guides β†’