home / skills / openclaw / skills / hubspot

hubspot skill

/skills/kwall1/hubspot

This skill integrates with HubSpot CRM and CMS via REST API to manage contacts, companies, deals, and content efficiently.

npx playbooks add skill openclaw/skills --skill hubspot

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
8.0 KB
---
name: hubspot
description: HubSpot CRM and CMS API integration for contacts, companies, deals, owners, and content management.
metadata: {"clawdbot":{"secrets":["HUBSPOT_ACCESS_TOKEN"]}}
---

# HubSpot Skill

Interact with HubSpot CRM and CMS via the REST API.

## Setup

Set your HubSpot Private App access token:
```
HUBSPOT_ACCESS_TOKEN=pat-na2-xxxxx
```

## API Base

All endpoints use: `https://api.hubapi.com`

Authorization header: `Bearer $HUBSPOT_ACCESS_TOKEN`

---

## CRM Objects

### Contacts

**Create contact:**
```bash
curl -s -X POST -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"properties":{"email":"[email protected]","firstname":"Test","lastname":"User","phone":"555-1234","company":"Acme Inc","jobtitle":"Manager"}}' \
  "https://api.hubapi.com/crm/v3/objects/contacts" | jq
```

**List contacts:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/crm/v3/objects/contacts?limit=10" | jq
```

**Search contacts:**
```bash
curl -s -X POST -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"filterGroups":[{"filters":[{"propertyName":"email","operator":"CONTAINS_TOKEN","value":"example.com"}]}],"limit":10}' \
  "https://api.hubapi.com/crm/v3/objects/contacts/search" | jq
```

**Get contact by ID:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/crm/v3/objects/contacts/{contactId}?properties=email,firstname,lastname,phone,company" | jq
```

**Get contact by email:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/crm/v3/objects/contacts/{email}?idProperty=email" | jq
```

### Companies

**List companies:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/crm/v3/objects/companies?limit=10&properties=name,domain,industry" | jq
```

**Search companies:**
```bash
curl -s -X POST -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"filterGroups":[{"filters":[{"propertyName":"name","operator":"CONTAINS_TOKEN","value":"acme"}]}],"limit":10}' \
  "https://api.hubapi.com/crm/v3/objects/companies/search" | jq
```

**Get company by ID:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/crm/v3/objects/companies/{companyId}?properties=name,domain,industry,numberofemployees" | jq
```

### Deals

**Create deal:**
```bash
curl -s -X POST -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"properties":{"dealname":"New Deal","amount":"10000","closedate":"2026-06-01","description":"Deal notes here"}}' \
  "https://api.hubapi.com/crm/v3/objects/deals" | jq
```

**List deals:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/crm/v3/objects/deals?limit=10&properties=dealname,amount,dealstage,closedate" | jq
```

**Search deals:**
```bash
curl -s -X POST -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"filterGroups":[{"filters":[{"propertyName":"dealstage","operator":"EQ","value":"closedwon"}]}],"limit":10}' \
  "https://api.hubapi.com/crm/v3/objects/deals/search" | jq
```

**Get deal by ID:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/crm/v3/objects/deals/{dealId}?properties=dealname,amount,dealstage,closedate,pipeline" | jq
```

### Owners

**List owners (users):**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/crm/v3/owners" | jq
```

---

## Update & Assign Owner

**Update contact properties:**
```bash
curl -s -X PATCH -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"properties":{"phone":"555-9999","jobtitle":"Director"}}' \
  "https://api.hubapi.com/crm/v3/objects/contacts/{contactId}" | jq
```

**Assign owner to contact:**
```bash
curl -s -X PATCH -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"properties":{"hubspot_owner_id":"{ownerId}"}}' \
  "https://api.hubapi.com/crm/v3/objects/contacts/{contactId}" | jq
```

**Assign owner to deal:**
```bash
curl -s -X PATCH -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"properties":{"hubspot_owner_id":"{ownerId}"}}' \
  "https://api.hubapi.com/crm/v3/objects/deals/{dealId}" | jq
```

---

## Associations

**Get associated contacts for a company:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/crm/v4/objects/companies/{companyId}/associations/contacts" | jq
```

**Get associated deals for a contact:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/crm/v4/objects/contacts/{contactId}/associations/deals" | jq
```

**Create association (deal to contact):**
```bash
curl -s -X POST -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"inputs":[{"from":{"id":"{dealId}"},"to":{"id":"{contactId}"},"types":[{"associationCategory":"HUBSPOT_DEFINED","associationTypeId":3}]}]}' \
  "https://api.hubapi.com/crm/v4/associations/deals/contacts/batch/create" | jq
```

Common association type IDs:
- 3: Deal to Contact
- 5: Deal to Company
- 1: Contact to Company

---

## Properties (Schema)

**List contact properties:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/crm/v3/properties/contacts" | jq '.results[].name'
```

**List company properties:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/crm/v3/properties/companies" | jq '.results[].name'
```

**List deal properties:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/crm/v3/properties/deals" | jq '.results[].name'
```

---

## CMS

### Pages

**List site pages:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/cms/v3/pages/site-pages?limit=10" | jq
```

**List landing pages:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/cms/v3/pages/landing-pages?limit=10" | jq
```

### Domains

**List domains:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/cms/v3/domains" | jq
```

---

## Files

**List files:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/files/v3/files?limit=10" | jq
```

**Search files:**
```bash
curl -s -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" \
  "https://api.hubapi.com/files/v3/files/search?name=logo" | jq
```

---

## Search Operators

For search endpoints, use these operators in filters:

| Operator | Description |
|----------|-------------|
| `EQ` | Equal to |
| `NEQ` | Not equal to |
| `LT` | Less than |
| `LTE` | Less than or equal |
| `GT` | Greater than |
| `GTE` | Greater than or equal |
| `CONTAINS_TOKEN` | Contains word |
| `NOT_CONTAINS_TOKEN` | Does not contain word |
| `HAS_PROPERTY` | Has a value |
| `NOT_HAS_PROPERTY` | Does not have a value |

---

## PowerShell Examples

For Windows/PowerShell, use Invoke-RestMethod:

```powershell
$headers = @{ 
  "Authorization" = "Bearer $env:HUBSPOT_ACCESS_TOKEN"
  "Content-Type" = "application/json" 
}

# List contacts
Invoke-RestMethod -Uri "https://api.hubapi.com/crm/v3/objects/contacts?limit=10" -Headers $headers

# Search contacts
$body = @{
  filterGroups = @(@{
    filters = @(@{
      propertyName = "email"
      operator = "CONTAINS_TOKEN"
      value = "example.com"
    })
  })
  limit = 10
} | ConvertTo-Json -Depth 5

Invoke-RestMethod -Method POST -Uri "https://api.hubapi.com/crm/v3/objects/contacts/search" -Headers $headers -Body $body
```

---

## Notes

- Full CRUD operations supported with appropriate scopes
- Rate limits: 100 requests per 10 seconds for private apps
- Pagination: Use `after` parameter from `paging.next.after` for next page
- Portal ID is in the record URL: `https://app-na2.hubspot.com/contacts/{portalId}/record/...`

Overview

This skill integrates with the HubSpot CRM and CMS REST APIs to manage contacts, companies, deals, owners, associations, files, pages, and domains. It provides endpoints and examples for creating, searching, updating, and associating CRM objects, plus CMS and file operations. Use a HubSpot Private App access token for authentication and follow rate limits and pagination guidelines.

How this skill works

The skill issues HTTPS requests to https://api.hubapi.com using a Bearer token set in HUBSPOT_ACCESS_TOKEN. It maps common CRM and CMS workflows to API calls: create/list/search/get/update objects, assign owners, manage associations, list properties, and operate on CMS pages, domains, and files. Responses follow HubSpot pagination and error conventions; the skill demonstrates curl and PowerShell examples for each operation.

When to use it

  • Sync contacts, companies, or deals between systems and HubSpot.
  • Automate owner assignment and bulk updates for CRM records.
  • Search and filter CRM records programmatically using HubSpot search operators.
  • Back up or archive HubSpot CRM/CMS content and files.
  • Manage CMS pages, landing pages, and domains via API for deployment automation.
  • Inspect schema and properties before building integrations.

Best practices

  • Use a HubSpot Private App token with minimal required scopes and rotate tokens regularly.
  • Respect rate limits (100 requests per 10 seconds for private apps) and implement exponential backoff on 429 responses.
  • Use search endpoints with appropriate filters and limit parameters to reduce payload size.
  • Follow pagination: use paging.next.after from responses to fetch subsequent pages.
  • Validate property names against the properties API before writing updates to avoid schema errors.
  • Log API requests and responses for troubleshooting and auditing, redacting sensitive tokens.

Example use cases

  • Create new contacts from a signup form and assign the correct owner automatically.
  • Bulk update company records with industry and employee count from an external data source.
  • Search for deals in a specific stage (e.g., closedwon) and export them for reporting.
  • Associate newly created deals with contacts and companies in a single workflow.
  • List CMS site and landing pages for automated site audits or backups.
  • Search and download files (e.g., logos) for media asset management.

FAQ

What authentication does this skill require?

A HubSpot Private App access token provided in the HUBSPOT_ACCESS_TOKEN environment variable; include it as a Bearer token in the Authorization header.

How do I handle pagination?

Use the paging.next.after value from the API response and pass it as the after parameter on the next request to retrieve subsequent pages.

What search operators are supported?

Use HubSpot operators such as EQ, NEQ, LT, LTE, GT, GTE, CONTAINS_TOKEN, NOT_CONTAINS_TOKEN, HAS_PROPERTY, and NOT_HAS_PROPERTY in search filters.