# GHL Users API

> ⚠️ **Deprecations:** Email update is deprecated. User deletion is asynchronous (returns 202 Accepted). `GET /users/` is deprecated — use `GET /users/search` instead.

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

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

---

## Endpoints

- [GET /users/](#get--users-) — Get User by Location
- [POST /users/](#post--users-) — Create User
- [GET /users/search](#get--users-search) — Search Users
- [POST /users/search/filter-by-email](#post--users-search-filter-by-email) — Filter Users by Email
- [DELETE /users/{userId}](#delete--users-userId) — Delete User
- [GET /users/{userId}](#get--users-userId) — Get User
- [PUT /users/{userId}](#put--users-userId) — Update User

---

## GET /users/

> ⚠️ **DEPRECATED** — This endpoint is deprecated and may be removed in a future version.

**Summary:** Get User by Location

Deprecated. Use `GET /users/search` instead. Pass `locationId` as a query parameter to filter results by location, along with the required `companyId` and other search filters as needed.

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

**Operation ID:** `get-user-by-location`

**Tags:** Users

### cURL

```bash
curl -X GET 'https://rest.gohighlevel.com/v1/users/?locationId=s4BtzHFWmT28mbb85uPa' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Version: 2021-07-28' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'User-Agent: YourApp/1.0'
```

### Python (http.client)

```python
import http.client
import json

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

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

conn.request('GET', '/v1/users/?locationId=s4BtzHFWmT28mbb85uPa', 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 users",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "GET",
    "url": "https://rest.gohighlevel.com/v1/users/",
    "authentication": "genericCredentialType",
    "genericAuthType": "httpHeaderAuth",
    "sendHeaders": true,
    "headerParameters": {
      "parameters": [
        {
          "name": "Authorization",
          "value": "Bearer YOUR_API_TOKEN"
        },
        {
          "name": "Version",
          "value": "2021-07-28"
        },
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Accept",
          "value": "application/json"
        },
        {
          "name": "User-Agent",
          "value": "YourApp/1.0"
        }
      ]
    },
    "sendBody": false,
    "bodyParameters": {
      "parameters": []
    },
    "options": {},
    "sendQuery": true,
    "queryParameters": {
      "parameters": [
        {
          "name": "locationId",
          "value": "s4BtzHFWmT28mbb85uPa"
        }
      ]
    }
  }
}
```

**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` | ✅ |  [example: `s4BtzHFWmT28mbb85uPa`] |

### Response Codes

| Code | Description | Schema |
|------|-------------|--------|
| `200` | Successful response |   - **users** (array of UserSchema) |
| `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 /users/

**Summary:** Create User

Create User

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

**Operation ID:** `create-user`

**Tags:** Users

### cURL

```bash
curl -X POST 'https://rest.gohighlevel.com/v1/users/' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Version: 2021-07-28' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'User-Agent: YourApp/1.0' \
  -d '{}'  # See request body schema below
```

### Python (http.client)

```python
import http.client
import json

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

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

payload = json.dumps({})
conn.request('POST', '/v1/users/', 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 users",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "POST",
    "url": "https://rest.gohighlevel.com/v1/users/",
    "authentication": "genericCredentialType",
    "genericAuthType": "httpHeaderAuth",
    "sendHeaders": true,
    "headerParameters": {
      "parameters": [
        {
          "name": "Authorization",
          "value": "Bearer YOUR_API_TOKEN"
        },
        {
          "name": "Version",
          "value": "2021-07-28"
        },
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Accept",
          "value": "application/json"
        },
        {
          "name": "User-Agent",
          "value": "YourApp/1.0"
        }
      ]
    },
    "sendBody": true,
    "bodyParameters": {
      "parameters": []
    },
    "options": {}
  }
}
```

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

### Request Body Schema

  - **companyId** (string) (required) (e.g. `ve9EPM428h8vShlRW1KT`)
  - **firstName** (string) (required) (e.g. `John`)
  - **lastName** (string) (required) (e.g. `Deo`)
  - **email** (string) (required) (e.g. `john@deo.com`)
  - **password** (string) (required) (e.g. `*******`)
  - **phone** (string) (e.g. `+18832327657`)
  - **type** (string) (required) (e.g. `account`)
  - **role** (string) (required) (e.g. `admin`)
  - **locationIds** (array) (required) (e.g. `['C2QujeCh8ZnC7al2InWR']`)
  - **permissions** (PermissionsDto)
  - **scopes** (array) (e.g. `['contacts.write', 'campaigns.readonly']`): Scopes allowed for users. Only scopes that have been passed will be enabled. Note:- If passed empty all the scopes will be get disabled
  - **scopesAssignedToOnly** (array) (e.g. `['contacts.write', 'campaigns.readonly']`): Assigned Scopes allowed for users. Only scopes that have been passed will be enabled. If passed empty all the assigned scopes will be get disabled
  - **profilePhoto** (string) (e.g. `https://img.png`)
  - **twilioPhone** (object) (e.g. `{'C2QujeCh8ZnC7al2InWR': '+18832327657', 'M2QrtfVt8ZnC7cv2InDL': '+18832327657'}`): Per-location inbound Twilio number in E.164 format, keyed by location id (Call and Voicemail Inbound Number for direct Twilio, not LC Phone). Replacement semantics: if you send twilioPhone in the request body, the stored map is replaced entirely with this object (not merged). Any location id omitted from the object is removed from the saved map. Omit the twilioPhone property entirely to leave existing numbers unchanged. Send an empty object {} to clear all per-location numbers. To clear a single location only, set that location id to an empty string "".
  - **platformLanguage** (string) (e.g. `en_US`): Platform language preference for the user

### Response Codes

| Code | Description | Schema |
|------|-------------|--------|
| `201` | Successful response |   - **id** (string) (e.g. `0IHuJvc2ofPAAA8GzTRi`)<br>  - **name** (string) (e.g. `John Deo`)<br>  - **firstName** (string) (e.g. `John`)<br>  - **lastName**... |
| `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 /users/search

**Summary:** Search Users

Search Users

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

**Operation ID:** `search-users`

**Tags:** Search

### cURL

```bash
curl -X GET 'https://rest.gohighlevel.com/v1/users/search?companyId=5DP41231LkQsiKESj6rh&query=John&skip=1&limit=10&locationId=5DP41231LkQsiKESj6rh&type=agency&role=admin&ids=5DP4iH6HLkQsiKESj6rh,5DP4iH6HLkQsiKESj34h&sort=dateAdded&sortDirection=asc&enabled2waySync=VALUE' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Version: 2021-07-28' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'User-Agent: YourApp/1.0'
```

### Python (http.client)

```python
import http.client
import json

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

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

conn.request('GET', '/v1/users/search?companyId=5DP41231LkQsiKESj6rh&query=John&skip=1&limit=10&locationId=5DP41231LkQsiKESj6rh&type=agency&role=admin&ids=5DP4iH6HLkQsiKESj6rh,5DP4iH6HLkQsiKESj34h&sort=dateAdded&sortDirection=asc&enabled2waySync=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 search",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "GET",
    "url": "https://rest.gohighlevel.com/v1/users/search",
    "authentication": "genericCredentialType",
    "genericAuthType": "httpHeaderAuth",
    "sendHeaders": true,
    "headerParameters": {
      "parameters": [
        {
          "name": "Authorization",
          "value": "Bearer YOUR_API_TOKEN"
        },
        {
          "name": "Version",
          "value": "2021-07-28"
        },
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Accept",
          "value": "application/json"
        },
        {
          "name": "User-Agent",
          "value": "YourApp/1.0"
        }
      ]
    },
    "sendBody": false,
    "bodyParameters": {
      "parameters": []
    },
    "options": {},
    "sendQuery": true,
    "queryParameters": {
      "parameters": [
        {
          "name": "companyId",
          "value": "5DP41231LkQsiKESj6rh"
        },
        {
          "name": "query",
          "value": "John"
        },
        {
          "name": "skip",
          "value": "1"
        },
        {
          "name": "limit",
          "value": "10"
        },
        {
          "name": "locationId",
          "value": "5DP41231LkQsiKESj6rh"
        },
        {
          "name": "type",
          "value": "agency"
        },
        {
          "name": "role",
          "value": "admin"
        },
        {
          "name": "ids",
          "value": "5DP4iH6HLkQsiKESj6rh,5DP4iH6HLkQsiKESj34h"
        },
        {
          "name": "sort",
          "value": "dateAdded"
        },
        {
          "name": "sortDirection",
          "value": "asc"
        },
        {
          "name": "enabled2waySync",
          "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 |
|------|----------|------|----------|-------------|
| `companyId` | Query | `string` | ✅ | Company ID in which the search needs to be performed [example: `5DP41231LkQsiKESj6rh`] |
| `query` | Query | `string` | — | The search term for the user is matched based on the user full name, email or phone [example: `Jo... |
| `skip` | Query | `string` | — | No of results to be skipped before returning the result [example: `1`] |
| `limit` | Query | `string` | — | No of results to be limited before returning the result [example: `10`] |
| `locationId` | Query | `string` | — | Location ID in which the search needs to be performed [example: `5DP41231LkQsiKESj6rh`] |
| `type` | Query | `string` | — | Type of the users to be filtered in the search [example: `agency`] |
| `role` | Query | `string` | — | Role of the users to be filtered in the search [example: `admin`] |
| `ids` | Query | `string` | — | List of User IDs to be filtered in the search [example: `5DP4iH6HLkQsiKESj6rh,5DP4iH6HLkQsiKESj34h`] |
| `sort` | Query | `string` | — | The field on which sort is applied in which the results need to be sorted. Default is based on th... |
| `sortDirection` | Query | `string` | — | The direction in which the results need to be sorted [example: `asc`] |
| `enabled2waySync` | Query | `boolean` | — |  |

### Response Codes

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

### ⚠️ Special Notes & Quirks

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

---

## POST /users/search/filter-by-email

**Summary:** Filter Users by Email

Filter users by company ID, deleted status, and email array

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

**Operation ID:** `filter-users-by-email`

**Tags:** Search

### cURL

```bash
curl -X POST 'https://rest.gohighlevel.com/v1/users/search/filter-by-email' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Version: 2021-07-28' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'User-Agent: YourApp/1.0' \
  -d '{}'  # See request body schema below
```

### Python (http.client)

```python
import http.client
import json

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

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

payload = json.dumps({})
conn.request('POST', '/v1/users/search/filter-by-email', 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 filter-by-email",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "POST",
    "url": "https://rest.gohighlevel.com/v1/users/search/filter-by-email",
    "authentication": "genericCredentialType",
    "genericAuthType": "httpHeaderAuth",
    "sendHeaders": true,
    "headerParameters": {
      "parameters": [
        {
          "name": "Authorization",
          "value": "Bearer YOUR_API_TOKEN"
        },
        {
          "name": "Version",
          "value": "2021-07-28"
        },
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Accept",
          "value": "application/json"
        },
        {
          "name": "User-Agent",
          "value": "YourApp/1.0"
        }
      ]
    },
    "sendBody": true,
    "bodyParameters": {
      "parameters": []
    },
    "options": {}
  }
}
```

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

### Request Body Schema

  - **companyId** (string) (required) (e.g. `5DP41231LkQsiKESj6rh`): Company ID to filter users
  - **emails** (string) (required) (e.g. `user1@example.com,user2@example.com`): Comma-separated list of email addresses to filter users
  - **deleted** (boolean) (e.g. `False`): Filter deleted users
  - **skip** (string) (e.g. `1`): No of results to be skipped before returning the result
  - **limit** (string) (e.g. `10`): No of results to be limited before returning the result
  - **projection** (string) (e.g. `all`): Projection fields to return. Use "all" for all fields, or specify comma-separated field names. Default returns only id and email

### Response Codes

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

### ⚠️ Special Notes & Quirks

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

> 📌 **POST for Search:** Search endpoints use POST instead of GET because the search filters are complex JSON objects that can't be easily encoded in query parameters.

---

## DELETE /users/{userId}

**Summary:** Delete User

Delete User

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

**Operation ID:** `delete-user`

**Tags:** Users

### cURL

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

### Python (http.client)

```python
import http.client
import json

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

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

conn.request('DELETE', '/v1/users/{userId}', 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 {userId}",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "DELETE",
    "url": "https://rest.gohighlevel.com/v1/users/{userId}",
    "authentication": "genericCredentialType",
    "genericAuthType": "httpHeaderAuth",
    "sendHeaders": true,
    "headerParameters": {
      "parameters": [
        {
          "name": "Authorization",
          "value": "Bearer YOUR_API_TOKEN"
        },
        {
          "name": "Version",
          "value": "2021-07-28"
        },
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Accept",
          "value": "application/json"
        },
        {
          "name": "User-Agent",
          "value": "YourApp/1.0"
        }
      ]
    },
    "sendBody": false,
    "bodyParameters": {
      "parameters": []
    },
    "options": {}
  }
}
```

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

### Response Codes

| Code | Description | Schema |
|------|-------------|--------|
| `200` | Successful response |   - **succeded** (boolean) (e.g. `True`)<br>  - **message** (string) (e.g. `Queued deleting user with e-mail john@deo.com and name John Deo. Will take... |
| `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.

> ⚠️ **Async Delete:** User deletion is asynchronous. The API returns `202 Accepted` but the user may not be deleted immediately.

---

## GET /users/{userId}

**Summary:** Get User

Get User

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

**Operation ID:** `get-user`

**Tags:** Users

### cURL

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

### Python (http.client)

```python
import http.client
import json

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

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

conn.request('GET', '/v1/users/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 ve9EPM428h8vShlRW1KT",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "GET",
    "url": "https://rest.gohighlevel.com/v1/users/ve9EPM428h8vShlRW1KT",
    "authentication": "genericCredentialType",
    "genericAuthType": "httpHeaderAuth",
    "sendHeaders": true,
    "headerParameters": {
      "parameters": [
        {
          "name": "Authorization",
          "value": "Bearer YOUR_API_TOKEN"
        },
        {
          "name": "Version",
          "value": "2021-07-28"
        },
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Accept",
          "value": "application/json"
        },
        {
          "name": "User-Agent",
          "value": "YourApp/1.0"
        }
      ]
    },
    "sendBody": false,
    "bodyParameters": {
      "parameters": []
    },
    "options": {}
  }
}
```

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

### Request Parameters

| Name | Location | Type | Required | Description |
|------|----------|------|----------|-------------|
| `userId` | Path | `string` | ✅ | User Id [example: `ve9EPM428h8vShlRW1KT`] |

### Response Codes

| Code | Description | Schema |
|------|-------------|--------|
| `200` | Successful response |   - **id** (string) (e.g. `0IHuJvc2ofPAAA8GzTRi`)<br>  - **name** (string) (e.g. `John Deo`)<br>  - **firstName** (string) (e.g. `John`)<br>  - **lastName**... |
| `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.

---

## PUT /users/{userId}

**Summary:** Update User

Update User

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

**Operation ID:** `update-user`

**Tags:** Users

### cURL

```bash
curl -X PUT 'https://rest.gohighlevel.com/v1/users/{userId}' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Version: 2021-07-28' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'User-Agent: YourApp/1.0' \
  -d '{}'  # See request body schema below
```

### Python (http.client)

```python
import http.client
import json

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

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

payload = json.dumps({})
conn.request('PUT', '/v1/users/{userId}', 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 {userId}",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "PUT",
    "url": "https://rest.gohighlevel.com/v1/users/{userId}",
    "authentication": "genericCredentialType",
    "genericAuthType": "httpHeaderAuth",
    "sendHeaders": true,
    "headerParameters": {
      "parameters": [
        {
          "name": "Authorization",
          "value": "Bearer YOUR_API_TOKEN"
        },
        {
          "name": "Version",
          "value": "2021-07-28"
        },
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Accept",
          "value": "application/json"
        },
        {
          "name": "User-Agent",
          "value": "YourApp/1.0"
        }
      ]
    },
    "sendBody": true,
    "bodyParameters": {
      "parameters": []
    },
    "options": {}
  }
}
```

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

### Request Body Schema

  - **firstName** (string) (e.g. `John`)
  - **lastName** (string) (e.g. `Deo`)
  - **email** (string) (e.g. `john@deo.com`): Email update is no longer supported due to security reasons.
  - **password** (string) (e.g. `*******`)
  - **phone** (string) (e.g. `+18832327657`)
  - **type** (string) (e.g. `account`)
  - **role** (string) (e.g. `admin`)
  - **companyId** (string) (e.g. `UAXssdawIWAWD`): Company/Agency Id. Required for Agency Level access
  - **locationIds** (array) (e.g. `['C2QujeCh8ZnC7al2InWR']`)
  - **permissions** (PermissionsDto)
  - **scopes** (array) (e.g. `['contacts.write', 'campaigns.readonly']`): Scopes allowed for users. Only scopes that have been passed will be enabled. If passed empty all the scopes will be get disabled
  - **scopesAssignedToOnly** (array) (e.g. `['contacts.write', 'campaigns.readonly']`): Assigned Scopes allowed for users. Only scopes that have been passed will be enabled. If passed empty all the assigned scopes will be get disabled
  - **profilePhoto** (string) (e.g. `https://img.png`)
  - **twilioPhone** (object) (e.g. `{'C2QujeCh8ZnC7al2InWR': '+18832327657', 'M2QrtfVt8ZnC7cv2InDL': '+18832327657'}`): Per-location inbound Twilio number in E.164 format, keyed by location id (Call and Voicemail Inbound Number for direct Twilio, not LC Phone). Replacement semantics: if you send twilioPhone in the request body, the stored map is replaced entirely with this object (not merged). Any location id omitted from the object is removed from the saved map. Omit the twilioPhone property entirely to leave existing numbers unchanged. Send an empty object {} to clear all per-location numbers. To clear a single location only, set that location id to an empty string "".
  - **platformLanguage** (string) (e.g. `en_US`): Platform language preference for the user

### Response Codes

| Code | Description | Schema |
|------|-------------|--------|
| `200` | Successful response |   - **id** (string) (e.g. `0IHuJvc2ofPAAA8GzTRi`)<br>  - **name** (string) (e.g. `John Deo`)<br>  - **firstName** (string) (e.g. `John`)<br>  - **lastName**... |
| `400` | Bad Request | Standard error response for bad requests (400). Contains message, statusCode fields. |
| `401` | Unauthorized | Standard error response for unauthorized requests (401). Contains message, statusCode fields. |
| `422` | Unprocessable Entity | Standard error response for unprocessable entity (422). Contains message, statusCode, errors array fields. |

### ⚠️ Special Notes & Quirks

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

---


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