Private Integration tokens: agency vs sub-account
Private Integration Tokens (PITs) are HighLevel's simple alternative to building a full OAuth app: you create a token with chosen scopes and send it in the Authorization header. The part that trips people up is that you can create them at two levels, and they don't behave the same.
The facts from HighLevel
- Private Integrations exist at both the agency and the sub-account (location) level, with up to 20 tokens at each level.
- By default agency admins can create and manage them; access can be restricted separately for agency-level and sub-account-level integrations.
- Scopes are chosen when you create the token and can be edited later. Editing does not generate a new token.
- HighLevel recommends rotating tokens every 90 days. "Rotate and expire later" gives a 7-day window where both old and new tokens work.
- Requests use
Authorization: Bearer <token>and aVersionheader (the examples use2021-07-28).
[Private Integrations: Everything you need to know, updated 2026-10-16; checked 2026-10-25]
What we hit in practice
Working on our own account, we first created a token at the agency level. Calls to sub-account data such as contacts and calendars failed with authorization errors, even with a locationId in the request. The same calls worked as soon as we created the token inside the sub-account (Settings > Private Integrations in that sub-account) with the contacts and calendars scopes.
HighLevel's help article doesn't spell this rule out, so treat it as our experience rather than official policy. The practical lesson holds either way: if your integration works with one client's CRM data, create the token in that client's sub-account.
Which level to use
| You want to… | Create the token in |
|---|---|
| Read or write contacts, opportunities, calendars, conversations for one business | That business's sub-account |
| Create or update Voice AI agents for one business | That business's sub-account (this is what we used) |
| Manage sub-accounts themselves (list, create, update locations), agency-wide users or SaaS settings | Agency |
| Build something many agencies will install | Neither: build a Marketplace app with OAuth |
Step by step: a sub-account token
- Switch into the sub-account (not agency view).
- Open Settings > Private Integrations and create a new integration with a clear name ("Zap: website form sync").
- Select only the scopes you need, for example
contacts.readonlyandcontacts.write, or the calendars scopes for booking. - Copy the token once and store it in a secrets manager or environment variable, never in code or a shared doc.
- Test with a read call:
curl "https://services.leadconnectorhq.com/contacts/?locationId=LOCATION_ID&limit=1" \
-H "Authorization: Bearer $GHL_TOKEN" \
-H "Version: 2021-07-28" \
-H "Accept: application/json"
Troubleshooting
| Symptom | Likely cause |
|---|---|
| 401 or 403 on contacts or calendars with an agency token | Token at the wrong level. Create one in the sub-account. |
| 401/403 with a sub-account token | Missing scope. Edit the integration and add it (the token stays the same). |
| Errors mentioning the version | Missing Version header. |
| Data from the wrong client | Wrong locationId, or a token from another sub-account. |
| Token suddenly stopped working | It was rotated and the 7-day overlap ended, or someone chose "expire now". |
Security habits
- One token per integration, so you can revoke one without breaking the others.
- Least privilege: read-only scopes unless the integration writes.
- Put a rotation reminder in your calendar for 90 days out.
- Restrict who can create tokens under Roles & Permissions.
API access level depends on plan: the pricing page lists Basic API access on Unlimited and Advanced API access on Agency Pro. [HighLevel pricing page; checked 2026-10-25]
Affiliate link: if you sign up through it we may earn a commission, at no extra cost to you. How we make money.
Facts last checked against official sources: