<!-- BusyBot node reference — https://busybot.net/tools/high-level/ -->

> Node: HighLevel (`high_level`) · Action · v1
> Category: Marketing · Credentials: HighLevel OAuth2 (`highLevelOAuth2`)
> Updated: 2026-08-16

# HighLevel

> Manage contacts, opportunities, tasks, and calendars in HighLevel CRM

## Overview

HighLevel (GoHighLevel) is an all-in-one CRM and marketing automation platform. This tool provides CRUD operations for contacts, opportunities (deals/pipelines), tasks, and calendar appointments via the HighLevel API v2. It uses OAuth2 authentication and automatically refreshes tokens on 401 errors. Contacts support upsert (create or update based on email/phone match). Opportunities track deals through pipeline stages. Tasks are associated with contacts. Calendar operations support booking appointments and checking free slots.

**Category:** Marketing  
**Tool Name:** `high_level`  
**Version:** 1

**Appearance:** Icon: `lucide-Megaphone` | Color: `#FF6D39`

## Node Type

**Action** — processes input items and produces output

## Input / Output

| Direction | Port(s) |
|-----------|--------|
| Input | `Input` |
| Output | `Output`, `Error` |

## Credentials

This tool requires **HighLevel OAuth2** credentials.
See the [Credentials Guide](https://busybot.net/credentials/high-level-oauth2/) for setup instructions.

### Resources

| Resource | Value |
|----------|-------|
| Calendar | `calendar` |
| Contact | `contact` |
| Opportunity | `opportunity` |
| Task | `task` |

### Operations

Each resource has its own Operation list, and three of them reuse the same operation values (`create`, `delete`, `get`, `getAll`, `update`). Pick the resource first, then the operation.

| Resource | Operation | Value | Description |
|----------|-----------|-------|-------------|
| Calendar | Book Appointment | `bookAppointment` | Book an appointment in a calendar |
| Calendar | Get Free Slots | `getFreeSlots` | List bookable slots in a date range |
| Contact | Create or Update | `create` | Create a contact, or update the existing one that matches the email or phone |
| Contact | Delete | `delete` | Delete a contact |
| Contact | Get | `get` | Get a contact |
| Contact | Get Many | `getAll` | Search and list contacts |
| Contact | Update | `update` | Update a contact by ID |
| Opportunity | Create | `create` | Create an opportunity in a pipeline |
| Opportunity | Delete | `delete` | Delete an opportunity |
| Opportunity | Get | `get` | Get an opportunity |
| Opportunity | Get Many | `getAll` | Search and list opportunities |
| Opportunity | Update | `update` | Update an opportunity |
| Task | Create | `create` | Create a task on a contact |
| Task | Delete | `delete` | Delete a task |
| Task | Get | `get` | Get a task |
| Task | Get Many | `getAll` | List a contact's tasks |
| Task | Update | `update` | Update a task |

### Parameters

Top-level fields accept expressions, so IDs and text can be driven from the incoming item. Values you put **inside** the Additional Fields, Update Fields, Filters and Options collections are sent exactly as typed — expressions there are not evaluated.

#### All Operations

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| HighLevel Account (`credentialId`) | `credential` | No | — | Connect your HighLevel account via OAuth2. |
| Max Concurrency | `number` | No | `10` | Maximum number of items to process concurrently (1–100). |

#### Calendar: Book Appointment

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Calendar ID | `string` | Yes | — | The calendar to book in. |
| Location ID | `string` | Yes | — | The HighLevel location ID. |
| Contact ID | `string` | Yes | — | The contact the appointment is for. |
| Start Time (`startTime`) | `string` | Yes | — | Appointment start time. Example: 2021-06-23T03:30:00+05:30. |
| Additional Fields (`additionalFields`) | `collection` | No | `{}` | Optional appointment properties. |
| — Address (`address`) | `string` | No | — | Where the appointment takes place. |
| — Appointment Status (`appointmentStatus`) | `options` | No | `new` | The status the appointment is created with. |
| | | | | Options: `cancelled`, `confirmed`, `invalid`, `new`, `noshow`, `showed` |
| — Assigned User ID (`assignedUserId`) | `string` | No | — | The user the appointment is assigned to. |
| — End Time (`endTime`) | `string` | No | — | Example: 2021-06-23T04:30:00+05:30. |
| — Ignore Date Range (`ignoreDateRange`) | `boolean` | No | `false` | Book outside the calendar's configured availability. |
| — Notify (`toNotify`) | `boolean` | No | `true` | Whether HighLevel sends its notifications for this booking. |
| — Title (`title`) | `string` | No | — | Title of the appointment. |

#### Calendar: Get Free Slots

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Calendar ID | `string` | Yes | — | The calendar to check. |
| Start Date (`startDate`) | `number` | Yes | — | Start date as epoch milliseconds. Example: 1548898600000. |
| End Date (`endDate`) | `number` | Yes | — | End date as epoch milliseconds. Example: 1601490599999. |
| Additional Fields (`additionalFields`) | `collection` | No | `{}` | Optional slot filters. |
| — Apply Look Busy (`enableLookBusy`) | `boolean` | No | `false` | Apply Look Busy to the slots. |
| — Timezone (`timezone`) | `string` | No | — | Timezone for returned slots. Example: America/Chihuahua. |
| — User ID (`userId`) | `string` | No | — | Filter by a single user. |
| — User IDs (`userIds`) | `collection` | No | `{}` | Filter by several users. |
| — — User IDs (`userIds`) | `string` | No | — | Comma-separated list of user IDs to filter the slots. |

#### Contact: Create or Update

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Email | `string` | No | — | Email or Phone are required to create/upsert contact. |
| Phone | `string` | No | — | Phone or Email are required to create contact. Must start with a valid country code with + sign. |
| Additional Fields (`additionalFields`) | `collection` | No | `{}` | Optional contact properties. |
| — Address (`address1`) | `string` | No | — | Street address. |
| — City (`city`) | `string` | No | — | City. |
| — Custom Fields (`customFields`) | `fixedCollection` | No | `{}` | Custom field values to set. Add as many as you need. |
| — — Field ID (`fieldId`) | `string` | Yes | — | The custom field ID. Find in HighLevel: Settings > Custom Fields. |
| — — Field Value (`fieldValue`) | `string` | No | — | The value to store in that field. |
| — Do Not Disturb (`dnd`) | `boolean` | No | `false` | Whether automated/manual outbound messages are permitted. True means NO outbound messages. |
| — First Name (`firstName`) | `string` | No | — | First name. |
| — Last Name (`lastName`) | `string` | No | — | Last name. |
| — Name (`name`) | `string` | No | — | Full name, will be overwritten by First Name and Last Name if set. |
| — Note (`notes`) | `string` | No | — | A note to add to the contact after creation. |
| — Postal Code (`postalCode`) | `string` | No | — | Postal or ZIP code. |
| — Source (`source`) | `string` | No | — | Where the contact came from, e.g. Public API. |
| — State (`state`) | `string` | No | — | State or region. |
| — Tags (`tags`) | `string` | No | — | Comma separated list of tags; an array of strings can be set in an expression. |
| — Timezone (`timezone`) | `string` | No | — | Timezone for the contact. Example: America/New_York. |
| — Website (`website`) | `string` | No | — | Website URL. |

#### Contact: Delete

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Contact ID | `string` | Yes | — | The contact to delete. |

#### Contact: Get

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Contact ID | `string` | Yes | — | The contact to retrieve. |

#### Contact: Get Many

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Return All | `boolean` | No | `false` | Whether to return all results or only up to a given limit. |
| Limit | `number` | No | `50` | Max number of results to return. _(shown when Return All is `false`)_ |
| Filters | `collection` | No | `{}` | Narrow the search. |
| — Query (`query`) | `string` | No | — | Search on Name, Phone, Email, Tags, and Company Name. |
| Options | `collection` | No | `{}` | Result ordering. |
| — Order (`order`) | `options` | No | `desc` | Sort direction. |
| | | | | Options: `asc`, `desc` |
| — Sort By (`sortBy`) | `options` | No | `date_added` | Field to sort on. |
| | | | | Options: `date_added`, `date_updated` |

#### Contact: Update

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Contact ID | `string` | Yes | — | The contact to update. |
| Update Fields | `collection` | No | `{}` | Fields to change. Only the fields you add are sent. |
| — Address (`address1`) | `string` | No | — | Street address. |
| — City (`city`) | `string` | No | — | City. |
| — Custom Fields (`customFields`) | `fixedCollection` | No | `{}` | Custom field values to set. Add as many as you need. |
| — — Field ID (`fieldId`) | `string` | Yes | — | The custom field ID. |
| — — Field Value (`fieldValue`) | `string` | No | — | The value to store in that field. |
| — Do Not Disturb (`dnd`) | `boolean` | No | `false` | True means no outbound messages. |
| — Email (`email`) | `string` | No | — | New email address. |
| — First Name (`firstName`) | `string` | No | — | First name. |
| — Last Name (`lastName`) | `string` | No | — | Last name. |
| — Name (`name`) | `string` | No | — | Full name, overwritten by First/Last Name if set. |
| — Phone (`phone`) | `string` | No | — | New phone number, with country code. |
| — Postal Code (`postalCode`) | `string` | No | — | Postal or ZIP code. |
| — State (`state`) | `string` | No | — | State or region. |
| — Tags (`tags`) | `string` | No | — | Comma separated list of tags. |
| — Timezone (`timezone`) | `string` | No | — | Timezone for the contact. |
| — Website (`website`) | `string` | No | — | Website URL. |

#### Opportunity: Create

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Pipeline ID | `string` | Yes | — | The pipeline ID. Find in HighLevel: Settings > Pipelines. |
| Contact ID | `string` | Yes | — | The contact ID to associate with this opportunity. One opportunity per contact. |
| Name | `string` | Yes | — | Name of the opportunity. |
| Status | `options` | Yes | `open` | The stage the deal is in. |
| | | | | Options: `open`, `won`, `lost`, `abandoned` |
| Additional Fields (`additionalFields`) | `collection` | No | `{}` | Optional opportunity properties. |
| — Assigned To (`assignedTo`) | `string` | No | — | User ID to assign. Find via HighLevel Users list. |
| — Company Name (`companyName`) | `string` | No | — | Company associated with the deal. |
| — Monetary Value (`monetaryValue`) | `number` | No | — | Monetary value of lead opportunity. |
| — Stage ID (`stageId`) | `string` | No | — | Pipeline stage ID. Depends on selected pipeline. |
| — Tags (`tags`) | `string` | No | — | Comma separated list of tags. |

#### Opportunity: Delete

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Opportunity ID | `string` | Yes | — | The opportunity to delete. |

#### Opportunity: Get

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Opportunity ID | `string` | Yes | — | The opportunity to retrieve. |

#### Opportunity: Get Many

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Return All | `boolean` | No | `false` | Whether to return all results or only up to a given limit. |
| Limit | `number` | No | `20` | Max number of results to return (1–100). _(shown when Return All is `false`)_ |
| Filters | `collection` | No | `{}` | Narrow the search. |
| — Assigned To (`assignedTo`) | `string` | No | — | User ID to filter by. |
| — Campaign ID (`campaignId`) | `string` | No | — | Filter by campaign. |
| — End Date (`endDate`) | `string` | No | — | Filter opportunities created before this date (ISO string). |
| — Pipeline ID (`pipelineId`) | `string` | No | — | Filter by pipeline. |
| — Query (`query`) | `string` | No | — | Search Name, Phone, Email, Tags, and Company Name. |
| — Stage ID (`stageId`) | `string` | No | — | Filter by pipeline stage. |
| — Start Date (`startDate`) | `string` | No | — | Filter opportunities created after this date (ISO string). |
| — Status (`status`) | `options` | No | `open` | Filter by deal status. |
| | | | | Options: `open`, `won`, `lost`, `abandoned` |

#### Opportunity: Update

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Opportunity ID | `string` | Yes | — | The opportunity to update. You cannot update an opportunity's pipeline ID. |
| Update Fields | `collection` | No | `{}` | Fields to change. Only the fields you add are sent. |
| — Assigned To (`assignedTo`) | `string` | No | — | User ID to assign. |
| — Monetary Value (`monetaryValue`) | `number` | No | — | Monetary value of the deal. |
| — Name (`name`) | `string` | No | — | New name for the opportunity. |
| — Pipeline ID (`pipelineId`) | `string` | No | — | Pipeline ID. |
| — Stage ID (`stageId`) | `string` | No | — | Pipeline stage ID. Select pipeline first. |
| — Status (`status`) | `options` | No | `open` | New deal status. |
| | | | | Options: `open`, `won`, `lost`, `abandoned` |

#### Task: Create

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Contact ID | `string` | Yes | — | The contact ID this task belongs to. |
| Title | `string` | Yes | — | Title of the task. |
| Due Date (`dueDate`) | `string` | Yes | — | ISO 8601 datetime string, e.g. 2024-01-15T10:00:00Z. |
| Completed | `boolean` | Yes | `false` | Whether the task starts out completed. |
| Additional Fields (`additionalFields`) | `collection` | No | `{}` | Optional task properties. |
| — Assigned To (`assignedTo`) | `string` | No | — | User ID to assign the task to. |
| — Body (`body`) | `string` | No | — | Task description/body text. |

#### Task: Delete

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Contact ID | `string` | Yes | — | The contact the task belongs to. |
| Task ID | `string` | Yes | — | The task to delete. |

#### Task: Get

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Contact ID | `string` | Yes | — | The contact ID this task belongs to. |
| Task ID | `string` | Yes | — | The task to retrieve. |

#### Task: Get Many

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Contact ID | `string` | Yes | — | The contact ID to list tasks for. |
| Return All | `boolean` | No | `false` | Whether to return all results or only up to a given limit. |
| Limit | `number` | No | `20` | Max number of results to return (1–100). _(shown when Return All is `false`)_ |

#### Task: Update

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Contact ID | `string` | Yes | — | The contact the task belongs to. |
| Task ID | `string` | Yes | — | The task to update. |
| Update Fields | `collection` | No | `{}` | Fields to change. Only the fields you add are sent. |
| — Assigned To (`assignedTo`) | `string` | No | — | User ID to assign the task to. |
| — Body (`body`) | `string` | No | — | Task description/body text. |
| — Completed (`completed`) | `boolean` | No | `false` | Whether the task is done. |
| — Due Date (`dueDate`) | `string` | No | — | ISO 8601 datetime. |
| — Title (`title`) | `string` | No | — | New title for the task. |

## Output Data

The HighLevel response is **merged onto the input item's JSON** at the top level — the fields the item already carried survive, and a response key with the same name overwrites the item's value, so downstream nodes read the record directly (`{{ $json.id }}`). Binary data on the input item is forwarded unchanged.

The number of output items follows the shape of the reply: **a list reply fans out to one output item per record**, and anything else produces exactly one output item.

| Operation | Output |
|-----------|--------|
| Contact Get Many, Opportunity Get Many, Task Get Many | **One output item per contact, opportunity or task.** A search that matches nothing produces **no output items at all**, so that branch of the workflow stops there. Task records also carry the `contactId` they were listed for. |
| Contact Create or Update, Contact Get, Contact Update, Opportunity Create, Opportunity Get, Opportunity Update, Task Create, Task Get, Task Update, Calendar Book Appointment | One output item carrying the record HighLevel returned. |
| Calendar Get Free Slots | One output item carrying the free-slots response for the date range. |
| Contact Delete, Opportunity Delete, Task Delete | One output item carrying `success: true` — these calls confirm the change instead of returning a record. |

## Usage Examples

- Create or update a contact in HighLevel by email
- Create an opportunity in a pipeline
- List all contacts matching a search query
- Book an appointment in a HighLevel calendar
- Update a task assigned to a contact

## Example Configuration

Upsert a contact from a form submission — an existing contact with the same email is updated rather than duplicated:

```json
{
  "type": "high_level",
  "parameters": {
    "resource": "contact",
    "operation": "create",
    "email": "{{ $json.email }}",
    "phone": "{{ $json.phone }}",
    "additionalFields": {
      "firstName": "Jane",
      "lastName": "Doe",
      "source": "Public API",
      "tags": "webinar,2026",
      "timezone": "America/New_York"
    }
  }
}
```

Search contacts, newest first:

```json
{
  "type": "high_level",
  "parameters": {
    "resource": "contact",
    "operation": "getAll",
    "returnAll": false,
    "limit": 50,
    "filters": {
      "query": "acme"
    },
    "options": {
      "order": "desc",
      "sortBy": "date_added"
    }
  }
}
```

Open a deal in a pipeline for the contact an upstream node just created:

```json
{
  "type": "high_level",
  "parameters": {
    "resource": "opportunity",
    "operation": "create",
    "pipelineId": "kFrZL2Wf6VOyRQlM5Xtg",
    "contactId": "{{ $json.id }}",
    "name": "Website enquiry",
    "status": "open",
    "additionalFields": {
      "monetaryValue": 2500,
      "stageId": "e93ba61a-4d4f-4f13-8a1a-11f4bbd0a2fd",
      "companyName": "Acme Ltd"
    }
  }
}
```

Mark a deal as won:

```json
{
  "type": "high_level",
  "parameters": {
    "resource": "opportunity",
    "operation": "update",
    "opportunityId": "{{ $json.id }}",
    "updateFields": {
      "status": "won",
      "monetaryValue": 3200
    }
  }
}
```

Add a follow-up task to a contact:

```json
{
  "type": "high_level",
  "parameters": {
    "resource": "task",
    "operation": "create",
    "contactId": "{{ $json.contactId }}",
    "title": "Follow up on quote",
    "dueDate": "2026-01-15T10:00:00Z",
    "completed": false,
    "additionalFields": {
      "body": "Call back after the trial ends"
    }
  }
}
```

Close a task:

```json
{
  "type": "high_level",
  "parameters": {
    "resource": "task",
    "operation": "update",
    "contactId": "{{ $json.contactId }}",
    "taskId": "{{ $json.taskId }}",
    "updateFields": {
      "completed": true
    }
  }
}
```

Check what a calendar has free in a date range:

```json
{
  "type": "high_level",
  "parameters": {
    "resource": "calendar",
    "operation": "getFreeSlots",
    "calendarId": "BqTwX8QFwXzpegMve9EQ",
    "startDate": 1548898600000,
    "endDate": 1601490599999,
    "additionalFields": {
      "timezone": "America/Chihuahua"
    }
  }
}
```

Book an appointment:

```json
{
  "type": "high_level",
  "parameters": {
    "resource": "calendar",
    "operation": "bookAppointment",
    "calendarId": "BqTwX8QFwXzpegMve9EQ",
    "locationId": "ve9EPM428h8vShlRW1KT",
    "contactId": "{{ $json.contactId }}",
    "startTime": "2026-06-23T03:30:00+05:30",
    "additionalFields": {
      "title": "Discovery call",
      "appointmentStatus": "confirmed",
      "toNotify": true
    }
  }
}
```

### Error Handling

| Mode | Behavior |
|------|----------|
| **stop** | Halts workflow on first error |
| **continue** | Skips failed items, passes successful ones through |
| **errorPort** | Routes failed items to Error output port |

## Tips

Manage contacts, opportunities, tasks, and calendar appointments in HighLevel (GoHighLevel) CRM.

- **Contact Create is really an upsert.** A contact whose email or phone already exists is updated instead of duplicated, so it is safe to run repeatedly over the same list. One of Email or Phone must be filled in.
- **Adding a Note costs a second call.** The Note field on contact creation is posted to the contact after it is created, so it only appears when the contact itself was created successfully.
- **Opportunities are one per contact.** Each opportunity is associated with a single contact, so plan the pipeline around one open deal per contact.
- **Pipeline stays put.** Opportunity Update cannot move a deal to a different pipeline, only to a different stage within it.
- **Tasks always need their contact.** Every task operation takes the Contact ID as well as the Task ID — a task ID on its own is not enough.
- **Free-slot dates are epoch milliseconds**, not ISO strings; appointment times are ISO strings with an offset. The two calendar operations do not use the same format.
- **Tokens refresh themselves.** An expired access token is refreshed automatically when a call comes back unauthorized, so long-running schedules keep working.