# 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.<br>  - **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<br>  - **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. `<p>Hello World</p>`): 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.<br>  - **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. <br />

**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<br>  - **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`)<br>  - **altId** (string) (e.g. `ve9EPM428h8vShlRW1KT`): External Id<br>  - **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<br>  - **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. <br />

**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)<br>  - **conversationId** (string) (required) (e.g. `ABC12h2F6uBrIkfXYazb`): Conversation ID.<br>  - **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)<br>  - **conversationId** (string) (required) (e.g. `ABC12h2F6uBrIkfXYazb`): Conversation ID.<br>  - **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.<br>  - **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". <br /><br /> The allowed file types are: <br/> <ul><li>JPG</li><li>JPEG</li><li>PNG</li><li>MP4</li><li>MPEG</li><li>ZIP</li><li>RAR</li><li>PDF</li><li>DOC</li><li>DOCX</li><li>TXT</li><li>MP3</li><li>WAV</li></ul> <br /><br /> 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)<br>  - **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<br>  - **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<br>  - **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`)<br>  - **type** (number) (required) (e.g. `1`)<br>  - **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. <br />

**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<br>  - **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.<br>  - **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 <a href="https://highlevel.stoplight.io/docs/integrations/00c5ff21f0030-get-contact" target="_blank">GET Contact API</a>
  - **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<br>  - **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<br>  - **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.<br>  - **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<br>  - **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.*