Skip to main content
Version: 2023-02-21

OAuth 2.0

OAuth v2 is the recommended External Authentication method. HighLevel redirects the user to your authorization page, where they grant access. Your provider returns an authorization code, HighLevel exchanges it for an access/refresh token pair, stores the tokens securely, and includes them in the external calls your app makes (for example, in your Workflow Actions and Triggers).

Currently, only the Authorization Code grant type is supported.

How the flow works

  1. The user installs your app and is redirected to your Authorization URL.
  2. They log in and approve access on your site.
  3. Your site redirects back to HighLevel's OAuth redirect URL with an authorization code.
  4. HighLevel calls your Access Token Request endpoint, exchanging the code for an access_token and refresh_token.
  5. HighLevel stores the tokens and calls your Test API endpoint to confirm they work.
  6. When the access token later expires, HighLevel calls your Refresh Token Request endpoint to obtain a new one.

1. External app name

Enter a name for the external application you're integrating (e.g. "My OAuth App"). This is used to identify the app within the system.

2. OAuth redirect URL

HighLevel generates a redirect (callback) URL unique to your app:

https://services.leadconnectorhq.com/oauth/clients/{appId}/authentication/oauth2/callback

Copy this URL and register it as an allowed redirect/callback URL in your provider's API or developer settings. Your provider must redirect back to this exact URL after the user authorizes access.

3. Configure your fields (optional)

If your authorization or token endpoints differ per user (for example a per-tenant domain), collect those values with Configure Your Fields and reference them as {{userData.<key>}} in your endpoint configuration.

4. App credentials

Choose how your app exchanges the authorization code for tokens:

OptionWhen to use
OAuth v2Standard flow. Copy the Client ID and Client Secret from your provider's developer settings and paste them below.
OAuth v2 with PKCE extensionPKCE (Proof Key for Code Exchange) is an extension that helps prevent attacks such as authorization-code interception. Choose this if your provider supports PKCE.

Then provide:

  • Client ID (required)
  • Client Secret ID (required for standard OAuth v2)

About PKCE

When PKCE is enabled:

  • A unique code verifier is generated for each authorization request.
  • A code challenge (derived from the verifier using SHA-256) is sent on the authorization request.
  • The code verifier is securely stored and automatically included on the token request for verification.

This protects against authorization-code interception and is recommended when your provider supports it.

5. Add OAuth endpoint configuration

This section defines the four requests in the OAuth flow. Each request has a method dropdown, a URL, and More options for parameters, headers, and body. Where defaults are useful, HighLevel pre-populates them - adjust to match your provider's documentation. Most requests also support Switch to Code Mode when you need full control.

Authorization URL

Where HighLevel sends the user to authenticate and authorize the integration.

Default URL parameters:

ParameterValue
client_id{{externalApp.clientId}}
scope{{externalApp.scope}}
response_typecode
state{{bundle.state}}
redirect_uri{{bundle.redirectUrl}}

The response_type, state, and redirect_uri parameters are managed by HighLevel and should not be modified. The state parameter is a standard OAuth security measure that protects against CSRF; HighLevel verifies it on the callback.

Scope

The OAuth scopes that define the level of access your integration needs. Enter a comma- or space-separated list of values (e.g. read:user write:data). Include only the scopes you actually need.

Access token request

The endpoint where HighLevel sends the authorization code to receive tokens - typically a POST.

Default body:

ParameterValue
client_id{{externalApp.clientId}}
client_secret{{externalApp.clientSecret}}
state{{bundle.state}}
redirect_uri{{bundle.redirectUrl}}
code{{bundle.code}}
grant_typeauthorization_code

Default headers:

content-type: application/x-www-form-urlencoded
accept: application/json

Expected response:

{
"access_token": "your_access_token",
"refresh_token": "your_refresh_token",
"expires_in": 3600
}

When PKCE is enabled, the code_verifier is automatically included on this request.

Long-Lived Access Token Request (optional)

Some providers require you to exchange the first (short-lived) access token for a long-lived one before it's used. If your provider works this way, configure this extra request; otherwise leave it blank.

Refresh token request

The endpoint HighLevel calls to obtain a new access token when the current one expires - typically a POST.

Default body:

ParameterValue
refresh_token{{bundle.refreshToken}}
grant_typerefresh_token

Default headers:

content-type: application/x-www-form-urlencoded
accept: application/json

Automatically refresh token

Enable I want to automatically refresh on unauthorized error so HighLevel automatically calls your refresh token request when a request returns a 401. This keeps the connection alive without the user having to re-authorize.

If auto-refresh is disabled, the connection breaks once the access token expires and the user must re-authorize. We strongly recommend leaving it enabled.

Test API endpoint

A simple endpoint (ideally a GET needing no special configuration, such as /me) that HighLevel calls to confirm the access token is valid. The access token is included automatically via the Authorization header:

authorization: Bearer {{bundle.accessToken}}

If the test fails and auto-refresh is enabled, HighLevel attempts to refresh the token and try again.

6. Multi-account support & user info (optional)

OAuth apps can also fetch the connected user's profile and support connecting multiple external accounts. This is configured in the Fetch user information and Multi-Account Support sections - see Multi-Account Support & User Info.

Glossary

OAuth parameters

ParameterSystem ValueDescription
client_id{{externalApp.clientId}}Unique identifier issued by your provider, used to identify your application during the OAuth flow.
client_secret{{externalApp.clientSecret}}Confidential key issued alongside the client_id, used to authenticate your application when exchanging the code for tokens. Keep it secure.
scope{{externalApp.scope}}Space-separated list of permissions your application requests.
response_typecodeOnly the code response type is supported; it returns an authorization code that is exchanged for tokens.
state{{bundle.state}}Security token generated by HighLevel to prevent CSRF. Must be returned unchanged on the callback. Requests with a mismatched state are rejected.
redirect_uri{{bundle.redirectUrl}}The callback URL the provider redirects to after authorization. Must match the registered OAuth redirect URL exactly.
grant_typeauthorization_code or refresh_tokenauthorization_code when exchanging the code for tokens; refresh_token when requesting a new access token.
code_challengeGenerated valueWhen PKCE is enabled, derived from the code_verifier using SHA-256 and base64URL encoding, sent on the authorization request.
code_challenge_methodS256When PKCE is enabled, indicates the challenge method. Only S256 (SHA-256) is supported.
code_verifierGenerated valueWhen PKCE is enabled, the high-entropy random string used to generate the code_challenge, sent on the token request.

Token parameters

ParameterSystem ValueDescription
code{{bundle.code}}The authorization code returned after the user authorizes. Temporary and single-use; exchanged for tokens.
access_token{{bundle.accessToken}}Token used to authenticate requests. Has a limited lifetime and is refreshed periodically.
refresh_token{{bundle.refreshToken}}Long-lived token used to obtain new access tokens when the current one expires.

Testing your setup

Use Step 3 - Test your auth to run the OAuth flow end to end. HighLevel opens your authorization page, exchanges the code for tokens, then calls your Test API endpoint. The tester shows the requests, responses, and HTTP details - and execution logs when Code Mode is used.

Save your configuration before testing - the tester uses the most recently saved version.