Guide
GoHighLevel API Authentication: Private Integration Tokens vs OAuth
Which auth method each endpoint accepts, the difference between sub-account and agency tokens, and how to pick one.
Last updated
Which auth method does each endpoint accept?
Almost all of them accept either. Across the 540 endpoints in our index that publish an authentication line, 515 accept an OAuth access token or a Private Integration Token interchangeably, 11 accept OAuth only, and 14 state no method. For ordinary CRM work — contacts, conversations, calendars, opportunities, payments — the choice is yours, and it is a choice about operations rather than about capability.
What does constrain you is not the token's type but its level. Every endpoint is documented as taking a sub-account token or an agency token, and the wrong level fails regardless of which method minted it. Across the 576 endpoints in our index that come from GoHighLevel's official specification:
| Documented token | Endpoints | What it means |
|---|---|---|
| Sub-account | 356 | Scoped to one location — the bulk of the CRM surface |
| Agency | 105 | Company level: billing, SaaS configuration, user and location management |
| Neither, in our index | 115 | No level recorded — 94 of them are ad-manager endpoints |
That third row is a gap in our data rather than a third kind of token. Those 115 rows carry the bare word Bearer where the other 461 carry a level, which tells you how to format the header and nothing about whose token to use. We treat it as unknown: the reference pages omit the token-type row entirely on those endpoints rather than present a non-answer as a fact. If you are working in ad-manager, determine the level empirically rather than from us.
For everything else, the documented token type and required scope is on that endpoint's page in the API reference.
Private Integration Token vs OAuth
The two methods differ in who holds the credential and how it is renewed, not in what the API will do for you.
| Private Integration Token | OAuth | |
|---|---|---|
| Created by | The sub-account owner, in Settings → Private Integrations | A marketplace app, through an install and consent flow |
| Lifetime | Long-lived until revoked | Access token expires; renewed with a refresh token |
| Scope of access | One location | Every location that installed the app |
| Setup cost | Minutes — tick scopes, copy the token | You register and maintain a marketplace app |
| Best for | Your own account, scripts, a single-tenant integration | Software other people install; anything multi-tenant |
Both travel in the same header. The Version header is required alongside it, and leaving it out is a common first-call failure:
A request, either way
curl -s https://services.leadconnectorhq.com/contacts/ \
-H "Authorization: Bearer pit-your-token" \
-H "Version: 2021-07-28" \
-H "Accept: application/json" \
--get --data-urlencode "locationId=your-location-id"A token is a credential, not a setting
A Private Integration Token grants everything its scopes allow for as long as it exists. Create one per integration rather than sharing one, so that revoking it is a contained act — and never paste it into a chat window or a prompt. Hand it to the integration directly.
Sub-account tokens vs agency tokens
A sub-account token acts inside one location. An agency token acts at the company level, across locations. The split is not arbitrary: agency-token endpoints cluster in the parts of the platform that are about running an agency rather than serving a client.
| Category | Agency-token endpoints |
|---|---|
invoices | 41 |
products | 12 |
saas | 11 |
saas-api | 11 |
users | 6 |
custom-menus | 5 |
locations | 5 |
proposals | 4 |
snapshots | 4 |
marketplace | 2 |
oauth | 2 |
companies | 1 |
objects | 1 |
Invoicing dominates at 41 endpoints, followed by product catalogue management and the two SaaS-configuration groups. The trap is the seven categories containing both kinds — invoices, locations, marketplace, oauth, objects, products, and users. There, two endpoints that look like siblings can want different tokens, so an integration that reads a product happily may fail the moment it tries to write one.
users is the sharpest case: six of its seven endpoints want an agency token and only one takes a sub-account token. When you hit a permission error on an endpoint whose neighbours work, check the token level before you start adding scopes.
The endpoints that require OAuth
Eleven endpoints in our index publish OAuth as the only accepted method, and they share a clean pattern: every one is a marketplace app-developer or OAuth-management endpoint. They are operations that only mean anything in the context of an installed app, so there is no sub-account credential that could authorize them.
- Billing for paid marketplace apps —
marketplace-charge,get-charges,get-specific-charge,delete-charge,has-funds - App lifecycle —
get-installer-details,uninstall-application,get-rebilling-config-for-app,migrate-connection - OAuth management —
get-installed-location,get-location-access-token
The practical reading is reassuring. If you are building an integration for your own account, nothing on this list applies and a Private Integration Token covers the entire surface you care about. If you are building a marketplace app you need OAuth regardless, and get-location-access-token — which mints a sub-account token from an agency grant — is how you bridge from the agency level down to per-location work.
How scopes work
Scopes are what a token may do, independently of how it was minted. GoHighLevel organises them per resource with read and write kept separate: contacts.readonly and contacts.write are distinct grants, and holding one never implies the other. Our index covers 74 scope resources and 124 scopes, appearing as 118 distinct scope requirements across the endpoint catalogue.
Two consequences are worth internalising, because between them they produce most scope confusion:
- A scope you did not tick cannot be added later to the same token. A Private Integration Token carries the set chosen at creation. When writes start failing on an integration whose reads work, this is nearly always why — recreate the token instead of debugging the request.
- Scopes bound capability, not correctness. A token holding
contacts.writecan still fail a call because the endpoint wanted an agency token, or because the body was wrong. Read the error rather than adding scopes until something works.
Every scope, paired with the resource it covers, is listed in the OAuth scopes reference, and each endpoint page names the specific scope it requires.
How to choose
Use a Private Integration Token when the integration serves accounts you control: internal scripts, an AI assistant on your own sub-account, a one-off migration, a single-tenant tool. It is minutes of setup, and 515 of the 540 endpoints that publish an auth line accept it.
Use OAuth when other people's accounts are involved — anything distributed through the marketplace, anything multi-tenant, anything where you cannot ask each customer to paste a token. It is also the better answer for agencies operating many sub-accounts, since one grant mints per-location tokens instead of you managing one credential per client.
A reasonable default for most people reading this: start with a Private Integration Token scoped to exactly what you need, and move to OAuth when you are distributing software rather than running it. If you are connecting an AI assistant, the connection guide covers both paths, and the MCP overview explains why the official server now prefers OAuth sign-in.
Common questions
What is the difference between a Private Integration Token and an OAuth access token in GoHighLevel?
A Private Integration Token is a long-lived credential you create inside one sub-account and paste into your integration. An OAuth access token is issued to an installed marketplace app, expires, and is renewed with a refresh token. Of the 540 endpoints in our index that publish an auth line, 515 accept either.
Do Private Integration Tokens expire?
They are long-lived and carry no refresh cycle the way OAuth access tokens do. They stay valid until revoked, which is why scoping them tightly matters more than it does for a short-lived token.
Can one token work across multiple sub-accounts?
Not a Private Integration Token — it is bound to the location it was created in. Multi-location access means either one token per location or an agency OAuth grant, which can mint per-location access tokens.
Which GoHighLevel endpoints cannot use a Private Integration Token?
In our index, 11 endpoints publish OAuth as the only accepted method, and all of them are marketplace app-developer or OAuth-management endpoints: billing charges, installer details, uninstalling an app, and minting a location access token. Ordinary CRM endpoints all accept both.
What headers does the GoHighLevel API expect?
Authorization: Bearer <token> for both methods, plus a Version header — Version: 2021-07-28. Which token goes in the Authorization header is what differs between the two methods.