# GHL Conversations API
> ⚠️ **Version Header:** All Conversations endpoints use `Version: 2021-04-15` (different from most other APIs which use `2021-07-28`).
**Endpoints:** 29
**Base URL:** `https://rest.gohighlevel.com/v1`
**Version Header(s):** `2021-04-15`
---
## Endpoints
- [POST /conversations/](#post--conversations-) — Create Conversation
- [GET /conversations/locations/{locationId}/messages/{messageId}/transcription](#get--conversations-locations-locationId-messages-messageId-transcription) — Get transcription by Message ID
- [GET /conversations/locations/{locationId}/messages/{messageId}/transcription/download](#get--conversations-locations-locationId-messages-messageId-transcription-download) — Download transcription by Message ID
- [POST /conversations/messages](#post--conversations-messages) — Send a new message
- [DELETE /conversations/messages/email/{emailMessageId}/schedule](#delete--conversations-messages-email-emailMessageId-schedule) — Cancel a scheduled email message.
- [GET /conversations/messages/email/{id}](#get--conversations-messages-email-id) — Get email by Id
- [GET /conversations/messages/export](#get--conversations-messages-export) — Export messages by location ID
- [POST /conversations/messages/inbound](#post--conversations-messages-inbound) — Add an inbound message
- [POST /conversations/messages/outbound](#post--conversations-messages-outbound) — Add an external outbound call
- [POST /conversations/messages/review-reply](#post--conversations-messages-review-reply) — Send a review reply to Google My Business
- [POST /conversations/messages/upload](#post--conversations-messages-upload) — Upload file attachments
- [POST /conversations/messages/upload/complete](#post--conversations-messages-upload-complete) — Complete file upload
- [POST /conversations/messages/upload/initiate](#post--conversations-messages-upload-initiate) — Initiate file upload to GCS
- [GET /conversations/messages/{id}](#get--conversations-messages-id) — Get message by message id
- [PUT /conversations/messages/{messageId}/attachments](#put--conversations-messages-messageId-attachments) — Add message attachments
- [GET /conversations/messages/{messageId}/locations/{locationId}/recording](#get--conversations-messages-messageId-locations-locationId-recording) — Get Recording by Message ID
- [DELETE /conversations/messages/{messageId}/schedule](#delete--conversations-messages-messageId-schedule) — Cancel a scheduled message.
- [PUT /conversations/messages/{messageId}/status](#put--conversations-messages-messageId-status) — Update message status
- [GET /conversations/preferences/custom-subtypes](#get--conversations-preferences-custom-subtypes) — Get All Custom Subtypes
- [POST /conversations/preferences/custom-subtypes](#post--conversations-preferences-custom-subtypes) — Create Custom Subtype
- [PUT /conversations/preferences/custom-subtypes/{id}](#put--conversations-preferences-custom-subtypes-id) — Update Custom Subtype
- [GET /conversations/preferences/unsubscriptions/status](#get--conversations-preferences-unsubscriptions-status) — Get Contact Unsubscription Status
- [POST /conversations/preferences/unsubscriptions/user-change](#post--conversations-preferences-unsubscriptions-user-change) — User Subscription Change
- [POST /conversations/providers/live-chat/typing](#post--conversations-providers-live-chat-typing) — Agent/Ai-Bot is typing a message indicator for live chat
- [GET /conversations/search](#get--conversations-search) — Search Conversations
- [DELETE /conversations/{conversationId}](#delete--conversations-conversationId) — Delete Conversation
- [GET /conversations/{conversationId}](#get--conversations-conversationId) — Get Conversation
- [PUT /conversations/{conversationId}](#put--conversations-conversationId) — Update Conversation
- [GET /conversations/{conversationId}/messages](#get--conversations-conversationId-messages) — Get messages by conversation id
---
## POST /conversations/
**Summary:** Create Conversation
Creates a new conversation with the data provided
**Version Header:** `2021-04-15`
**Operation ID:** `create-conversation`
**Tags:** Conversations
### cURL
```bash
curl -X POST 'https://rest.gohighlevel.com/v1/conversations/' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
payload = json.dumps({})
conn.request('POST', '/v1/conversations/', 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 conversations",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://rest.gohighlevel.com/v1/conversations/",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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. `tDtDnQdgm2LXpyiqYvZ6`): Location ID as string
- **contactId** (string) (required) (e.g. `tDtDnQdgm2LXpyiqYvZ6`): Contact ID as string
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `201` | Successful response | - **success** (boolean) (required) (e.g. `True`): Indicates whether the API request was successful.
- **conversation** (string) (required): Con... |
| `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. |
### ⚠️ 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 /conversations/locations/{locationId}/messages/{messageId}/transcription
**Summary:** Get transcription by Message ID
Get the recording transcription for a message by passing the message id
**Version Header:** `2021-04-15`
**Operation ID:** `get-message-transcription`
**Tags:** Messages
### cURL
```bash
curl -X GET 'https://rest.gohighlevel.com/v1/conversations/locations/tDtDnQdgm2LXpyiqYvZ6/messages/tDtDnQdgm2LXpyiqYvZ6/transcription' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
conn.request('GET', '/v1/conversations/locations/tDtDnQdgm2LXpyiqYvZ6/messages/tDtDnQdgm2LXpyiqYvZ6/transcription', 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 transcription",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "GET",
"url": "https://rest.gohighlevel.com/v1/conversations/locations/tDtDnQdgm2LXpyiqYvZ6/messages/tDtDnQdgm2LXpyiqYvZ6/transcription",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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` | ✅ | Location ID as string [example: `tDtDnQdgm2LXpyiqYvZ6`] |
| `messageId` | Path | `string` | ✅ | Message ID as string [example: `tDtDnQdgm2LXpyiqYvZ6`] |
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Gives the attached recording transcription to the message | - **mediaChannel** (number) (required) (e.g. `1`): Media channel describes the user interaction channel
- **sentenceIndex** (number) (required)... |
| `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. |
### ⚠️ 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 /conversations/locations/{locationId}/messages/{messageId}/transcription/download
**Summary:** Download transcription by Message ID
Download the recording transcription for a message by passing the message id
**Version Header:** `2021-04-15`
**Operation ID:** `download-message-transcription`
**Tags:** Messages
### cURL
```bash
curl -X GET 'https://rest.gohighlevel.com/v1/conversations/locations/tDtDnQdgm2LXpyiqYvZ6/messages/tDtDnQdgm2LXpyiqYvZ6/transcription/download' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
conn.request('GET', '/v1/conversations/locations/tDtDnQdgm2LXpyiqYvZ6/messages/tDtDnQdgm2LXpyiqYvZ6/transcription/download', 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 download",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "GET",
"url": "https://rest.gohighlevel.com/v1/conversations/locations/tDtDnQdgm2LXpyiqYvZ6/messages/tDtDnQdgm2LXpyiqYvZ6/transcription/download",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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` | ✅ | Location ID as string [example: `tDtDnQdgm2LXpyiqYvZ6`] |
| `messageId` | Path | `string` | ✅ | Message ID as string [example: `tDtDnQdgm2LXpyiqYvZ6`] |
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Downloads the attached transcription of the message | — |
| `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. |
### ⚠️ 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 /conversations/messages
**Summary:** Send a new message
Post the necessary fields for the API to send a new message.
**Version Header:** `2021-04-15`
**Operation ID:** `send-a-new-message`
**Tags:** Messages
### cURL
```bash
curl -X POST 'https://rest.gohighlevel.com/v1/conversations/messages' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
payload = json.dumps({})
conn.request('POST', '/v1/conversations/messages', 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 messages",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://rest.gohighlevel.com/v1/conversations/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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
- **type** (string) (required) (e.g. `Email`): Type of message being sent
- **subType** (object) (required) (e.g. `Email`): Type of message being sent
- **contactId** (string) (required) (e.g. `abc123def456`): ID of the contact receiving the message
- **appointmentId** (string) (e.g. `appt123`): ID of the associated appointment
- **attachments** (array) (e.g. `['https://storage.com/file1.pdf', 'https://storage.com/file2.jpg']`): Array of attachment URLs
- **emailFrom** (string) (e.g. `sender@company.com`): Email address to send from
- **emailCc** (array) (e.g. `['cc1@company.com', 'cc2@company.com']`): Array of CC email addresses
- **emailBcc** (array) (e.g. `['bcc1@company.com', 'bcc2@company.com']`): Array of BCC email addresses
- **html** (string) (e.g. `
Hello World
`): HTML content of the message
- **message** (string) (e.g. `Hello, how can I help you today?`): Text content of the message
- **subject** (string) (e.g. `Important Update`): Subject line for email messages
- **replyMessageId** (string) (e.g. `msg123`): ID of message being replied to
- **templateId** (string) (e.g. `template123`): ID of message template
- **threadId** (string) (e.g. `thread123`): ID of message thread. For email messages, this is the message ID that contains multiple email messages in the thread
- **scheduledTimestamp** (number) (e.g. `1669287863`): UTC Timestamp (in seconds) at which the message should be scheduled
- **conversationProviderId** (string) (e.g. `provider123`): ID of conversation provider
- **emailTo** (string) (e.g. `recipient@company.com`): Email address to send to, if different from contact's primary email. This should be a valid email address associated with the contact.
- **customSubtypeId** (string) (e.g. `507f1f77bcf86cd799439011`): Custom subtype ID for email unsubscription preferences. Only applies to email messages.
- **emailReplyMode** (string) (e.g. `reply_all`): Mode for email replies
- **fromNumber** (string) (e.g. `+1499499299`): Phone number used as the sender number for outbound messages
- **toNumber** (string) (e.g. `+1439499299`): Recipient phone number for outbound messages
- **forward** (string) (e.g. `{'isForwarded': True, 'forwardWholeThread': False, 'messageId': 't22c6DQcTDf3MjRhwf77', 'emailMessageId': 'rnGyqh2F6uBrIkfhFo9A', 'toEmail': 'forward@example.com', 'recipientContactId': 'DEF56h2F6uBrIkfXYacd'}`): Forwarding configuration for emails
- **status** (string) (required) (e.g. `delivered`): Message status
- **usesNativeSchedulingAi** (boolean) (e.g. `False`): Whether the scheduled email uses native AI for the email scheduling
- **optimizationPeriod** (string) (e.g. `24h`): Optimization period in hours (24h, 48h, or 72h)
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Created the message | - **conversationId** (string) (required) (e.g. `ABC12h2F6uBrIkfXYazb`): Conversation ID.
- **emailMessageId** (string) (e.g. `rnGyqh2F6uBrIkfhF... |
| `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. |
### ⚠️ 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 /conversations/messages/email/{emailMessageId}/schedule
**Summary:** Cancel a scheduled email message.
Post the messageId for the API to delete a scheduled email message.
**Version Header:** Not required
**Operation ID:** `cancel-scheduled-email-message`
**Tags:** Email
### cURL
```bash
curl -X DELETE 'https://rest.gohighlevel.com/v1/conversations/messages/email/ve9EPM428h8vShlRW1KT/schedule' \
-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('DELETE', '/v1/conversations/messages/email/ve9EPM428h8vShlRW1KT/schedule', 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 schedule",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "DELETE",
"url": "https://rest.gohighlevel.com/v1/conversations/messages/email/ve9EPM428h8vShlRW1KT/schedule",
"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": 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 |
|------|----------|------|----------|-------------|
| `emailMessageId` | Path | `string` | ✅ | Email Message Id [example: `ve9EPM428h8vShlRW1KT`] |
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | The scheduled email message was cancelled successfully | - **status** (number) (required) (e.g. `404`): HTTP Status code of the request
- **message** (string) (required) (e.g. `Failed cancel the sched... |
### ⚠️ 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 /conversations/messages/email/{id}
**Summary:** Get email by Id
Get email by Id
**Version Header:** Not required
**Operation ID:** `get-email-by-id`
**Tags:** Email
### cURL
```bash
curl -X GET 'https://rest.gohighlevel.com/v1/conversations/messages/email/{id}' \
-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('GET', '/v1/conversations/messages/email/{id}', 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 {id}",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "GET",
"url": "https://rest.gohighlevel.com/v1/conversations/messages/email/{id}",
"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": 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
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Email object for the id given. | - **id** (string) (required) (e.g. `ve9EPM428h8vShlRW1KT`)
- **altId** (string) (e.g. `ve9EPM428h8vShlRW1KT`): External Id
- **threadId** (st... |
### ⚠️ 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 /conversations/messages/export
**Summary:** Export messages by location ID
Export messages for a specific location with cursor-based pagination support. Response includes messageType (string), source, and subType fields. The channel parameter is optional - if not provided, all non-email message types will be returned including activity messages (opportunity updates, appointments, etc.).
**Version Header:** `2021-04-15`
**Operation ID:** `export-messages-by-location`
**Tags:** Messages
### cURL
```bash
curl -X GET 'https://rest.gohighlevel.com/v1/conversations/messages/export?locationId=VALUE&limit=VALUE&cursor=eyJwaXRJZCI6ImFiYy0xMjMiLCJsYXN0U29ydCI6WzE2NDY4NjQ0MDBdLCJsYXN0SWQiOiIxMjMifQ==&sortBy=createdAt&sortOrder=asc&conversationId=VALUE&contactId=VALUE&channel=Call&startDate=VALUE&endDate=VALUE' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
conn.request('GET', '/v1/conversations/messages/export?locationId=VALUE&limit=VALUE&cursor=eyJwaXRJZCI6ImFiYy0xMjMiLCJsYXN0U29ydCI6WzE2NDY4NjQ0MDBdLCJsYXN0SWQiOiIxMjMifQ==&sortBy=VALUE&sortOrder=VALUE&conversationId=VALUE&contactId=VALUE&channel=VALUE&startDate=VALUE&endDate=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 export",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "GET",
"url": "https://rest.gohighlevel.com/v1/conversations/messages/export",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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": "cursor",
"value": "eyJwaXRJZCI6ImFiYy0xMjMiLCJsYXN0U29ydCI6WzE2NDY4NjQ0MDBdLCJsYXN0SWQiOiIxMjMifQ=="
},
{
"name": "sortBy",
"value": "VALUE"
},
{
"name": "sortOrder",
"value": "VALUE"
},
{
"name": "conversationId",
"value": "VALUE"
},
{
"name": "contactId",
"value": "VALUE"
},
{
"name": "channel",
"value": "VALUE"
},
{
"name": "startDate",
"value": "VALUE"
},
{
"name": "endDate",
"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 filter messages by |
| `limit` | Query | `number` | — | Number of messages to return per page |
| `cursor` | Query | `string` | — | Cursor for pagination. Pass the nextCursor from previous response to get next page. [example: `ey... |
| `sortBy` | Query | `string` | — | Field to sort by (values: createdAt, updatedAt) |
| `sortOrder` | Query | `string` | — | Sort order (values: asc, desc) |
| `conversationId` | Query | `string` | — | Filter messages by conversation ID |
| `contactId` | Query | `string` | — | Filter messages by contact ID |
| `channel` | Query | `string` | — | Filter by message channel. If not provided, all non-email message types will be returned includin... |
| `startDate` | Query | `string` | — | Start date to filter messages by |
| `endDate` | Query | `string` | — | End date to filter messages by |
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | List of messages for the location with pagination details. | - **messages** (array of GetMessageResponseDto) (required): Array of messages
- **nextCursor** (string) (e.g. `eyJwaXRJZCI6ImFiYy0xMjMiLCJsYXN0... |
| `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. |
### ⚠️ 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 /conversations/messages/inbound
**Summary:** Add an inbound message
Post the necessary fields for the API to add a new inbound message.
**Version Header:** `2021-04-15`
**Operation ID:** `add-an-inbound-message`
**Tags:** Messages
### cURL
```bash
curl -X POST 'https://rest.gohighlevel.com/v1/conversations/messages/inbound' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
payload = json.dumps({})
conn.request('POST', '/v1/conversations/messages/inbound', 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 inbound",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://rest.gohighlevel.com/v1/conversations/messages/inbound",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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
- **type** (string) (required) (e.g. `SMS`): Message Type
- **attachments** (array): Array of attachments
- **message** (string): Message Body
- **conversationId** (string) (required) (e.g. `ve9EPM428h8vShlRW1KT`): Conversation Id
- **contactId** (string) (required) (e.g. `ve9EPM428h8vShlRW1KT`): Contact Id
- **conversationProviderId** (string) (required) (e.g. `61d6d1f9cdac7612faf80753`): Conversation Provider Id
- **html** (string): HTML Body of Email
- **subject** (string): Subject of the Email
- **emailFrom** (string) (e.g. `sender@company.com`): Email address to send from. This field is associated with the contact record and cannot be dynamically changed.
- **emailTo** (string): Recipient email address. This field is associated with the contact record and cannot be dynamically changed.
- **emailCc** (array) (e.g. `['john1@doe.com', 'john2@doe.com']`): List of email address to CC
- **emailBcc** (array) (e.g. `['john1@doe.com', 'john2@doe.com']`): List of email address to BCC
- **emailMessageId** (string): Send the email message id for which this email should be threaded. This is for replying to a specific email
- **altId** (string) (e.g. `61d6d1f9cdac7612faf80753`): external mail provider's message id
- **direction** (object) (e.g. `['outbound', 'inbound']`): Message direction, if required can be set manually, default is outbound
- **date** (string): Date of the inbound message
- **call** (string): Phone call dialer and receiver information
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Created the message | - **success** (boolean) (required)
- **conversationId** (string) (required) (e.g. `ABC12h2F6uBrIkfXYazb`): Conversation ID.
- **messageId** (... |
| `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. |
### ⚠️ 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 /conversations/messages/outbound
**Summary:** Add an external outbound call
Post the necessary fields for the API to add a new outbound call.
**Version Header:** `2021-04-15`
**Operation ID:** `add-an-outbound-message`
**Tags:** Messages
### cURL
```bash
curl -X POST 'https://rest.gohighlevel.com/v1/conversations/messages/outbound' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
payload = json.dumps({})
conn.request('POST', '/v1/conversations/messages/outbound', 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 outbound",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://rest.gohighlevel.com/v1/conversations/messages/outbound",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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
- **type** (string) (required) (e.g. `Call`): Message Type
- **attachments** (array): Array of attachments
- **conversationId** (string) (required) (e.g. `ve9EPM428h8vShlRW1KT`): Conversation Id
- **conversationProviderId** (string) (required) (e.g. `61d6d1f9cdac7612faf80753`): Conversation Provider Id
- **altId** (string) (e.g. `61d6d1f9cdac7612faf80753`): external mail provider's message id
- **date** (string): Date of the outbound message
- **call** (string): Phone call dialer and receiver information
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Created the message | - **success** (boolean) (required)
- **conversationId** (string) (required) (e.g. `ABC12h2F6uBrIkfXYazb`): Conversation ID.
- **messageId** (... |
| `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. |
### ⚠️ 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 /conversations/messages/review-reply
**Summary:** Send a review reply to Google My Business
Post a reply to a customer review on Google My Business
**Version Header:** `2021-04-15`
**Operation ID:** `send-review-reply`
**Tags:** Messages
### cURL
```bash
curl -X POST 'https://rest.gohighlevel.com/v1/conversations/messages/review-reply' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
payload = json.dumps({})
conn.request('POST', '/v1/conversations/messages/review-reply', 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 review-reply",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://rest.gohighlevel.com/v1/conversations/messages/review-reply",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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
- **conversationId** (string) (required) (e.g. `conv123`): Conversation ID (must have reviewId)
- **locationId** (string) (required) (e.g. `loc123`): Location ID
- **message** (string) (required) (e.g. `Thank you for your review!`): Review reply message text
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Review reply sent successfully | - **conversationId** (string) (required) (e.g. `ABC12h2F6uBrIkfXYazb`): Conversation ID.
- **emailMessageId** (string) (e.g. `rnGyqh2F6uBrIkfhF... |
| `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. |
### ⚠️ 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 /conversations/messages/upload
**Summary:** Upload file attachments
Post the necessary fields for the API to upload files. The files need to be a buffer with the key "fileAttachment".
The allowed file types are:
- JPG
- JPEG
- PNG
- MP4
- MPEG
- ZIP
- RAR
- PDF
- DOC
- DOCX
- TXT
- MP3
- WAV
The API will return an object with the URLs
**Version Header:** `2021-04-15`
**Operation ID:** `upload-file-attachments`
**Tags:** Messages
### cURL
```bash
curl -X POST 'https://rest.gohighlevel.com/v1/conversations/messages/upload' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
conn.request('POST', '/v1/conversations/messages/upload', 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 upload",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://rest.gohighlevel.com/v1/conversations/messages/upload",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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` | Uploaded the file successfully | - **uploadedFiles** (object) (required)
- **twilioMediaSids** (array) (e.g. `['MExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx']`): Twilio media SIDs for gr... |
| `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. |
| `413` | Payload Too Large | - **status** (number) (required) (e.g. `413`): HTTP Status code of the request
- **message** (string) (required) (e.g. `Failed to upload the fi... |
| `415` | Unsupported Media Type | - **status** (number) (required) (e.g. `413`): HTTP Status code of the request
- **message** (string) (required) (e.g. `Failed to upload the fi... |
### ⚠️ 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 /conversations/messages/upload/complete
**Summary:** Complete file upload
Validates the uploaded file in GCS and returns the public URL. Call this endpoint after successfully uploading the file to the signed URL.
**Version Header:** `2021-04-15`
**Operation ID:** `complete-file-upload`
**Tags:** Messages
### cURL
```bash
curl -X POST 'https://rest.gohighlevel.com/v1/conversations/messages/upload/complete' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
payload = json.dumps({})
conn.request('POST', '/v1/conversations/messages/upload/complete', 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 complete",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://rest.gohighlevel.com/v1/conversations/messages/upload/complete",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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
- **uploadId** (string) (required) (e.g. `a1b2c3d4-e5f6-7890-abcd-ef1234567890`): Upload ID from request response
- **filePath** (string) (required) (e.g. `location/loc123/conversations/conv456/uuid.mp4`): File path from request response
- **locationId** (string) (required) (e.g. `ve9EPM428h8vShlRW1KT`): Location ID
- **conversationId** (string) (required) (e.g. `ve9EPM428h8vShlRW1KT`): Conversation ID
- **filename** (string) (required) (e.g. `video.mp4`): Original filename (for response mapping)
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Upload completed successfully | - **uploadedFiles** (object) (required) (e.g. `{'video.mp4': 'https://your-domain.com/conversations-assets/location/.../video.mp4'}`): Map of fil... |
| `400` | Bad Request - Invalid parameters | — |
| `401` | Unauthorized | Standard error response for unauthorized requests (401). Contains message, statusCode fields. |
| `404` | File not found in storage - upload may have failed or URL expired | — |
### ⚠️ 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 /conversations/messages/upload/initiate
**Summary:** Initiate file upload to GCS
Generates a signed URL for direct file upload to Google Cloud Storage. Returns a signed URL valid for 15 minutes. Upload file via PUT request, then call /complete to finalize.
**Version Header:** `2021-04-15`
**Operation ID:** `initiate-file-upload`
**Tags:** Messages
### cURL
```bash
curl -X POST 'https://rest.gohighlevel.com/v1/conversations/messages/upload/initiate' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
payload = json.dumps({})
conn.request('POST', '/v1/conversations/messages/upload/initiate', 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 initiate",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://rest.gohighlevel.com/v1/conversations/messages/upload/initiate",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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`): Location ID
- **conversationId** (string) (required) (e.g. `ve9EPM428h8vShlRW1KT`): Conversation ID
- **filename** (string) (required) (e.g. `video.mp4`): Original filename with extension
- **contentType** (string) (required) (e.g. `video/mp4`): MIME type of the file
- **fileSize** (number) (e.g. `52428800`): File size in bytes (optional, for pre-validation)
- **channel** (string) (required) (e.g. `WHATSAPP`): Channel type for size limits (WHATSAPP for 100MB limit, others for 5MB)
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Signed URL generated successfully | - **uploadUrl** (string) (required) (e.g. `https://storage.googleapis.com/bucket/path?X-Goog-Algorithm=...`): Signed URL for direct upload to GCS... |
| `400` | Bad Request - Invalid parameters | — |
| `401` | Unauthorized | Standard error response for unauthorized requests (401). Contains message, statusCode fields. |
| `413` | File size exceeds maximum allowed limit | — |
### ⚠️ 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 /conversations/messages/{id}
**Summary:** Get message by message id
Get message by message id.
**Version Header:** `2021-04-15`
**Operation ID:** `get-message`
**Tags:** Messages
### cURL
```bash
curl -X GET 'https://rest.gohighlevel.com/v1/conversations/messages/{id}' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
conn.request('GET', '/v1/conversations/messages/{id}', 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 {id}",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "GET",
"url": "https://rest.gohighlevel.com/v1/conversations/messages/{id}",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Message object for the id given. | - **id** (string) (required) (e.g. `ve9EPM428h8vShlRW1KT`)
- **type** (number) (required) (e.g. `1`)
- **messageType** (string) (required) (e... |
| `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. |
### ⚠️ 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.
---
## PUT /conversations/messages/{messageId}/attachments
**Summary:** Add message attachments
Set attachments on an existing message (replaces existing). Maximum 5 URLs. Supported for TYPE_CUSTOM_CALL (34) and TYPE_CALL (1) with subType EXTERNAL_CALL.
**Version Header:** `2021-04-15`
**Operation ID:** `add-message-attachments`
**Tags:** Messages
### cURL
```bash
curl -X PUT 'https://rest.gohighlevel.com/v1/conversations/messages/ve9EPM428h8vShlRW1KT/attachments' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
payload = json.dumps({})
conn.request('PUT', '/v1/conversations/messages/ve9EPM428h8vShlRW1KT/attachments', 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 - PUT attachments",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "PUT",
"url": "https://rest.gohighlevel.com/v1/conversations/messages/ve9EPM428h8vShlRW1KT/attachments",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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 Parameters
| Name | Location | Type | Required | Description |
|------|----------|------|----------|-------------|
| `messageId` | Path | `string` | ✅ | Message Id [example: `ve9EPM428h8vShlRW1KT`] |
### Request Body Schema
- **attachments** (array) (required) (e.g. `['https://provider.com/recordings/call-123.mp3']`): Array of attachment URLs to set on the message (replaces existing). Maximum 5 URLs.
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Successfully set message attachments | — |
| `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` | Message type does not support attachment updates | — |
| `404` | Message not found | — |
### ⚠️ 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 /conversations/messages/{messageId}/locations/{locationId}/recording
**Summary:** Get Recording by Message ID
Get the recording for a message by passing the message id
**Version Header:** `2021-04-15`
**Operation ID:** `get-message-recording`
**Tags:** Messages
### cURL
```bash
curl -X GET 'https://rest.gohighlevel.com/v1/conversations/messages/tDtDnQdgm2LXpyiqYvZ6/locations/tDtDnQdgm2LXpyiqYvZ6/recording' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
conn.request('GET', '/v1/conversations/messages/tDtDnQdgm2LXpyiqYvZ6/locations/tDtDnQdgm2LXpyiqYvZ6/recording', 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 recording",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "GET",
"url": "https://rest.gohighlevel.com/v1/conversations/messages/tDtDnQdgm2LXpyiqYvZ6/locations/tDtDnQdgm2LXpyiqYvZ6/recording",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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` | ✅ | Location ID as string [example: `tDtDnQdgm2LXpyiqYvZ6`] |
| `messageId` | Path | `string` | ✅ | Message ID as string [example: `tDtDnQdgm2LXpyiqYvZ6`] |
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Gives the attached recording to the message | — |
| `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. |
### ⚠️ 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 /conversations/messages/{messageId}/schedule
**Summary:** Cancel a scheduled message.
Post the messageId for the API to delete a scheduled message.
**Version Header:** `2021-04-15`
**Operation ID:** `cancel-scheduled-message`
**Tags:** Messages
### cURL
```bash
curl -X DELETE 'https://rest.gohighlevel.com/v1/conversations/messages/ve9EPM428h8vShlRW1KT/schedule' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
conn.request('DELETE', '/v1/conversations/messages/ve9EPM428h8vShlRW1KT/schedule', 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 schedule",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "DELETE",
"url": "https://rest.gohighlevel.com/v1/conversations/messages/ve9EPM428h8vShlRW1KT/schedule",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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 |
|------|----------|------|----------|-------------|
| `messageId` | Path | `string` | ✅ | Message Id [example: `ve9EPM428h8vShlRW1KT`] |
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | The scheduled message was cancelled successfully | - **status** (number) (required) (e.g. `404`): HTTP Status code of the request
- **message** (string) (required) (e.g. `Failed cancel the sched... |
| `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. |
### ⚠️ 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.
---
## PUT /conversations/messages/{messageId}/status
**Summary:** Update message status
Post the necessary fields for the API to update message status.
**Version Header:** `2021-04-15`
**Operation ID:** `update-message-status`
**Tags:** Messages
### cURL
```bash
curl -X PUT 'https://rest.gohighlevel.com/v1/conversations/messages/ve9EPM428h8vShlRW1KT/status' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
payload = json.dumps({})
conn.request('PUT', '/v1/conversations/messages/ve9EPM428h8vShlRW1KT/status', 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 - PUT status",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "PUT",
"url": "https://rest.gohighlevel.com/v1/conversations/messages/ve9EPM428h8vShlRW1KT/status",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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 Parameters
| Name | Location | Type | Required | Description |
|------|----------|------|----------|-------------|
| `messageId` | Path | `string` | ✅ | Message Id [example: `ve9EPM428h8vShlRW1KT`] |
### Request Body Schema
- **status** (string) (required) (e.g. `read`): Message status
- **error** (string): Error object from the conversation provider
- **emailMessageId** (string) (e.g. `ve9EPM428h8vShlRW1KT`): Email message Id
- **recipients** (array): Email delivery status for additional email recipients.
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Created the message | - **conversationId** (string) (required) (e.g. `ABC12h2F6uBrIkfXYazb`): Conversation ID.
- **emailMessageId** (string) (e.g. `rnGyqh2F6uBrIkfhF... |
| `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. |
### ⚠️ 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 /conversations/preferences/custom-subtypes
**Summary:** Get All Custom Subtypes
Get all custom subtypes for a location
**Version Header:** `2021-04-15`
**Operation ID:** `get-all-custom-subtypes`
**Tags:** Preference Management
### cURL
```bash
curl -X GET 'https://rest.gohighlevel.com/v1/conversations/preferences/custom-subtypes?locationId=ve9EPM428h8vShlRW1KT' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
conn.request('GET', '/v1/conversations/preferences/custom-subtypes?locationId=ve9EPM428h8vShlRW1KT', 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 custom-subtypes",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "GET",
"url": "https://rest.gohighlevel.com/v1/conversations/preferences/custom-subtypes",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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": "ve9EPM428h8vShlRW1KT"
}
]
}
}
}
```
**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 [example: `ve9EPM428h8vShlRW1KT`] |
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | | — |
| `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. |
### ⚠️ 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 /conversations/preferences/custom-subtypes
**Summary:** Create Custom Subtype
Create a new custom subtype for a location. Requires agency or account admin role.
**Version Header:** `2021-04-15`
**Operation ID:** `create-custom-subtype`
**Tags:** Preference Management
### cURL
```bash
curl -X POST 'https://rest.gohighlevel.com/v1/conversations/preferences/custom-subtypes?locationId=ve9EPM428h8vShlRW1KT' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
payload = json.dumps({})
conn.request('POST', '/v1/conversations/preferences/custom-subtypes?locationId=ve9EPM428h8vShlRW1KT', 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 custom-subtypes",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://rest.gohighlevel.com/v1/conversations/preferences/custom-subtypes",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Accept",
"value": "application/json"
},
{
"name": "User-Agent",
"value": "YourApp/1.0"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": []
},
"options": {},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "locationId",
"value": "ve9EPM428h8vShlRW1KT"
}
]
}
}
}
```
**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 [example: `ve9EPM428h8vShlRW1KT`] |
### Request Body Schema
- **name** (string) (required) (e.g. `Newsletter Subscription`): Name of the custom subtype (max 100 characters)
- **description** (string) (e.g. `Weekly newsletter subscription preferences`): Description of the custom subtype (max 100 characters)
- **channel** (string) (required) (e.g. `email`): Communication channel
- **language** (string) (required) (e.g. `en`): Language code
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Successful response | — |
| `201` | | — |
| `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. |
### ⚠️ 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.
---
## PUT /conversations/preferences/custom-subtypes/{id}
**Summary:** Update Custom Subtype
Update or archive a custom subtype. Requires agency or account admin role.
**Version Header:** `2021-04-15`
**Operation ID:** `update-custom-subtype`
**Tags:** Preference Management
### cURL
```bash
curl -X PUT 'https://rest.gohighlevel.com/v1/conversations/preferences/custom-subtypes/ve9EPM428h8vShlRW1KT?locationId=ve9EPM428h8vShlRW1KT' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
payload = json.dumps({})
conn.request('PUT', '/v1/conversations/preferences/custom-subtypes/ve9EPM428h8vShlRW1KT?locationId=ve9EPM428h8vShlRW1KT', 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 - PUT ve9EPM428h8vShlRW1KT",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "PUT",
"url": "https://rest.gohighlevel.com/v1/conversations/preferences/custom-subtypes/ve9EPM428h8vShlRW1KT",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Accept",
"value": "application/json"
},
{
"name": "User-Agent",
"value": "YourApp/1.0"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": []
},
"options": {},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "locationId",
"value": "ve9EPM428h8vShlRW1KT"
}
]
}
}
}
```
**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 |
|------|----------|------|----------|-------------|
| `id` | Path | `string` | ✅ | Custom Subtype Id [example: `ve9EPM428h8vShlRW1KT`] |
| `locationId` | Query | `string` | ✅ | Location Id [example: `ve9EPM428h8vShlRW1KT`] |
### Request Body Schema
- **name** (string) (e.g. `Newsletter Subscription`): Name of the custom subtype (max 100 characters)
- **description** (string) (e.g. `Updated weekly newsletter subscription preferences`): Description of the custom subtype (max 100 characters)
- **archived** (boolean) (e.g. `False`): Whether the custom subtype is archived
- **resubscription_legal_form_id** (string) (e.g. `form_123456`): Resubscription legal form ID (optional when archiving)
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | | — |
| `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. |
### ⚠️ 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 /conversations/preferences/unsubscriptions/status
**Summary:** Get Contact Unsubscription Status
Get all subscription statuses for a contact (all emails or specific email)
**Version Header:** `2021-04-15`
**Operation ID:** `get-contact-unsubscription-status`
**Tags:** Preference Management
### cURL
```bash
curl -X GET 'https://rest.gohighlevel.com/v1/conversations/preferences/unsubscriptions/status?locationId=ve9EPM428h8vShlRW1KT&contactId=OP7z4LCyPACyH5fcEIZa&email=user@example.com' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
conn.request('GET', '/v1/conversations/preferences/unsubscriptions/status?locationId=ve9EPM428h8vShlRW1KT&contactId=OP7z4LCyPACyH5fcEIZa&email=user@example.com', 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 status",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "GET",
"url": "https://rest.gohighlevel.com/v1/conversations/preferences/unsubscriptions/status",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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": "ve9EPM428h8vShlRW1KT"
},
{
"name": "contactId",
"value": "OP7z4LCyPACyH5fcEIZa"
},
{
"name": "email",
"value": "user@example.com"
}
]
}
}
}
```
**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 [example: `ve9EPM428h8vShlRW1KT`] |
| `contactId` | Query | `string` | ✅ | Contact Id [example: `OP7z4LCyPACyH5fcEIZa`] |
| `email` | Query | `string` | — | Email address (optional - if not provided, gets all emails for contact) [example: `user@example.c... |
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | | — |
| `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. |
### ⚠️ 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 /conversations/preferences/unsubscriptions/user-change
**Summary:** User Subscription Change
Process subscription change initiated by a user (admin/agent). Supports individual custom subscription changes and resub all functionality. Legal forms are automatically created for user-initiated resubscribe actions on custom subscriptions.
**Version Header:** `2021-04-15`
**Operation ID:** `user-subscription-change`
**Tags:** Preference Management
### cURL
```bash
curl -X POST 'https://rest.gohighlevel.com/v1/conversations/preferences/unsubscriptions/user-change' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
payload = json.dumps({})
conn.request('POST', '/v1/conversations/preferences/unsubscriptions/user-change', 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 user-change",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://rest.gohighlevel.com/v1/conversations/preferences/unsubscriptions/user-change",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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`): Location Id
- **contactId** (string) (required) (e.g. `OP7z4LCyPACyH5fcEIZa`): Contact Id
- **email** (string) (required) (e.g. `user@example.com`): Email address
- **subscription_action** (string) (required): Subscription action details
- **legal_reason** (string) (e.g. `User requested resubscribe via customer service`): Legal reason for the change (required only for resubscribe and resub_all actions)
- **legal_description** (string) (e.g. `Customer called support on 2024-01-15 requesting to be removed from newsletter`): Legal description/details
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Successful response | — |
| `201` | | — |
| `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. |
### ⚠️ 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 /conversations/providers/live-chat/typing
**Summary:** Agent/Ai-Bot is typing a message indicator for live chat
Agent/AI-Bot will call this when they are typing a message in live chat message
**Version Header:** `2021-04-15`
**Operation ID:** `live-chat-agent-typing`
**Tags:** Providers
### cURL
```bash
curl -X POST 'https://rest.gohighlevel.com/v1/conversations/providers/live-chat/typing' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
payload = json.dumps({})
conn.request('POST', '/v1/conversations/providers/live-chat/typing', 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 typing",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://rest.gohighlevel.com/v1/conversations/providers/live-chat/typing",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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`): Location Id
- **isTyping** (string) (required) (e.g. `True`): Typing status
- **visitorId** (string) (required) (e.g. `ve9EPM428h8vShlRW1KT`): visitorId is the Unique ID assigned to each Live chat visitor. visitorId will be added soon in GET Contact API
- **conversationId** (string) (required) (e.g. `ve9EPM428h8vShlRW1KT`): Conversation Id
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `201` | Show typing indicator for live chat | - **success** (boolean) (required) |
| `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.
---
## GET /conversations/search
**Summary:** Search Conversations
Returns a list of all conversations matching the search criteria along with the sort and filter options selected.
**Version Header:** `2021-04-15`
**Operation ID:** `search-conversation`
**Tags:** Search
### cURL
```bash
curl -X GET 'https://rest.gohighlevel.com/v1/conversations/search?locationId=ABCHkzuJQ8ZMd4Te84GK&contactId=9VEmS0si86GW6gXWU89b&assignedTo=ABCHkzuJQ8ZMd4Te84GK,fGiae4CHkzoskh8thsik&followers=ABCHkzuJQ8ZMd4Te84GK,fGiae4CHkzoskh8thsik&mentions=ABCHkzuJQ8ZMd4Te84GK,fGiae4CHkzoskh8thsik&query=Search string&sort=asc&startAfterDate=1600854&id=ABCHkzuJQ8ZMd4Te84GK&limit=20&lastMessageType=TYPE_SMS&lastMessageAction=manual&lastMessageDirection=inbound&status=all&sortBy=last_message_date&sortScoreProfile=ABCHkzuJQ8ZMd4Te84GK&scoreProfile=ABCHkzuJQ8ZMd4Te84GK&scoreProfileMin=ABCHkzuJQ8ZMd4Te84GK&scoreProfileMax=ABCHkzuJQ8ZMd4Te84GK&startDate=1640995200000&endDate=1672531199000' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
conn.request('GET', '/v1/conversations/search?locationId=ABCHkzuJQ8ZMd4Te84GK&contactId=9VEmS0si86GW6gXWU89b&assignedTo=ABCHkzuJQ8ZMd4Te84GK,fGiae4CHkzoskh8thsik&followers=ABCHkzuJQ8ZMd4Te84GK,fGiae4CHkzoskh8thsik&mentions=ABCHkzuJQ8ZMd4Te84GK,fGiae4CHkzoskh8thsik&query=Search string&sort=asc&startAfterDate=1600854&id=ABCHkzuJQ8ZMd4Te84GK&limit=20&lastMessageType=TYPE_SMS&lastMessageAction=manual&lastMessageDirection=inbound&status=all&sortBy=last_message_date&sortScoreProfile=ABCHkzuJQ8ZMd4Te84GK&scoreProfile=ABCHkzuJQ8ZMd4Te84GK&scoreProfileMin=ABCHkzuJQ8ZMd4Te84GK&scoreProfileMax=ABCHkzuJQ8ZMd4Te84GK&startDate=1640995200000&endDate=1672531199000', 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 search",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "GET",
"url": "https://rest.gohighlevel.com/v1/conversations/search",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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": "ABCHkzuJQ8ZMd4Te84GK"
},
{
"name": "contactId",
"value": "9VEmS0si86GW6gXWU89b"
},
{
"name": "assignedTo",
"value": "ABCHkzuJQ8ZMd4Te84GK,fGiae4CHkzoskh8thsik"
},
{
"name": "followers",
"value": "ABCHkzuJQ8ZMd4Te84GK,fGiae4CHkzoskh8thsik"
},
{
"name": "mentions",
"value": "ABCHkzuJQ8ZMd4Te84GK,fGiae4CHkzoskh8thsik"
},
{
"name": "query",
"value": "Search string"
},
{
"name": "sort",
"value": "asc"
},
{
"name": "startAfterDate",
"value": 1600854
},
{
"name": "id",
"value": "ABCHkzuJQ8ZMd4Te84GK"
},
{
"name": "limit",
"value": 20
},
{
"name": "lastMessageType",
"value": "TYPE_SMS"
},
{
"name": "lastMessageAction",
"value": "manual"
},
{
"name": "lastMessageDirection",
"value": "inbound"
},
{
"name": "status",
"value": "all"
},
{
"name": "sortBy",
"value": "last_message_date"
},
{
"name": "sortScoreProfile",
"value": "ABCHkzuJQ8ZMd4Te84GK"
},
{
"name": "scoreProfile",
"value": "ABCHkzuJQ8ZMd4Te84GK"
},
{
"name": "scoreProfileMin",
"value": "ABCHkzuJQ8ZMd4Te84GK"
},
{
"name": "scoreProfileMax",
"value": "ABCHkzuJQ8ZMd4Te84GK"
},
{
"name": "startDate",
"value": 1640995200000
},
{
"name": "endDate",
"value": 1672531199000
}
]
}
}
}
```
**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 [example: `ABCHkzuJQ8ZMd4Te84GK`] |
| `contactId` | Query | `string` | — | Contact Id [example: `9VEmS0si86GW6gXWU89b`] |
| `assignedTo` | Query | `string` | — | User IDs that conversations are assigned to. Multiple IDs can be provided as comma-separated valu... |
| `followers` | Query | `string` | — | User IDs of followers to filter conversations by. Multiple IDs can be provided as comma-separated... |
| `mentions` | Query | `string` | — | User Id of the mention. Multiple values are comma separated. [example: `ABCHkzuJQ8ZMd4Te84GK,fGia... |
| `query` | Query | `string` | — | Search paramater as a string [example: `Search string`] |
| `sort` | Query | `string` | — | Sort paramater - asc or desc (values: asc, desc) [example: `asc`] |
| `startAfterDate` | Query | `any` | — | Search to begin after the specified date - should contain the sort value of the last document [ex... |
| `id` | Query | `string` | — | Id of the conversation [example: `ABCHkzuJQ8ZMd4Te84GK`] |
| `limit` | Query | `number` | — | Limit of conversations - Default is 20 [example: `20`] |
| `lastMessageType` | Query | `string` | — | Type of the last message in the conversation as a string (values: TYPE_CALL, TYPE_SMS, TYPE_RCS, ... |
| `lastMessageAction` | Query | `string` | — | Action of the last outbound message in the conversation as string. (values: automated, manual) [e... |
| `lastMessageDirection` | Query | `string` | — | Direction of the last message in the conversation as string. (values: inbound, outbound) [example... |
| `status` | Query | `string` | — | The status of the conversation to be filtered - all, read, unread, starred (values: all, read, u... |
| `sortBy` | Query | `string` | — | The sorting of the conversation to be filtered as - manual messages or all messages (values: last... |
| `sortScoreProfile` | Query | `string` | — | Id of score profile on which sortBy.ScoreProfile should sort on [example: `ABCHkzuJQ8ZMd4Te84GK`] |
| `scoreProfile` | Query | `string` | — | Id of score profile on which conversations should get filtered out, works with scoreProfileMin & ... |
| `scoreProfileMin` | Query | `number` | — | Minimum value for score [example: `ABCHkzuJQ8ZMd4Te84GK`] |
| `scoreProfileMax` | Query | `number` | — | Maximum value for score [example: `ABCHkzuJQ8ZMd4Te84GK`] |
| `startDate` | Query | `number` | — | Start date filter for dateAdded field (Unix timestamp in milliseconds) [example: `1640995200000`] |
| `endDate` | Query | `number` | — | End date filter for dateAdded field (Unix timestamp in milliseconds) [example: `1672531199000`] |
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Successfully fetched the conversations | - **conversations** (array of ConversationSchema) (required): The list of all conversations found for the given query
- **total** (number) (req... |
| `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. |
### ⚠️ 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 /conversations/{conversationId}
**Summary:** Delete Conversation
Delete the conversation details based on the conversation ID
**Version Header:** `2021-04-15`
**Operation ID:** `delete-conversation`
**Tags:** Conversations
### cURL
```bash
curl -X DELETE 'https://rest.gohighlevel.com/v1/conversations/tDtDnQdgm2LXpyiqYvZ6' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
conn.request('DELETE', '/v1/conversations/tDtDnQdgm2LXpyiqYvZ6', 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 tDtDnQdgm2LXpyiqYvZ6",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "DELETE",
"url": "https://rest.gohighlevel.com/v1/conversations/tDtDnQdgm2LXpyiqYvZ6",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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 |
|------|----------|------|----------|-------------|
| `conversationId` | Path | `string` | ✅ | Conversation ID as string [example: `tDtDnQdgm2LXpyiqYvZ6`] |
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Successful response | - **success** (boolean) (required) (e.g. `True`): Boolean value as the API response. |
| `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. |
### ⚠️ 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 /conversations/{conversationId}
**Summary:** Get Conversation
Get the conversation details based on the conversation ID
**Version Header:** `2021-04-15`
**Operation ID:** `get-conversation`
**Tags:** Conversations
### cURL
```bash
curl -X GET 'https://rest.gohighlevel.com/v1/conversations/tDtDnQdgm2LXpyiqYvZ6' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
conn.request('GET', '/v1/conversations/tDtDnQdgm2LXpyiqYvZ6', 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 tDtDnQdgm2LXpyiqYvZ6",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "GET",
"url": "https://rest.gohighlevel.com/v1/conversations/tDtDnQdgm2LXpyiqYvZ6",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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 |
|------|----------|------|----------|-------------|
| `conversationId` | Path | `string` | ✅ | Conversation ID as string [example: `tDtDnQdgm2LXpyiqYvZ6`] |
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Successful response | - **contactId** (string) (required) (e.g. `ve9EPM428kjkvShlRW1KT`): Unique identifier of the contact associated with this conversation
- **loca... |
| `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. |
### ⚠️ 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.
---
## PUT /conversations/{conversationId}
**Summary:** Update Conversation
Update the conversation details based on the conversation ID
**Version Header:** `2021-04-15`
**Operation ID:** `update-conversation`
**Tags:** Conversations
### cURL
```bash
curl -X PUT 'https://rest.gohighlevel.com/v1/conversations/tDtDnQdgm2LXpyiqYvZ6' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
payload = json.dumps({})
conn.request('PUT', '/v1/conversations/tDtDnQdgm2LXpyiqYvZ6', 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 - PUT tDtDnQdgm2LXpyiqYvZ6",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "PUT",
"url": "https://rest.gohighlevel.com/v1/conversations/tDtDnQdgm2LXpyiqYvZ6",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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 Parameters
| Name | Location | Type | Required | Description |
|------|----------|------|----------|-------------|
| `conversationId` | Path | `string` | ✅ | Conversation ID as string [example: `tDtDnQdgm2LXpyiqYvZ6`] |
### Request Body Schema
- **locationId** (string) (required) (e.g. `tDtDnQdgm2LXpyiqYvZ6`): Location ID as string
- **unreadCount** (number) (e.g. `1`): Count of unread messages in the conversation
- **starred** (boolean) (e.g. `True`): Starred status of the conversation.
- **feedback** (object)
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | Successful response | - **success** (boolean) (required) (e.g. `True`): Boolean value as the API response.
- **conversation** (string) (required): Conversation data ... |
| `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. |
### ⚠️ 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 /conversations/{conversationId}/messages
**Summary:** Get messages by conversation id
Get messages by conversation id.
**Version Header:** `2021-04-15`
**Operation ID:** `get-messages`
**Tags:** Messages
### cURL
```bash
curl -X GET 'https://rest.gohighlevel.com/v1/conversations/tDtDnQdgm2LXpyiqYvZ6/messages?lastMessageId=tDtDnQdgm2LXpyiqYvZ6&limit=20&type=TYPE_SMS,TYPE_CALL' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Version: 2021-04-15' \
-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-04-15',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'YourApp/1.0',
}
conn.request('GET', '/v1/conversations/tDtDnQdgm2LXpyiqYvZ6/messages?lastMessageId=tDtDnQdgm2LXpyiqYvZ6&limit=20&type=TYPE_SMS,TYPE_CALL', 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 messages",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "GET",
"url": "https://rest.gohighlevel.com/v1/conversations/tDtDnQdgm2LXpyiqYvZ6/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_API_TOKEN"
},
{
"name": "Version",
"value": "2021-04-15"
},
{
"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": "lastMessageId",
"value": "tDtDnQdgm2LXpyiqYvZ6"
},
{
"name": "limit",
"value": 20
},
{
"name": "type",
"value": "TYPE_SMS,TYPE_CALL"
}
]
}
}
}
```
**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 |
|------|----------|------|----------|-------------|
| `conversationId` | Path | `string` | ✅ | Conversation ID as string [example: `tDtDnQdgm2LXpyiqYvZ6`] |
| `lastMessageId` | Query | `string` | — | Message ID of the last message in the list as a string [example: `tDtDnQdgm2LXpyiqYvZ6`] |
| `limit` | Query | `number` | — | Number of messages to be fetched from the conversation. Default limit is 20 [example: `20`] |
| `type` | Query | `string` | — | Types of message to fetched separated with comma (values: TYPE_CALL, TYPE_SMS, TYPE_RCS, TYPE_EMA... |
### Response Codes
| Code | Description | Schema |
|------|-------------|--------|
| `200` | List of messages for the conversation id of the given type. | - **lastMessageId** (string) (required) (e.g. `p1mRSHeLDhAms5q0LMr4`): Id of the last message in the messages array
- **nextPage** (boolean) (r... |
| `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. |
### ⚠️ 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.*