# GHL Emails API

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

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

---

## Endpoints

- [GET /emails/builder](#get--emails-builder) — Fetch email templates
- [POST /emails/builder](#post--emails-builder) — Create a new template
- [POST /emails/builder/data](#post--emails-builder-data) — Update a template
- [DELETE /emails/builder/{locationId}/{templateId}](#delete--emails-builder-locationId-templateId) — Delete a template
- [GET /emails/schedule](#get--emails-schedule) — Get Campaigns

---

## GET /emails/builder

**Summary:** Fetch email templates

Fetch email templates by location id

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

**Operation ID:** `fetch-template`

**Tags:** Templates

### cURL

```bash
curl -X GET 'https://rest.gohighlevel.com/v1/emails/builder?locationId=VALUE&limit=VALUE&offset=VALUE&search=VALUE&sortByDate=VALUE&archived=VALUE&builderVersion=1&name=VALUE&parentId=VALUE&originId=VALUE&templatesOnly=VALUE' \
  -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/emails/builder?locationId=VALUE&limit=VALUE&offset=VALUE&search=VALUE&sortByDate=VALUE&archived=VALUE&builderVersion=VALUE&name=VALUE&parentId=VALUE&originId=VALUE&templatesOnly=VALUE', 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 builder",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "GET",
    "url": "https://rest.gohighlevel.com/v1/emails/builder",
    "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": "locationId",
          "value": "VALUE"
        },
        {
          "name": "limit",
          "value": "VALUE"
        },
        {
          "name": "offset",
          "value": "VALUE"
        },
        {
          "name": "search",
          "value": "VALUE"
        },
        {
          "name": "sortByDate",
          "value": "VALUE"
        },
        {
          "name": "archived",
          "value": "VALUE"
        },
        {
          "name": "builderVersion",
          "value": "VALUE"
        },
        {
          "name": "name",
          "value": "VALUE"
        },
        {
          "name": "parentId",
          "value": "VALUE"
        },
        {
          "name": "originId",
          "value": "VALUE"
        },
        {
          "name": "templatesOnly",
          "value": "VALUE"
        }
      ]
    }
  }
}
```

**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 |
|------|----------|------|----------|-------------|
| `locationId` | Query | `string` | ✅ |  |
| `limit` | Query | `string` | — |  |
| `offset` | Query | `string` | — |  |
| `search` | Query | `string` | — |  |
| `sortByDate` | Query | `string` | — |  |
| `archived` | Query | `string` | — |  |
| `builderVersion` | Query | `string` | — |  (values: 1, 2) |
| `name` | Query | `string` | — |  |
| `parentId` | Query | `string` | — |  |
| `originId` | Query | `string` | — |  |
| `templatesOnly` | Query | `string` | — |  |

### Response Codes

| Code | Description | Schema |
|------|-------------|--------|
| `200` | Success |   - **name** (string) (e.g. `New Template`): template name<br>  - **updatedBy** (string) (e.g. `John Doe`): updated by<br>  - **isPlainText** (boolean) (... |
| `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. |
| `404` | Not Found | — |
| `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 /emails/builder

**Summary:** Create a new template

Create a new template

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

**Operation ID:** `create-template`

**Tags:** Templates

### cURL

```bash
curl -X POST 'https://rest.gohighlevel.com/v1/emails/builder' \
  -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' \
  -d '{}'  # See request body schema below
```

### 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',
}

payload = json.dumps({})
conn.request('POST', '/v1/emails/builder', body=payload, 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 builder",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "POST",
    "url": "https://rest.gohighlevel.com/v1/emails/builder",
    "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

### Request Body Schema

  - **locationId** (string) (required) (e.g. `ve9EPM428h8vShlRW1KT`)
  - **title** (string) (e.g. `template title`)
  - **type** (string) (required)
  - **updatedBy** (string) (e.g. `zYy3YOUuHxgomU1uYJty`)
  - **builderVersion** (string)
  - **name** (string) (e.g. `Template1`)
  - **parentId** (string) (e.g. `zYy3YOUuHxgomU1uYJty`)
  - **templateDataUrl** (string) (e.g. ``)
  - **importProvider** (string) (required)
  - **importURL** (string) (e.g. `https://tplshare.com/fhYJ3Mi`)
  - **templateSource** (string) (e.g. `template_library`)
  - **isPlainText** (boolean) (e.g. `False`)

### Response Codes

| Code | Description | Schema |
|------|-------------|--------|
| `201` | Success |   - **redirect** (string) (required) (e.g. `66e811229245fc098765590`): template id<br>  - **traceId** (string) (required) (e.g. `0c52e980-41f6-4be7-8c... |
| `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. |
| `404` | Not Found | — |
| `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 /emails/builder/data

**Summary:** Update a template

Update a template

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

**Operation ID:** `update-template`

**Tags:** Templates

### cURL

```bash
curl -X POST 'https://rest.gohighlevel.com/v1/emails/builder/data' \
  -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' \
  -d '{}'  # See request body schema below
```

### 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',
}

payload = json.dumps({})
conn.request('POST', '/v1/emails/builder/data', body=payload, 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 data",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "POST",
    "url": "https://rest.gohighlevel.com/v1/emails/builder/data",
    "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

### Request Body Schema

  - **locationId** (string) (required) (e.g. `ve9EPM428h8vShlRW1KT`)
  - **templateId** (string) (required) (e.g. `zYy3YOUuHxgomU1uYJty`)
  - **updatedBy** (string) (required) (e.g. `zYy3YOUuHxgomU1uYJty`)
  - **dnd** (string) (required) (e.g. `{elements:[], attrs:{}, templateSettings:{}}`)
  - **html** (string) (required) (e.g. ``)
  - **editorType** (string) (required)
  - **previewText** (string) (e.g. `zYy3YOUuHxgomU1uYJty`)
  - **isPlainText** (boolean) (e.g. `false`)

### Response Codes

| Code | Description | Schema |
|------|-------------|--------|
| `201` | Success |   - **ok** (string) (e.g. `true`): ok<br>  - **traceId** (string) (e.g. `0c52e980-41f6-4be7-8c4b-32332ss`): trace id<br>  - **previewUrl** (string) (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. |
| `404` | Not Found | — |
| `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.

---

## DELETE /emails/builder/{locationId}/{templateId}

**Summary:** Delete a template

Delete a template

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

**Operation ID:** `delete-template`

**Tags:** Templates

### cURL

```bash
curl -X DELETE 'https://rest.gohighlevel.com/v1/emails/builder/VALUE/VALUE' \
  -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('DELETE', '/v1/emails/builder/VALUE/VALUE', 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 - DELETE VALUE",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "DELETE",
    "url": "https://rest.gohighlevel.com/v1/emails/builder/VALUE/VALUE",
    "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": {}
  }
}
```

**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 |
|------|----------|------|----------|-------------|
| `locationId` | Path | `string` | ✅ |  |
| `templateId` | Path | `string` | ✅ |  |

### Response Codes

| Code | Description | Schema |
|------|-------------|--------|
| `200` | Success |   - **ok** (string) (e.g. `true`): ok<br>  - **traceId** (string) (e.g. `0c52e980-41f6-4be7-8c4b-32332ss`): trace id |
| `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. |
| `404` | Not Found | — |
| `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.

---

## GET /emails/schedule

**Summary:** Get Campaigns

Get Campaigns

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

**Operation ID:** `fetch-campaigns`

**Tags:** Campaigns

### cURL

```bash
curl -X GET 'https://rest.gohighlevel.com/v1/emails/schedule?locationId=VALUE&limit=VALUE&offset=VALUE&status=active&emailStatus=all&name=VALUE&parentId=VALUE&limitedFields=VALUE&archived=VALUE&campaignsOnly=VALUE&showStats=VALUE' \
  -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/emails/schedule?locationId=VALUE&limit=VALUE&offset=VALUE&status=VALUE&emailStatus=VALUE&name=VALUE&parentId=VALUE&limitedFields=VALUE&archived=VALUE&campaignsOnly=VALUE&showStats=VALUE', 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 schedule",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "GET",
    "url": "https://rest.gohighlevel.com/v1/emails/schedule",
    "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": "locationId",
          "value": "VALUE"
        },
        {
          "name": "limit",
          "value": "VALUE"
        },
        {
          "name": "offset",
          "value": "VALUE"
        },
        {
          "name": "status",
          "value": "VALUE"
        },
        {
          "name": "emailStatus",
          "value": "VALUE"
        },
        {
          "name": "name",
          "value": "VALUE"
        },
        {
          "name": "parentId",
          "value": "VALUE"
        },
        {
          "name": "limitedFields",
          "value": "VALUE"
        },
        {
          "name": "archived",
          "value": "VALUE"
        },
        {
          "name": "campaignsOnly",
          "value": "VALUE"
        },
        {
          "name": "showStats",
          "value": "VALUE"
        }
      ]
    }
  }
}
```

**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 |
|------|----------|------|----------|-------------|
| `locationId` | Query | `string` | ✅ | Location ID to fetch campaigns from |
| `limit` | Query | `number` | — | Maximum number of campaigns to return. Defaults to 10, maximum is 100 |
| `offset` | Query | `number` | — | Number of campaigns to skip for pagination |
| `status` | Query | `string` | — | Filter by schedule status (values: active, pause, complete, cancelled, retry, draft, resend-sched... |
| `emailStatus` | Query | `string` | — | Filter by email delivery status (values: all, not-started, paused, cancelled, processing, resumed... |
| `name` | Query | `string` | — | Filter campaigns by name |
| `parentId` | Query | `string` | — | Filter campaigns by parent folder ID |
| `limitedFields` | Query | `boolean` | — | When true, returns only essential campaign fields like id, templateDataDownloadUrl, updatedAt, ty... |
| `archived` | Query | `boolean` | — | Filter archived campaigns |
| `campaignsOnly` | Query | `boolean` | — | Return only campaigns, excluding folders |
| `showStats` | Query | `boolean` | — | When true, returns campaign statistics including delivered count, opened count, clicked count and... |

### Response Codes

| Code | Description | Schema |
|------|-------------|--------|
| `200` | Success |   - **schedules** (array of ScheduleDto) (required): The list of campaigns<br>  - **total** (array) (required): The total number of campaigns<br>  - **tr... |
| `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. |
| `403` | The token does not have access to this location |   - **statusCode** (number) (e.g. `403`)<br>  - **message** (string) (e.g. `The token does not have access to this location`) |
| `404` | Not Found |   - **statusCode** (number) (e.g. `404`)<br>  - **message** (string) (e.g. `Not Found`)<br>  - **error** (string) (e.g. `The requested resource was not f... |
| `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.*