OAuth2
Here are all details about configuring Connectors to authenticate with OAuth2
Introduction
Before diving into configuration details, it is useful to first understand at a high level how OAuth2 works. This helps with troubleshooting and understanding the process flow.
Redirect URI
The redirect URI is always https://api.locoia.com/v1/oauth2/callback/connectorname
For one-word Connectors, use the lowercase connector name
For multi-word Connectors, replace spaces with
%20
Examples:
HubSpot:
https://api.locoia.com/v1/oauth2/callback/hubspot
Teamwork CRM:
https://api.locoia.com/v1/oauth2/callback/teamwork%20crm
OAuth2 Header
The OAuth2 access token is typically sent in the header using this format:
{
"encode": false,
"token_in_header": true,
"content_type": "application/json",
"header_key": "Authorization",
"token_format": "{{token}}",
"token_prefix": "Bearer {{token_format}}"
}
Authentication Configuration (Standard)
For APIs following the standard OAuth2 flow, the configuration looks like:
{
"oauth2": {
"auth_form": [],
"config": {
"client_id": "CLIENT_ID for OAuth2 app",
"client_secret": "CLIENT_SECRET for OAuth2 app",
"extra_authorization_url": {
"response_type": "code"
},
"extra_access_url": {
"grant_type": "authorization_code"
},
"step1_authorize_url": "https://.../authorize",
"step3_access_url": "https://.../token",
"token_refresh_url": "https://.../token"
}
}
}
OAuth2 URLs Explained
step1_authorize_url
URL for user authorization page (GET request)step3_access_url
URL for exchanging the code for an access token (POST by default with content-typeapplication/x-www-form-urlencoded
)token_refresh_url
Used for token refresh if different from the regularstep3_access_url
(Deprecated for standard flows)
Additional Query/Body Parameters
extra_authorization_url: Add query parameters to the authorization request.
extra_access_url: Add body parameters to the token exchange request.
"scope": "scope1 scope2"
If scopes are required, add them in the extra_authorization_url:
Dynamic base domains
To handle dynamic subdomains or environments (like production/sandbox), use Jinja rendering inside URLs as needed.
https://{{ environment }}.example.com/oauth/token
Handling OAuth2 deviations
For APIs that deviate from the standard OAuth2 flow, additional config options are available:
client_id_and_secret_in_headers
Send client credentials as Basic Auth instead of body.
alternative_code_key
Rename the key for the authorization code.
alternative_client_id_key
Rename the key for client ID.
alternative_client_secret_key
Rename the key for client secret.
grant_type
Add custom grant_type (Deprecated).
accept_header
Set a custom Accept header.
content_type
Change Content-Type (e.g., to application/json).
request_method
Force GET instead of POST for token request.
access_token_path
Define a custom JSON path to find the access token in the response.
Deprecated auth_form Fields
Additional fields that can be exposed to users:
alternative_scope
User-defined scope input (overwrites default scopes).
client_id
Allows user to provide their own Client ID, overriding config.
client_secret
Allows user to provide their own Client Secret, overriding config.
Other custom fields can also be added manually if required.
Examples
HubSpot - Standard with Scopes
The Authentication Configuration is the standard one, with specific scopes:
{
"oauth2": {
"auth_form": [
{
"name": "scope",
"title": "Additional scopes",
"type": "text",
"required": false,
"hideInEmbed": true,
"placeholder": "crm.schemas.companies.write crm.schemas.contacts.write",
"info": "Adds scopes to the default: crm.schemas.companies.write crm.schemas.contacts.write crm.schemas.deals.read crm.schemas.deals.write files crm.objects.contacts.write e-commerce crm.objects.companies.write crm.objects.companies.read crm.objects.deals.read crm.schemas.contacts.read crm.objects.deals.write crm.objects.contacts.read crm.schemas.companies.read communication_preferences.read_write crm.objects.owners.read crm.lists.write crm.lists.read"
}
],
"config": {
"client_id": "CLIENT_ID for OAuth2 app",
"client_secret": "CLIENT_SECRET for OAuth2 app",
"exchange_request_body_type": "json",
"extra_access_url": {
"grant_type": "authorization_code"
},
"extra_authorization_url": {
"response_type": "code",
"scope": "communication_preferences.read_write crm.lists.read crm.lists.write crm.objects.companies.read crm.objects.companies.write crm.objects.contacts.read crm.objects.contacts.write crm.objects.deals.read crm.objects.deals.write crm.objects.owners.read crm.schemas.companies.read crm.schemas.companies.write crm.schemas.contacts.read crm.schemas.contacts.write crm.schemas.deals.read crm.schemas.deals.write e-commerce files settings.users.read tickets{% if scope is defined %} {{ scope }}{% endif %}"
},
"or_exchange_request_body_type": "data",
"step1_authorize_url": "https://app.hubspot.com/oauth/authorize",
"step3_access_url": "https://api.hubapi.com/oauth/v1/token",
"token_refresh_url": "https://api.hubapi.com/oauth/v1/token"
}
}
}
The header is the standard header.
TikTok - Alternative client keys and access token path
TikTok has a few deviations from the OAuth2 standard:
The client id key is
app_id
instead ofclient_id
, thusalternative_client_id_key
needs to be set accordinglyThe client id key is
secret
instead ofclient_secret
, thusalternative_client_secret_key
needs to be set accordinglyThe access token is returned inside a dictionary called
data
, instead of in the 'root' dictionary, thusaccess_token_path
needs to be set accordinglyThe base domain for the access url, is always
https://business-api.tiktok.com/
, even though the base domain for the endpoints itself is based on the environment:https://{% if environment is defined and environment == 'Sandbox' %}sandbox{% else %}business{% endif %}-api.tiktok.com/open_api/v1.2/
The Authentication Configuration thus needs to be setup like this:
{
"oauth2": {
"auth_form": [
{
"name": "environment",
"title": "Environment",
"type": "select",
"required": false,
"default": "Production",
"enum": [
"Production",
"Sandbox"
]
}
],
"config": {
"access_token_path": "data.access_token",
"alternative_client_id_key": "app_id",
"alternative_client_secret_key": "secret",
"alternative_code_key": "auth_code",
"client_id": "CLIENT_ID for OAuth2 app",
"client_secret": "CLIENT_SECRET for OAuth2 app",
"exchange_request_body_type": "json",
"extra_access_url": {
"grant_type": "authorization_code"
},
"extra_authorization_url": {
"response_type": "code"
},
"or_exchange_request_body_type": "data",
"step1_authorize_url": "https://ads.tiktok.com/marketing_api/auth",
"step3_access_url": "https://business-api.tiktok.com/open_api/v1.2/oauth2/access_token/",
"token_refresh_url": "https://business-api.tiktok.com/open_api/v1.2/oauth2/access_token/"
}
}
}
Last updated
Was this helpful?