# GHL OAuth API

**Endpoints:** 3
**Base URL:** `https://rest.gohighlevel.com/v1`

**Version Header(s):** `2021-07-28`

---

## Endpoints

- [GET /oauth/installedLocations](#get--oauth-installedLocations) — Get Location where app is installed
- [POST /oauth/locationToken](#post--oauth-locationToken) — Get Location Access Token from Agency Token
- [POST /oauth/token](#post--oauth-token) — Get Access Token

---

## GET /oauth/installedLocations

**Summary:** Get Location where app is installed

This API allows you fetch location where app is installed upon

**Version Header:** `2021-07-28`

**Operation ID:** `get-installed-location`

**Tags:** OAuth 2.0

### cURL

```bash
curl -X GET 'https://rest.gohighlevel.com/v1/oauth/installedLocations?skip=1&limit=10&query=location name&isInstalled=True&companyId=tDtDnQdgm2LXpyiqYvZ6&appId=tDtDnQdgm2LXpyiqYvZ6&versionId=tDtDnQdgm2LXpyiqYvZ6&onTrial=True&planId=True&locationId=1245' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Version: 2021-07-28' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'User-Agent: YourApp/1.0'
```

### Python (http.client)

```python
import http.client
import json

conn = http.client.HTTPSConnection('rest.gohighlevel.com')

headers = {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Version': '2021-07-28',
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'User-Agent': 'YourApp/1.0',
}

conn.request('GET', '/v1/oauth/installedLocations?skip=1&limit=10&query=location name&isInstalled=True&companyId=tDtDnQdgm2LXpyiqYvZ6&appId=tDtDnQdgm2LXpyiqYvZ6&versionId=tDtDnQdgm2LXpyiqYvZ6&onTrial=True&planId=True&locationId=1245', headers=headers)

response = conn.getresponse()
data = json.loads(response.read().decode())
print(json.dumps(data, indent=2))
conn.close()
```

### n8n HTTP Node

```json
{
  "name": "GHL - GET installedLocations",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "GET",
    "url": "https://rest.gohighlevel.com/v1/oauth/installedLocations",
    "authentication": "genericCredentialType",
    "genericAuthType": "httpHeaderAuth",
    "sendHeaders": true,
    "headerParameters": {
      "parameters": [
        {
          "name": "Authorization",
          "value": "Bearer YOUR_API_TOKEN"
        },
        {
          "name": "Version",
          "value": "2021-07-28"
        },
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Accept",
          "value": "application/json"
        },
        {
          "name": "User-Agent",
          "value": "YourApp/1.0"
        }
      ]
    },
    "sendBody": false,
    "bodyParameters": {
      "parameters": []
    },
    "options": {},
    "sendQuery": true,
    "queryParameters": {
      "parameters": [
        {
          "name": "skip",
          "value": "1"
        },
        {
          "name": "limit",
          "value": "10"
        },
        {
          "name": "query",
          "value": "location name"
        },
        {
          "name": "isInstalled",
          "value": true
        },
        {
          "name": "companyId",
          "value": "tDtDnQdgm2LXpyiqYvZ6"
        },
        {
          "name": "appId",
          "value": "tDtDnQdgm2LXpyiqYvZ6"
        },
        {
          "name": "versionId",
          "value": "tDtDnQdgm2LXpyiqYvZ6"
        },
        {
          "name": "onTrial",
          "value": true
        },
        {
          "name": "planId",
          "value": true
        },
        {
          "name": "locationId",
          "value": "1245"
        }
      ]
    }
  }
}
```

**To use in n8n:**
1. Add an HTTP Request node
2. Switch to JSON mode (Parameters → use RAW JSON)
3. Paste the JSON above
4. Update `YOUR_API_TOKEN` with your actual GHL API key

### Request Parameters

| Name | Location | Type | Required | Description |
|------|----------|------|----------|-------------|
| `skip` | Query | `string` | — | Parameter to skip the number installed locations [example: `1`] |
| `limit` | Query | `string` | — | Parameter to limit the number installed locations [example: `10`] |
| `query` | Query | `string` | — | Parameter to search for the installed location by name [example: `location name`] |
| `isInstalled` | Query | `boolean` | — | Filters out location which are installed for specified app under the specified company [example: ... |
| `companyId` | Query | `string` | ✅ | Parameter to search by the companyId [example: `tDtDnQdgm2LXpyiqYvZ6`] |
| `appId` | Query | `string` | ✅ | Parameter to search by the appId [example: `tDtDnQdgm2LXpyiqYvZ6`] |
| `versionId` | Query | `string` | — | VersionId of the app [example: `tDtDnQdgm2LXpyiqYvZ6`] |
| `onTrial` | Query | `boolean` | — | Filters out locations which are installed for specified app in trial mode [example: `True`] |
| `planId` | Query | `string` | — | Filters out location which are installed for specified app under the specified planId [example: `... |
| `locationId` | Query | `string` | — | locationId [example: `1245`] |

### Response Codes

| Code | Description | Schema |
|------|-------------|--------|
| `200` | Successful response |   - **locations** (array of InstalledLocationSchema)<br>  - **count** (number) (e.g. `1231`): Total location count under the company<br>  - **installToFu... |
| `400` | Bad Request | Standard error response for bad requests (400). Contains message, statusCode fields. |
| `401` | Unauthorized | Standard error response for unauthorized requests (401). Contains message, statusCode fields. |
| `422` | Unprocessable Entity | Standard error response for unprocessable entity (422). Contains message, statusCode, errors array fields. |

### ⚠️ Special Notes & Quirks

> ⚠️ **User-Agent Required:** All GHL API requests require a `User-Agent` HTTP header. Requests without it may be rejected with a 403 error.

---

## POST /oauth/locationToken

**Summary:** Get Location Access Token from Agency Token

This API allows you to generate locationAccessToken from AgencyAccessToken

**Version Header:** `2021-07-28`

**Operation ID:** `get-location-access-token`

**Tags:** OAuth 2.0

### cURL

```bash
curl -X POST 'https://rest.gohighlevel.com/v1/oauth/locationToken' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Version: 2021-07-28' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'User-Agent: YourApp/1.0'
```

### Python (http.client)

```python
import http.client
import json

conn = http.client.HTTPSConnection('rest.gohighlevel.com')

headers = {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Version': '2021-07-28',
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'User-Agent': 'YourApp/1.0',
}

conn.request('POST', '/v1/oauth/locationToken', headers=headers)

response = conn.getresponse()
data = json.loads(response.read().decode())
print(json.dumps(data, indent=2))
conn.close()
```

### n8n HTTP Node

```json
{
  "name": "GHL - POST locationToken",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "POST",
    "url": "https://rest.gohighlevel.com/v1/oauth/locationToken",
    "authentication": "genericCredentialType",
    "genericAuthType": "httpHeaderAuth",
    "sendHeaders": true,
    "headerParameters": {
      "parameters": [
        {
          "name": "Authorization",
          "value": "Bearer YOUR_API_TOKEN"
        },
        {
          "name": "Version",
          "value": "2021-07-28"
        },
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Accept",
          "value": "application/json"
        },
        {
          "name": "User-Agent",
          "value": "YourApp/1.0"
        }
      ]
    },
    "sendBody": true,
    "bodyParameters": {
      "parameters": []
    },
    "options": {}
  }
}
```

**To use in n8n:**
1. Add an HTTP Request node
2. Switch to JSON mode (Parameters → use RAW JSON)
3. Paste the JSON above
4. Update `YOUR_API_TOKEN` with your actual GHL API key

### Response Codes

| Code | Description | Schema |
|------|-------------|--------|
| `200` | Successful response |   - **access_token** (string) (e.g. `ab12dc0ae1234a7898f9ff06d4f69gh`): Location access token which can be used to authenticate & authorize API und... |
| `400` | Bad Request | Standard error response for bad requests (400). Contains message, statusCode fields. |
| `401` | Unauthorized | Standard error response for unauthorized requests (401). Contains message, statusCode fields. |
| `422` | Unprocessable Entity | Standard error response for unprocessable entity (422). Contains message, statusCode, errors array fields. |

### ⚠️ Special Notes & Quirks

> ⚠️ **User-Agent Required:** All GHL API requests require a `User-Agent` HTTP header. Requests without it may be rejected with a 403 error.

---

## POST /oauth/token

**Summary:** Get Access Token

Use Access Tokens to access GoHighLevel resources on behalf of an authenticated location/company.

**Version Header:** Not required

**Operation ID:** `get-access-token`

**Tags:** OAuth 2.0

### cURL

```bash
curl -X POST 'https://rest.gohighlevel.com/v1/oauth/token' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'User-Agent: YourApp/1.0'
```

### Python (http.client)

```python
import http.client
import json

conn = http.client.HTTPSConnection('rest.gohighlevel.com')

headers = {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'User-Agent': 'YourApp/1.0',
}

conn.request('POST', '/v1/oauth/token', headers=headers)

response = conn.getresponse()
data = json.loads(response.read().decode())
print(json.dumps(data, indent=2))
conn.close()
```

### n8n HTTP Node

```json
{
  "name": "GHL - POST token",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "POST",
    "url": "https://rest.gohighlevel.com/v1/oauth/token",
    "authentication": "genericCredentialType",
    "genericAuthType": "httpHeaderAuth",
    "sendHeaders": true,
    "headerParameters": {
      "parameters": [
        {
          "name": "Authorization",
          "value": "Bearer YOUR_API_TOKEN"
        },
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Accept",
          "value": "application/json"
        },
        {
          "name": "User-Agent",
          "value": "YourApp/1.0"
        }
      ]
    },
    "sendBody": true,
    "bodyParameters": {
      "parameters": []
    },
    "options": {}
  }
}
```

**To use in n8n:**
1. Add an HTTP Request node
2. Switch to JSON mode (Parameters → use RAW JSON)
3. Paste the JSON above
4. Update `YOUR_API_TOKEN` with your actual GHL API key

### Response Codes

| Code | Description | Schema |
|------|-------------|--------|
| `200` | Successful response |   - **access_token** (string) (e.g. `ab12dc0ae1234a7898f9ff06d4f69gh`)<br>  - **token_type** (string) (e.g. `Bearer`)<br>  - **expires_in** (number) (e.g... |
| `400` | Bad Request | Standard error response for bad requests (400). Contains message, statusCode fields. |
| `401` | Unauthorized | Standard error response for unauthorized requests (401). Contains message, statusCode fields. |
| `422` | Unprocessable Entity | Standard error response for unprocessable entity (422). Contains message, statusCode, errors array fields. |

### ⚠️ Special Notes & Quirks

> ⚠️ **User-Agent Required:** All GHL API requests require a `User-Agent` HTTP header. Requests without it may be rejected with a 403 error.

---


*Documentation generated from GHL OpenAPI specifications. Verify against official docs for latest changes.*