chub-dev 0.1.0 → 0.1.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/bin/chub-mcp +2 -0
- package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
- package/dist/airtable/docs/database/python/DOC.md +1735 -0
- package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
- package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
- package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
- package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
- package/dist/asana/docs/tasks/DOC.md +1396 -0
- package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
- package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
- package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
- package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
- package/dist/auth0/docs/identity/python/DOC.md +1199 -0
- package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
- package/dist/aws/docs/s3/python/DOC.md +1807 -0
- package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
- package/dist/binance/docs/trading/python/DOC.md +1454 -0
- package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
- package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
- package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
- package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
- package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
- package/dist/clerk/docs/auth/python/DOC.md +274 -0
- package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
- package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
- package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
- package/dist/cohere/docs/llm/DOC.md +1335 -0
- package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
- package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
- package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
- package/dist/deepgram/docs/speech/python/DOC.md +685 -0
- package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
- package/dist/deepl/docs/translation/python/DOC.md +944 -0
- package/dist/deepseek/docs/llm/DOC.md +1220 -0
- package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
- package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
- package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
- package/dist/discord/docs/bot/python/DOC.md +1130 -0
- package/dist/elasticsearch/docs/search/DOC.md +1634 -0
- package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
- package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
- package/dist/firebase/docs/auth/DOC.md +1015 -0
- package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
- package/dist/gemini/docs/genai/python/DOC.md +555 -0
- package/dist/github/docs/octokit/DOC.md +1560 -0
- package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
- package/dist/google/docs/bigquery/python/DOC.md +1503 -0
- package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
- package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
- package/dist/huggingface/docs/transformers/DOC.md +948 -0
- package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
- package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
- package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
- package/dist/jira/docs/issues/python/DOC.md +1492 -0
- package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
- package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
- package/dist/landingai-ade/docs/api/DOC.md +620 -0
- package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
- package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
- package/dist/landingai-ade/skills/SKILL.md +489 -0
- package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
- package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
- package/dist/linear/docs/tracker/DOC.md +1554 -0
- package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
- package/dist/livekit/docs/realtime/python/DOC.md +163 -0
- package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
- package/dist/meilisearch/docs/search/DOC.md +1241 -0
- package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
- package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
- package/dist/mongodb/docs/atlas/DOC.md +2041 -0
- package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
- package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
- package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
- package/dist/okta/docs/identity/python/DOC.md +1401 -0
- package/dist/openai/docs/chat/javascript/DOC.md +407 -0
- package/dist/openai/docs/chat/python/DOC.md +568 -0
- package/dist/paypal/docs/checkout/DOC.md +278 -0
- package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
- package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
- package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
- package/dist/plaid/docs/banking/python/DOC.md +1203 -0
- package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
- package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
- package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
- package/dist/prisma/docs/orm/python/DOC.md +1317 -0
- package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
- package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
- package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
- package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
- package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
- package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
- package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
- package/dist/redis/docs/key-value/python/DOC.md +2054 -0
- package/dist/registry.json +2817 -0
- package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
- package/dist/resend/docs/email/DOC.md +1271 -0
- package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
- package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
- package/dist/search-index.json +1 -0
- package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
- package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
- package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
- package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
- package/dist/shopify/docs/storefront/DOC.md +457 -0
- package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
- package/dist/slack/docs/workspace/python/DOC.md +271 -0
- package/dist/square/docs/payments/javascript/DOC.md +1855 -0
- package/dist/square/docs/payments/python/DOC.md +1728 -0
- package/dist/stripe/docs/api/DOC.md +1727 -0
- package/dist/stripe/docs/payments/DOC.md +1726 -0
- package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
- package/dist/stytch/docs/auth/python/DOC.md +1962 -0
- package/dist/supabase/docs/client/DOC.md +1606 -0
- package/dist/twilio/docs/messaging/python/DOC.md +469 -0
- package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
- package/dist/vercel/docs/platform/DOC.md +1940 -0
- package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
- package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
- package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
- package/dist/zendesk/docs/support/python/DOC.md +2297 -0
- package/package.json +22 -6
- package/skills/get-api-docs/SKILL.md +84 -0
- package/src/commands/annotate.js +83 -0
- package/src/commands/build.js +12 -1
- package/src/commands/feedback.js +150 -0
- package/src/commands/get.js +83 -42
- package/src/commands/search.js +7 -0
- package/src/index.js +43 -17
- package/src/lib/analytics.js +90 -0
- package/src/lib/annotations.js +57 -0
- package/src/lib/bm25.js +170 -0
- package/src/lib/cache.js +69 -6
- package/src/lib/config.js +8 -3
- package/src/lib/identity.js +99 -0
- package/src/lib/registry.js +103 -20
- package/src/lib/telemetry.js +86 -0
- package/src/mcp/server.js +177 -0
- package/src/mcp/tools.js +251 -0
|
@@ -0,0 +1,1805 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crm
|
|
3
|
+
description: "HubSpot Node.js SDK for managing CRM contacts, companies, deals, and marketing automation via the HubSpot API."
|
|
4
|
+
metadata:
|
|
5
|
+
languages: "javascript"
|
|
6
|
+
versions: "13.4.0"
|
|
7
|
+
updated-on: "2026-03-01"
|
|
8
|
+
source: maintainer
|
|
9
|
+
tags: "hubspot,crm,marketing,contacts,automation"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# HubSpot JavaScript/Node.js SDK Coding Guidelines
|
|
13
|
+
|
|
14
|
+
You are a HubSpot API coding expert. Help me write code using the HubSpot API with the official Node.js SDK.
|
|
15
|
+
|
|
16
|
+
Official SDK documentation and code samples:
|
|
17
|
+
https://developers.hubspot.com/docs/api/overview
|
|
18
|
+
|
|
19
|
+
## Golden Rule: Use the Correct and Current SDK
|
|
20
|
+
|
|
21
|
+
Always use the official HubSpot Node.js SDK (`@hubspot/api-client`), which is the standard library for all HubSpot API interactions. Do not use deprecated or unofficial packages.
|
|
22
|
+
|
|
23
|
+
- **Library Name:** HubSpot Node.js SDK
|
|
24
|
+
- **NPM Package:** `@hubspot/api-client`
|
|
25
|
+
- **Current Version:** 13.4.0
|
|
26
|
+
- **Deprecated Packages:** `hubspot`, `hubspot-api`, `@hubspot/integrations-framework-actions` (do not use these)
|
|
27
|
+
|
|
28
|
+
**Installation:**
|
|
29
|
+
|
|
30
|
+
- **Correct:** `npm install @hubspot/api-client`
|
|
31
|
+
- **Incorrect:** `npm install hubspot` or `npm install hubspot-api`
|
|
32
|
+
|
|
33
|
+
**APIs and Usage:**
|
|
34
|
+
|
|
35
|
+
- **Correct:** `const hubspot = require('@hubspot/api-client')`
|
|
36
|
+
- **Correct:** `const hubspotClient = new hubspot.Client({ accessToken: token })`
|
|
37
|
+
- **Correct:** `await hubspotClient.crm.contacts.basicApi.create(...)`
|
|
38
|
+
- **Incorrect:** `HubspotClient` or `HubspotAPI`
|
|
39
|
+
- **Incorrect:** Legacy v2 API endpoints
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
Install the SDK via npm:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm install @hubspot/api-client
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
For TypeScript projects, the SDK includes built-in type definitions.
|
|
50
|
+
|
|
51
|
+
## Authentication
|
|
52
|
+
|
|
53
|
+
HubSpot API uses access tokens for authentication. There are three types of access tokens:
|
|
54
|
+
|
|
55
|
+
1. **Private App Access Tokens** (recommended for server-side integrations)
|
|
56
|
+
2. **OAuth Access Tokens** (for public apps and integrations)
|
|
57
|
+
3. **Legacy API Keys** (deprecated, will be revoked November 19, 2025)
|
|
58
|
+
|
|
59
|
+
### Environment Variable Configuration
|
|
60
|
+
|
|
61
|
+
Set your access token as an environment variable:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# .env file
|
|
65
|
+
HUBSPOT_ACCESS_TOKEN=your_access_token_here
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Creating a Private App:**
|
|
69
|
+
|
|
70
|
+
1. Navigate to Settings > Integrations > Private Apps in your HubSpot account
|
|
71
|
+
2. Click "Create private app"
|
|
72
|
+
3. Configure the required scopes (permissions)
|
|
73
|
+
4. Click "Create app" and copy the access token
|
|
74
|
+
|
|
75
|
+
## Initialization
|
|
76
|
+
|
|
77
|
+
### Basic Initialization
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
const hubspot = require('@hubspot/api-client');
|
|
81
|
+
|
|
82
|
+
// Initialize with access token from environment variable
|
|
83
|
+
const hubspotClient = new hubspot.Client({
|
|
84
|
+
accessToken: process.env.HUBSPOT_ACCESS_TOKEN
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Initialization with OAuth
|
|
89
|
+
|
|
90
|
+
```javascript
|
|
91
|
+
const hubspot = require('@hubspot/api-client');
|
|
92
|
+
|
|
93
|
+
const hubspotClient = new hubspot.Client({
|
|
94
|
+
accessToken: 'YOUR_OAUTH_ACCESS_TOKEN'
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Refresh token when needed
|
|
98
|
+
hubspotClient.setAccessToken('NEW_ACCESS_TOKEN');
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Initialization with Rate Limiting Options
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
const hubspot = require('@hubspot/api-client');
|
|
105
|
+
|
|
106
|
+
const hubspotClient = new hubspot.Client({
|
|
107
|
+
accessToken: process.env.HUBSPOT_ACCESS_TOKEN,
|
|
108
|
+
limiterOptions: {
|
|
109
|
+
maxConcurrent: 5,
|
|
110
|
+
minTime: 100
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## CRM API - Contacts
|
|
116
|
+
|
|
117
|
+
### Create a Contact
|
|
118
|
+
|
|
119
|
+
**Basic Example:**
|
|
120
|
+
|
|
121
|
+
```javascript
|
|
122
|
+
const hubspot = require('@hubspot/api-client');
|
|
123
|
+
const hubspotClient = new hubspot.Client({ accessToken: process.env.HUBSPOT_ACCESS_TOKEN });
|
|
124
|
+
|
|
125
|
+
async function createContact() {
|
|
126
|
+
const contactObj = {
|
|
127
|
+
properties: {
|
|
128
|
+
email: 'example@company.com',
|
|
129
|
+
firstname: 'John',
|
|
130
|
+
lastname: 'Doe',
|
|
131
|
+
phone: '555-0100',
|
|
132
|
+
company: 'Example Company',
|
|
133
|
+
website: 'example.com'
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
const apiResponse = await hubspotClient.crm.contacts.basicApi.create(contactObj);
|
|
139
|
+
console.log('Contact created:', apiResponse.id);
|
|
140
|
+
return apiResponse;
|
|
141
|
+
} catch (error) {
|
|
142
|
+
console.error('Error creating contact:', error.message);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
createContact();
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Advanced Example with Custom Properties:**
|
|
150
|
+
|
|
151
|
+
```javascript
|
|
152
|
+
async function createContactAdvanced() {
|
|
153
|
+
const contactObj = {
|
|
154
|
+
properties: {
|
|
155
|
+
email: 'jane@example.com',
|
|
156
|
+
firstname: 'Jane',
|
|
157
|
+
lastname: 'Smith',
|
|
158
|
+
phone: '555-0200',
|
|
159
|
+
company: 'Tech Corp',
|
|
160
|
+
jobtitle: 'Software Engineer',
|
|
161
|
+
lifecyclestage: 'lead',
|
|
162
|
+
hs_lead_status: 'NEW',
|
|
163
|
+
// Custom properties
|
|
164
|
+
custom_field: 'custom_value',
|
|
165
|
+
industry: 'Technology'
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
const apiResponse = await hubspotClient.crm.contacts.basicApi.create(contactObj);
|
|
171
|
+
console.log('Contact created with ID:', apiResponse.id);
|
|
172
|
+
console.log('Properties:', apiResponse.properties);
|
|
173
|
+
return apiResponse;
|
|
174
|
+
} catch (error) {
|
|
175
|
+
if (error.statusCode === 409) {
|
|
176
|
+
console.error('Contact with this email already exists');
|
|
177
|
+
} else {
|
|
178
|
+
console.error('Error creating contact:', error.message);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Get a Contact
|
|
185
|
+
|
|
186
|
+
**By ID:**
|
|
187
|
+
|
|
188
|
+
```javascript
|
|
189
|
+
async function getContact(contactId) {
|
|
190
|
+
try {
|
|
191
|
+
const apiResponse = await hubspotClient.crm.contacts.basicApi.getById(
|
|
192
|
+
contactId,
|
|
193
|
+
['email', 'firstname', 'lastname', 'phone', 'company'] // properties to return
|
|
194
|
+
);
|
|
195
|
+
console.log('Contact:', apiResponse.properties);
|
|
196
|
+
return apiResponse;
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.error('Error fetching contact:', error.message);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**By Email:**
|
|
204
|
+
|
|
205
|
+
```javascript
|
|
206
|
+
async function getContactByEmail(email) {
|
|
207
|
+
const filter = { propertyName: 'email', operator: 'EQ', value: email };
|
|
208
|
+
const filterGroup = { filters: [filter] };
|
|
209
|
+
const sort = JSON.stringify({ propertyName: 'createdate', direction: 'DESCENDING' });
|
|
210
|
+
const properties = ['email', 'firstname', 'lastname'];
|
|
211
|
+
const limit = 1;
|
|
212
|
+
|
|
213
|
+
try {
|
|
214
|
+
const apiResponse = await hubspotClient.crm.contacts.searchApi.doSearch({
|
|
215
|
+
filterGroups: [filterGroup],
|
|
216
|
+
sorts: [sort],
|
|
217
|
+
properties,
|
|
218
|
+
limit
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
if (apiResponse.total > 0) {
|
|
222
|
+
return apiResponse.results[0];
|
|
223
|
+
}
|
|
224
|
+
return null;
|
|
225
|
+
} catch (error) {
|
|
226
|
+
console.error('Error searching contact:', error.message);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Update a Contact
|
|
232
|
+
|
|
233
|
+
```javascript
|
|
234
|
+
async function updateContact(contactId) {
|
|
235
|
+
const properties = {
|
|
236
|
+
firstname: 'Updated Name',
|
|
237
|
+
phone: '555-9999',
|
|
238
|
+
lifecyclestage: 'opportunity'
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
try {
|
|
242
|
+
const apiResponse = await hubspotClient.crm.contacts.basicApi.update(
|
|
243
|
+
contactId,
|
|
244
|
+
{ properties }
|
|
245
|
+
);
|
|
246
|
+
console.log('Contact updated:', apiResponse.id);
|
|
247
|
+
return apiResponse;
|
|
248
|
+
} catch (error) {
|
|
249
|
+
console.error('Error updating contact:', error.message);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### List Contacts
|
|
255
|
+
|
|
256
|
+
**Basic Pagination:**
|
|
257
|
+
|
|
258
|
+
```javascript
|
|
259
|
+
async function listContacts() {
|
|
260
|
+
const limit = 10;
|
|
261
|
+
const properties = ['email', 'firstname', 'lastname', 'company'];
|
|
262
|
+
|
|
263
|
+
try {
|
|
264
|
+
const apiResponse = await hubspotClient.crm.contacts.basicApi.getPage(
|
|
265
|
+
limit,
|
|
266
|
+
undefined, // after (for pagination)
|
|
267
|
+
properties
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
console.log(`Found ${apiResponse.results.length} contacts`);
|
|
271
|
+
apiResponse.results.forEach(contact => {
|
|
272
|
+
console.log(`${contact.properties.firstname} ${contact.properties.lastname}`);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
return apiResponse;
|
|
276
|
+
} catch (error) {
|
|
277
|
+
console.error('Error listing contacts:', error.message);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**Get All Contacts (with pagination handling):**
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
async function getAllContacts() {
|
|
286
|
+
const allContacts = [];
|
|
287
|
+
let after = undefined;
|
|
288
|
+
const limit = 100;
|
|
289
|
+
|
|
290
|
+
try {
|
|
291
|
+
do {
|
|
292
|
+
const apiResponse = await hubspotClient.crm.contacts.basicApi.getPage(
|
|
293
|
+
limit,
|
|
294
|
+
after,
|
|
295
|
+
['email', 'firstname', 'lastname']
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
allContacts.push(...apiResponse.results);
|
|
299
|
+
after = apiResponse.paging?.next?.after;
|
|
300
|
+
|
|
301
|
+
} while (after);
|
|
302
|
+
|
|
303
|
+
console.log(`Total contacts retrieved: ${allContacts.length}`);
|
|
304
|
+
return allContacts;
|
|
305
|
+
} catch (error) {
|
|
306
|
+
console.error('Error getting all contacts:', error.message);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Delete a Contact
|
|
312
|
+
|
|
313
|
+
```javascript
|
|
314
|
+
async function deleteContact(contactId) {
|
|
315
|
+
try {
|
|
316
|
+
await hubspotClient.crm.contacts.basicApi.archive(contactId);
|
|
317
|
+
console.log('Contact deleted:', contactId);
|
|
318
|
+
} catch (error) {
|
|
319
|
+
console.error('Error deleting contact:', error.message);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## CRM API - Companies
|
|
325
|
+
|
|
326
|
+
### Create a Company
|
|
327
|
+
|
|
328
|
+
```javascript
|
|
329
|
+
async function createCompany() {
|
|
330
|
+
const companyObj = {
|
|
331
|
+
properties: {
|
|
332
|
+
name: 'Example Company',
|
|
333
|
+
domain: 'example.com',
|
|
334
|
+
city: 'San Francisco',
|
|
335
|
+
state: 'California',
|
|
336
|
+
industry: 'Technology',
|
|
337
|
+
phone: '555-0100',
|
|
338
|
+
numberofemployees: '50',
|
|
339
|
+
description: 'A technology company'
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
try {
|
|
344
|
+
const apiResponse = await hubspotClient.crm.companies.basicApi.create(companyObj);
|
|
345
|
+
console.log('Company created:', apiResponse.id);
|
|
346
|
+
return apiResponse;
|
|
347
|
+
} catch (error) {
|
|
348
|
+
console.error('Error creating company:', error.message);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Get a Company
|
|
354
|
+
|
|
355
|
+
```javascript
|
|
356
|
+
async function getCompany(companyId) {
|
|
357
|
+
const properties = ['name', 'domain', 'city', 'industry', 'phone'];
|
|
358
|
+
|
|
359
|
+
try {
|
|
360
|
+
const apiResponse = await hubspotClient.crm.companies.basicApi.getById(
|
|
361
|
+
companyId,
|
|
362
|
+
properties
|
|
363
|
+
);
|
|
364
|
+
console.log('Company:', apiResponse.properties);
|
|
365
|
+
return apiResponse;
|
|
366
|
+
} catch (error) {
|
|
367
|
+
console.error('Error fetching company:', error.message);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Update a Company
|
|
373
|
+
|
|
374
|
+
```javascript
|
|
375
|
+
async function updateCompany(companyId) {
|
|
376
|
+
const properties = {
|
|
377
|
+
name: 'Updated Company Name',
|
|
378
|
+
numberofemployees: '100',
|
|
379
|
+
annualrevenue: '1000000'
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
try {
|
|
383
|
+
const apiResponse = await hubspotClient.crm.companies.basicApi.update(
|
|
384
|
+
companyId,
|
|
385
|
+
{ properties }
|
|
386
|
+
);
|
|
387
|
+
console.log('Company updated:', apiResponse.id);
|
|
388
|
+
return apiResponse;
|
|
389
|
+
} catch (error) {
|
|
390
|
+
console.error('Error updating company:', error.message);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### List Companies
|
|
396
|
+
|
|
397
|
+
```javascript
|
|
398
|
+
async function listCompanies() {
|
|
399
|
+
const limit = 10;
|
|
400
|
+
const properties = ['name', 'domain', 'city', 'industry'];
|
|
401
|
+
|
|
402
|
+
try {
|
|
403
|
+
const apiResponse = await hubspotClient.crm.companies.basicApi.getPage(
|
|
404
|
+
limit,
|
|
405
|
+
undefined,
|
|
406
|
+
properties
|
|
407
|
+
);
|
|
408
|
+
|
|
409
|
+
console.log(`Found ${apiResponse.results.length} companies`);
|
|
410
|
+
return apiResponse;
|
|
411
|
+
} catch (error) {
|
|
412
|
+
console.error('Error listing companies:', error.message);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
## CRM API - Deals
|
|
418
|
+
|
|
419
|
+
### Create a Deal
|
|
420
|
+
|
|
421
|
+
```javascript
|
|
422
|
+
async function createDeal() {
|
|
423
|
+
const dealObj = {
|
|
424
|
+
properties: {
|
|
425
|
+
dealname: 'New Deal',
|
|
426
|
+
dealstage: 'appointmentscheduled',
|
|
427
|
+
amount: '10000',
|
|
428
|
+
closedate: '2025-12-31',
|
|
429
|
+
pipeline: 'default',
|
|
430
|
+
hubspot_owner_id: '12345'
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
try {
|
|
435
|
+
const apiResponse = await hubspotClient.crm.deals.basicApi.create(dealObj);
|
|
436
|
+
console.log('Deal created:', apiResponse.id);
|
|
437
|
+
return apiResponse;
|
|
438
|
+
} catch (error) {
|
|
439
|
+
console.error('Error creating deal:', error.message);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### Get a Deal
|
|
445
|
+
|
|
446
|
+
```javascript
|
|
447
|
+
async function getDeal(dealId) {
|
|
448
|
+
const properties = ['dealname', 'dealstage', 'amount', 'closedate'];
|
|
449
|
+
|
|
450
|
+
try {
|
|
451
|
+
const apiResponse = await hubspotClient.crm.deals.basicApi.getById(
|
|
452
|
+
dealId,
|
|
453
|
+
properties
|
|
454
|
+
);
|
|
455
|
+
console.log('Deal:', apiResponse.properties);
|
|
456
|
+
return apiResponse;
|
|
457
|
+
} catch (error) {
|
|
458
|
+
console.error('Error fetching deal:', error.message);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Update a Deal
|
|
464
|
+
|
|
465
|
+
```javascript
|
|
466
|
+
async function updateDeal(dealId) {
|
|
467
|
+
const properties = {
|
|
468
|
+
dealstage: 'closedwon',
|
|
469
|
+
amount: '15000',
|
|
470
|
+
closedate: '2025-11-30'
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
try {
|
|
474
|
+
const apiResponse = await hubspotClient.crm.deals.basicApi.update(
|
|
475
|
+
dealId,
|
|
476
|
+
{ properties }
|
|
477
|
+
);
|
|
478
|
+
console.log('Deal updated:', apiResponse.id);
|
|
479
|
+
return apiResponse;
|
|
480
|
+
} catch (error) {
|
|
481
|
+
console.error('Error updating deal:', error.message);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### List Deals
|
|
487
|
+
|
|
488
|
+
```javascript
|
|
489
|
+
async function listDeals() {
|
|
490
|
+
const limit = 10;
|
|
491
|
+
const properties = ['dealname', 'dealstage', 'amount'];
|
|
492
|
+
|
|
493
|
+
try {
|
|
494
|
+
const apiResponse = await hubspotClient.crm.deals.basicApi.getPage(
|
|
495
|
+
limit,
|
|
496
|
+
undefined,
|
|
497
|
+
properties
|
|
498
|
+
);
|
|
499
|
+
|
|
500
|
+
console.log(`Found ${apiResponse.results.length} deals`);
|
|
501
|
+
return apiResponse;
|
|
502
|
+
} catch (error) {
|
|
503
|
+
console.error('Error listing deals:', error.message);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
## CRM API - Tickets
|
|
509
|
+
|
|
510
|
+
### Create a Ticket
|
|
511
|
+
|
|
512
|
+
```javascript
|
|
513
|
+
async function createTicket() {
|
|
514
|
+
const ticketObj = {
|
|
515
|
+
properties: {
|
|
516
|
+
subject: 'Customer Support Request',
|
|
517
|
+
content: 'Customer needs help with product setup',
|
|
518
|
+
hs_pipeline: '0',
|
|
519
|
+
hs_pipeline_stage: '1',
|
|
520
|
+
hs_ticket_priority: 'HIGH',
|
|
521
|
+
hubspot_owner_id: '12345'
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
try {
|
|
526
|
+
const apiResponse = await hubspotClient.crm.tickets.basicApi.create(ticketObj);
|
|
527
|
+
console.log('Ticket created:', apiResponse.id);
|
|
528
|
+
return apiResponse;
|
|
529
|
+
} catch (error) {
|
|
530
|
+
console.error('Error creating ticket:', error.message);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
### Get a Ticket
|
|
536
|
+
|
|
537
|
+
```javascript
|
|
538
|
+
async function getTicket(ticketId) {
|
|
539
|
+
const properties = ['subject', 'content', 'hs_pipeline_stage', 'hs_ticket_priority'];
|
|
540
|
+
|
|
541
|
+
try {
|
|
542
|
+
const apiResponse = await hubspotClient.crm.tickets.basicApi.getById(
|
|
543
|
+
ticketId,
|
|
544
|
+
properties
|
|
545
|
+
);
|
|
546
|
+
console.log('Ticket:', apiResponse.properties);
|
|
547
|
+
return apiResponse;
|
|
548
|
+
} catch (error) {
|
|
549
|
+
console.error('Error fetching ticket:', error.message);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
### Update a Ticket
|
|
555
|
+
|
|
556
|
+
```javascript
|
|
557
|
+
async function updateTicket(ticketId) {
|
|
558
|
+
const properties = {
|
|
559
|
+
hs_pipeline_stage: '4', // Closed
|
|
560
|
+
hs_ticket_priority: 'LOW'
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
try {
|
|
564
|
+
const apiResponse = await hubspotClient.crm.tickets.basicApi.update(
|
|
565
|
+
ticketId,
|
|
566
|
+
{ properties }
|
|
567
|
+
);
|
|
568
|
+
console.log('Ticket updated:', apiResponse.id);
|
|
569
|
+
return apiResponse;
|
|
570
|
+
} catch (error) {
|
|
571
|
+
console.error('Error updating ticket:', error.message);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
## CRM API - Associations
|
|
577
|
+
|
|
578
|
+
Associations link objects together (e.g., contacts to companies, deals to contacts).
|
|
579
|
+
|
|
580
|
+
### Create Association
|
|
581
|
+
|
|
582
|
+
**Associate Contact with Company:**
|
|
583
|
+
|
|
584
|
+
```javascript
|
|
585
|
+
async function associateContactWithCompany(contactId, companyId) {
|
|
586
|
+
try {
|
|
587
|
+
const apiResponse = await hubspotClient.crm.contacts.associationsApi.create(
|
|
588
|
+
contactId,
|
|
589
|
+
'companies',
|
|
590
|
+
companyId,
|
|
591
|
+
'contact_to_company'
|
|
592
|
+
);
|
|
593
|
+
console.log('Association created');
|
|
594
|
+
return apiResponse;
|
|
595
|
+
} catch (error) {
|
|
596
|
+
console.error('Error creating association:', error.message);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
**Associate Deal with Contact:**
|
|
602
|
+
|
|
603
|
+
```javascript
|
|
604
|
+
async function associateDealWithContact(dealId, contactId) {
|
|
605
|
+
try {
|
|
606
|
+
const apiResponse = await hubspotClient.crm.deals.associationsApi.create(
|
|
607
|
+
dealId,
|
|
608
|
+
'contacts',
|
|
609
|
+
contactId,
|
|
610
|
+
'deal_to_contact'
|
|
611
|
+
);
|
|
612
|
+
console.log('Association created');
|
|
613
|
+
return apiResponse;
|
|
614
|
+
} catch (error) {
|
|
615
|
+
console.error('Error creating association:', error.message);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### Get Associations
|
|
621
|
+
|
|
622
|
+
```javascript
|
|
623
|
+
async function getContactAssociations(contactId) {
|
|
624
|
+
try {
|
|
625
|
+
const companies = await hubspotClient.crm.contacts.associationsApi.getAll(
|
|
626
|
+
contactId,
|
|
627
|
+
'companies'
|
|
628
|
+
);
|
|
629
|
+
|
|
630
|
+
const deals = await hubspotClient.crm.contacts.associationsApi.getAll(
|
|
631
|
+
contactId,
|
|
632
|
+
'deals'
|
|
633
|
+
);
|
|
634
|
+
|
|
635
|
+
console.log('Associated companies:', companies.results);
|
|
636
|
+
console.log('Associated deals:', deals.results);
|
|
637
|
+
|
|
638
|
+
return { companies, deals };
|
|
639
|
+
} catch (error) {
|
|
640
|
+
console.error('Error fetching associations:', error.message);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
### Remove Association
|
|
646
|
+
|
|
647
|
+
```javascript
|
|
648
|
+
async function removeAssociation(contactId, companyId) {
|
|
649
|
+
try {
|
|
650
|
+
await hubspotClient.crm.contacts.associationsApi.archive(
|
|
651
|
+
contactId,
|
|
652
|
+
'companies',
|
|
653
|
+
companyId,
|
|
654
|
+
'contact_to_company'
|
|
655
|
+
);
|
|
656
|
+
console.log('Association removed');
|
|
657
|
+
} catch (error) {
|
|
658
|
+
console.error('Error removing association:', error.message);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
## CRM API - Batch Operations
|
|
664
|
+
|
|
665
|
+
Batch operations allow you to create, update, or read up to 100 records in a single API call.
|
|
666
|
+
|
|
667
|
+
### Batch Create Contacts
|
|
668
|
+
|
|
669
|
+
```javascript
|
|
670
|
+
async function batchCreateContacts() {
|
|
671
|
+
const batchInputs = {
|
|
672
|
+
inputs: [
|
|
673
|
+
{
|
|
674
|
+
properties: {
|
|
675
|
+
email: 'contact1@example.com',
|
|
676
|
+
firstname: 'Contact',
|
|
677
|
+
lastname: 'One'
|
|
678
|
+
}
|
|
679
|
+
},
|
|
680
|
+
{
|
|
681
|
+
properties: {
|
|
682
|
+
email: 'contact2@example.com',
|
|
683
|
+
firstname: 'Contact',
|
|
684
|
+
lastname: 'Two'
|
|
685
|
+
}
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
properties: {
|
|
689
|
+
email: 'contact3@example.com',
|
|
690
|
+
firstname: 'Contact',
|
|
691
|
+
lastname: 'Three'
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
]
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
try {
|
|
698
|
+
const apiResponse = await hubspotClient.crm.contacts.batchApi.create(batchInputs);
|
|
699
|
+
console.log(`Created ${apiResponse.results.length} contacts`);
|
|
700
|
+
return apiResponse;
|
|
701
|
+
} catch (error) {
|
|
702
|
+
console.error('Error batch creating contacts:', error.message);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
### Batch Update Contacts
|
|
708
|
+
|
|
709
|
+
```javascript
|
|
710
|
+
async function batchUpdateContacts(contactIds) {
|
|
711
|
+
const batchInputs = {
|
|
712
|
+
inputs: contactIds.map(id => ({
|
|
713
|
+
id: id,
|
|
714
|
+
properties: {
|
|
715
|
+
lifecyclestage: 'customer',
|
|
716
|
+
hs_lead_status: 'CONNECTED'
|
|
717
|
+
}
|
|
718
|
+
}))
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
try {
|
|
722
|
+
const apiResponse = await hubspotClient.crm.contacts.batchApi.update(batchInputs);
|
|
723
|
+
console.log(`Updated ${apiResponse.results.length} contacts`);
|
|
724
|
+
return apiResponse;
|
|
725
|
+
} catch (error) {
|
|
726
|
+
console.error('Error batch updating contacts:', error.message);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
### Batch Read Contacts
|
|
732
|
+
|
|
733
|
+
```javascript
|
|
734
|
+
async function batchReadContacts(contactIds) {
|
|
735
|
+
const batchInputs = {
|
|
736
|
+
properties: ['email', 'firstname', 'lastname', 'phone'],
|
|
737
|
+
inputs: contactIds.map(id => ({ id }))
|
|
738
|
+
};
|
|
739
|
+
|
|
740
|
+
try {
|
|
741
|
+
const apiResponse = await hubspotClient.crm.contacts.batchApi.read(batchInputs);
|
|
742
|
+
console.log(`Retrieved ${apiResponse.results.length} contacts`);
|
|
743
|
+
return apiResponse;
|
|
744
|
+
} catch (error) {
|
|
745
|
+
console.error('Error batch reading contacts:', error.message);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
### Batch Upsert Contacts
|
|
751
|
+
|
|
752
|
+
```javascript
|
|
753
|
+
async function batchUpsertContacts() {
|
|
754
|
+
const batchInputs = {
|
|
755
|
+
inputs: [
|
|
756
|
+
{
|
|
757
|
+
properties: {
|
|
758
|
+
email: 'existing@example.com',
|
|
759
|
+
firstname: 'Updated',
|
|
760
|
+
lastname: 'Name'
|
|
761
|
+
},
|
|
762
|
+
idProperty: 'email'
|
|
763
|
+
},
|
|
764
|
+
{
|
|
765
|
+
properties: {
|
|
766
|
+
email: 'new@example.com',
|
|
767
|
+
firstname: 'New',
|
|
768
|
+
lastname: 'Contact'
|
|
769
|
+
},
|
|
770
|
+
idProperty: 'email'
|
|
771
|
+
}
|
|
772
|
+
]
|
|
773
|
+
};
|
|
774
|
+
|
|
775
|
+
try {
|
|
776
|
+
const apiResponse = await hubspotClient.crm.contacts.batchApi.upsert(batchInputs);
|
|
777
|
+
console.log(`Upserted ${apiResponse.results.length} contacts`);
|
|
778
|
+
return apiResponse;
|
|
779
|
+
} catch (error) {
|
|
780
|
+
console.error('Error batch upserting contacts:', error.message);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
## CRM API - Search
|
|
786
|
+
|
|
787
|
+
The Search API allows you to filter, sort, and search across CRM objects.
|
|
788
|
+
|
|
789
|
+
### Basic Search
|
|
790
|
+
|
|
791
|
+
```javascript
|
|
792
|
+
async function searchContacts() {
|
|
793
|
+
const filter = {
|
|
794
|
+
propertyName: 'lifecyclestage',
|
|
795
|
+
operator: 'EQ',
|
|
796
|
+
value: 'lead'
|
|
797
|
+
};
|
|
798
|
+
|
|
799
|
+
const filterGroup = {
|
|
800
|
+
filters: [filter]
|
|
801
|
+
};
|
|
802
|
+
|
|
803
|
+
const searchRequest = {
|
|
804
|
+
filterGroups: [filterGroup],
|
|
805
|
+
properties: ['email', 'firstname', 'lastname', 'lifecyclestage'],
|
|
806
|
+
limit: 10
|
|
807
|
+
};
|
|
808
|
+
|
|
809
|
+
try {
|
|
810
|
+
const apiResponse = await hubspotClient.crm.contacts.searchApi.doSearch(searchRequest);
|
|
811
|
+
console.log(`Found ${apiResponse.total} contacts`);
|
|
812
|
+
console.log(`Returned ${apiResponse.results.length} results`);
|
|
813
|
+
return apiResponse;
|
|
814
|
+
} catch (error) {
|
|
815
|
+
console.error('Error searching contacts:', error.message);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
```
|
|
819
|
+
|
|
820
|
+
### Advanced Search with Multiple Filters
|
|
821
|
+
|
|
822
|
+
```javascript
|
|
823
|
+
async function advancedSearchContacts() {
|
|
824
|
+
const searchRequest = {
|
|
825
|
+
filterGroups: [
|
|
826
|
+
{
|
|
827
|
+
filters: [
|
|
828
|
+
{
|
|
829
|
+
propertyName: 'lifecyclestage',
|
|
830
|
+
operator: 'EQ',
|
|
831
|
+
value: 'lead'
|
|
832
|
+
},
|
|
833
|
+
{
|
|
834
|
+
propertyName: 'createdate',
|
|
835
|
+
operator: 'GTE',
|
|
836
|
+
value: '2025-01-01'
|
|
837
|
+
}
|
|
838
|
+
]
|
|
839
|
+
}
|
|
840
|
+
],
|
|
841
|
+
sorts: [
|
|
842
|
+
{
|
|
843
|
+
propertyName: 'createdate',
|
|
844
|
+
direction: 'DESCENDING'
|
|
845
|
+
}
|
|
846
|
+
],
|
|
847
|
+
properties: ['email', 'firstname', 'lastname', 'createdate', 'lifecyclestage'],
|
|
848
|
+
limit: 100,
|
|
849
|
+
after: 0
|
|
850
|
+
};
|
|
851
|
+
|
|
852
|
+
try {
|
|
853
|
+
const apiResponse = await hubspotClient.crm.contacts.searchApi.doSearch(searchRequest);
|
|
854
|
+
console.log(`Found ${apiResponse.total} matching contacts`);
|
|
855
|
+
return apiResponse;
|
|
856
|
+
} catch (error) {
|
|
857
|
+
console.error('Error searching contacts:', error.message);
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
### Search with Association Filters
|
|
863
|
+
|
|
864
|
+
```javascript
|
|
865
|
+
async function searchContactsByCompany(companyId) {
|
|
866
|
+
const searchRequest = {
|
|
867
|
+
filterGroups: [
|
|
868
|
+
{
|
|
869
|
+
filters: [
|
|
870
|
+
{
|
|
871
|
+
propertyName: 'associations.company',
|
|
872
|
+
operator: 'EQ',
|
|
873
|
+
value: companyId
|
|
874
|
+
}
|
|
875
|
+
]
|
|
876
|
+
}
|
|
877
|
+
],
|
|
878
|
+
properties: ['email', 'firstname', 'lastname'],
|
|
879
|
+
limit: 100
|
|
880
|
+
};
|
|
881
|
+
|
|
882
|
+
try {
|
|
883
|
+
const apiResponse = await hubspotClient.crm.contacts.searchApi.doSearch(searchRequest);
|
|
884
|
+
console.log(`Found ${apiResponse.results.length} contacts for company`);
|
|
885
|
+
return apiResponse;
|
|
886
|
+
} catch (error) {
|
|
887
|
+
console.error('Error searching contacts by company:', error.message);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
### Search Operators
|
|
893
|
+
|
|
894
|
+
Available operators for search filters:
|
|
895
|
+
|
|
896
|
+
- `EQ` - Equal to
|
|
897
|
+
- `NEQ` - Not equal to
|
|
898
|
+
- `LT` - Less than
|
|
899
|
+
- `LTE` - Less than or equal to
|
|
900
|
+
- `GT` - Greater than
|
|
901
|
+
- `GTE` - Greater than or equal to
|
|
902
|
+
- `IN` - In list of values
|
|
903
|
+
- `NOT_IN` - Not in list of values
|
|
904
|
+
- `HAS_PROPERTY` - Has property value set
|
|
905
|
+
- `NOT_HAS_PROPERTY` - Does not have property value set
|
|
906
|
+
- `CONTAINS_TOKEN` - Contains token (for text)
|
|
907
|
+
- `NOT_CONTAINS_TOKEN` - Does not contain token
|
|
908
|
+
|
|
909
|
+
## CRM API - Properties
|
|
910
|
+
|
|
911
|
+
### Get All Contact Properties
|
|
912
|
+
|
|
913
|
+
```javascript
|
|
914
|
+
async function getAllContactProperties() {
|
|
915
|
+
try {
|
|
916
|
+
const apiResponse = await hubspotClient.crm.properties.coreApi.getAll('contacts');
|
|
917
|
+
console.log(`Found ${apiResponse.results.length} contact properties`);
|
|
918
|
+
return apiResponse;
|
|
919
|
+
} catch (error) {
|
|
920
|
+
console.error('Error fetching contact properties:', error.message);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
```
|
|
924
|
+
|
|
925
|
+
### Create Custom Property
|
|
926
|
+
|
|
927
|
+
```javascript
|
|
928
|
+
async function createCustomProperty() {
|
|
929
|
+
const propertyObj = {
|
|
930
|
+
name: 'favorite_color',
|
|
931
|
+
label: 'Favorite Color',
|
|
932
|
+
type: 'string',
|
|
933
|
+
fieldType: 'text',
|
|
934
|
+
groupName: 'contactinformation',
|
|
935
|
+
description: 'The contact\'s favorite color',
|
|
936
|
+
options: []
|
|
937
|
+
};
|
|
938
|
+
|
|
939
|
+
try {
|
|
940
|
+
const apiResponse = await hubspotClient.crm.properties.coreApi.create(
|
|
941
|
+
'contacts',
|
|
942
|
+
propertyObj
|
|
943
|
+
);
|
|
944
|
+
console.log('Custom property created:', apiResponse.name);
|
|
945
|
+
return apiResponse;
|
|
946
|
+
} catch (error) {
|
|
947
|
+
console.error('Error creating custom property:', error.message);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
### Create Dropdown Property
|
|
953
|
+
|
|
954
|
+
```javascript
|
|
955
|
+
async function createDropdownProperty() {
|
|
956
|
+
const propertyObj = {
|
|
957
|
+
name: 'customer_tier',
|
|
958
|
+
label: 'Customer Tier',
|
|
959
|
+
type: 'enumeration',
|
|
960
|
+
fieldType: 'select',
|
|
961
|
+
groupName: 'contactinformation',
|
|
962
|
+
options: [
|
|
963
|
+
{ label: 'Bronze', value: 'bronze', displayOrder: 0 },
|
|
964
|
+
{ label: 'Silver', value: 'silver', displayOrder: 1 },
|
|
965
|
+
{ label: 'Gold', value: 'gold', displayOrder: 2 },
|
|
966
|
+
{ label: 'Platinum', value: 'platinum', displayOrder: 3 }
|
|
967
|
+
]
|
|
968
|
+
};
|
|
969
|
+
|
|
970
|
+
try {
|
|
971
|
+
const apiResponse = await hubspotClient.crm.properties.coreApi.create(
|
|
972
|
+
'contacts',
|
|
973
|
+
propertyObj
|
|
974
|
+
);
|
|
975
|
+
console.log('Dropdown property created:', apiResponse.name);
|
|
976
|
+
return apiResponse;
|
|
977
|
+
} catch (error) {
|
|
978
|
+
console.error('Error creating dropdown property:', error.message);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
```
|
|
982
|
+
|
|
983
|
+
### Update Property
|
|
984
|
+
|
|
985
|
+
```javascript
|
|
986
|
+
async function updateProperty(propertyName) {
|
|
987
|
+
const propertyUpdate = {
|
|
988
|
+
label: 'Updated Label',
|
|
989
|
+
description: 'Updated description'
|
|
990
|
+
};
|
|
991
|
+
|
|
992
|
+
try {
|
|
993
|
+
const apiResponse = await hubspotClient.crm.properties.coreApi.update(
|
|
994
|
+
'contacts',
|
|
995
|
+
propertyName,
|
|
996
|
+
propertyUpdate
|
|
997
|
+
);
|
|
998
|
+
console.log('Property updated:', apiResponse.name);
|
|
999
|
+
return apiResponse;
|
|
1000
|
+
} catch (error) {
|
|
1001
|
+
console.error('Error updating property:', error.message);
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
```
|
|
1005
|
+
|
|
1006
|
+
## Marketing API - Emails
|
|
1007
|
+
|
|
1008
|
+
### Get All Marketing Emails
|
|
1009
|
+
|
|
1010
|
+
```javascript
|
|
1011
|
+
async function getMarketingEmails() {
|
|
1012
|
+
try {
|
|
1013
|
+
const apiResponse = await hubspotClient.marketing.emails.emailsApi.getPage();
|
|
1014
|
+
console.log(`Found ${apiResponse.results.length} marketing emails`);
|
|
1015
|
+
return apiResponse;
|
|
1016
|
+
} catch (error) {
|
|
1017
|
+
console.error('Error fetching marketing emails:', error.message);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
### Get Email by ID
|
|
1023
|
+
|
|
1024
|
+
```javascript
|
|
1025
|
+
async function getMarketingEmail(emailId) {
|
|
1026
|
+
try {
|
|
1027
|
+
const apiResponse = await hubspotClient.marketing.emails.emailsApi.getById(emailId);
|
|
1028
|
+
console.log('Email:', apiResponse.name);
|
|
1029
|
+
return apiResponse;
|
|
1030
|
+
} catch (error) {
|
|
1031
|
+
console.error('Error fetching marketing email:', error.message);
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
```
|
|
1035
|
+
|
|
1036
|
+
## Marketing API - Forms
|
|
1037
|
+
|
|
1038
|
+
### Get All Forms
|
|
1039
|
+
|
|
1040
|
+
```javascript
|
|
1041
|
+
async function getAllForms() {
|
|
1042
|
+
try {
|
|
1043
|
+
const apiResponse = await hubspotClient.marketing.forms.formsApi.getPage();
|
|
1044
|
+
console.log(`Found ${apiResponse.results.length} forms`);
|
|
1045
|
+
return apiResponse;
|
|
1046
|
+
} catch (error) {
|
|
1047
|
+
console.error('Error fetching forms:', error.message);
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
```
|
|
1051
|
+
|
|
1052
|
+
### Get Form by ID
|
|
1053
|
+
|
|
1054
|
+
```javascript
|
|
1055
|
+
async function getForm(formId) {
|
|
1056
|
+
try {
|
|
1057
|
+
const apiResponse = await hubspotClient.marketing.forms.formsApi.getById(formId);
|
|
1058
|
+
console.log('Form:', apiResponse.name);
|
|
1059
|
+
return apiResponse;
|
|
1060
|
+
} catch (error) {
|
|
1061
|
+
console.error('Error fetching form:', error.message);
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
```
|
|
1065
|
+
|
|
1066
|
+
### Submit Form Data
|
|
1067
|
+
|
|
1068
|
+
```javascript
|
|
1069
|
+
async function submitFormData(formGuid, portalId) {
|
|
1070
|
+
const formData = {
|
|
1071
|
+
fields: [
|
|
1072
|
+
{
|
|
1073
|
+
name: 'email',
|
|
1074
|
+
value: 'test@example.com'
|
|
1075
|
+
},
|
|
1076
|
+
{
|
|
1077
|
+
name: 'firstname',
|
|
1078
|
+
value: 'John'
|
|
1079
|
+
},
|
|
1080
|
+
{
|
|
1081
|
+
name: 'lastname',
|
|
1082
|
+
value: 'Doe'
|
|
1083
|
+
}
|
|
1084
|
+
],
|
|
1085
|
+
context: {
|
|
1086
|
+
pageUri: 'https://example.com/contact',
|
|
1087
|
+
pageName: 'Contact Us'
|
|
1088
|
+
}
|
|
1089
|
+
};
|
|
1090
|
+
|
|
1091
|
+
try {
|
|
1092
|
+
const axios = require('axios');
|
|
1093
|
+
const response = await axios.post(
|
|
1094
|
+
`https://api.hsforms.com/submissions/v3/integration/submit/${portalId}/${formGuid}`,
|
|
1095
|
+
formData
|
|
1096
|
+
);
|
|
1097
|
+
console.log('Form submitted successfully');
|
|
1098
|
+
return response.data;
|
|
1099
|
+
} catch (error) {
|
|
1100
|
+
console.error('Error submitting form:', error.message);
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
```
|
|
1104
|
+
|
|
1105
|
+
## Events API - Timeline Events
|
|
1106
|
+
|
|
1107
|
+
### Create Timeline Event Type
|
|
1108
|
+
|
|
1109
|
+
```javascript
|
|
1110
|
+
async function createTimelineEventType() {
|
|
1111
|
+
const eventTypeObj = {
|
|
1112
|
+
name: 'Custom Event',
|
|
1113
|
+
applicationId: 12345, // Your app ID
|
|
1114
|
+
objectType: 'CONTACT',
|
|
1115
|
+
headerTemplate: '{{eventTitle}}',
|
|
1116
|
+
detailTemplate: '{{eventDescription}}'
|
|
1117
|
+
};
|
|
1118
|
+
|
|
1119
|
+
try {
|
|
1120
|
+
const apiResponse = await hubspotClient.crm.timeline.eventsApi.createEventType(
|
|
1121
|
+
eventTypeObj
|
|
1122
|
+
);
|
|
1123
|
+
console.log('Timeline event type created:', apiResponse.id);
|
|
1124
|
+
return apiResponse;
|
|
1125
|
+
} catch (error) {
|
|
1126
|
+
console.error('Error creating timeline event type:', error.message);
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
```
|
|
1130
|
+
|
|
1131
|
+
### Create Timeline Event
|
|
1132
|
+
|
|
1133
|
+
```javascript
|
|
1134
|
+
async function createTimelineEvent(eventTypeId, objectId) {
|
|
1135
|
+
const eventData = {
|
|
1136
|
+
eventTypeId: eventTypeId,
|
|
1137
|
+
objectId: objectId,
|
|
1138
|
+
extraData: {
|
|
1139
|
+
eventTitle: 'Purchase Completed',
|
|
1140
|
+
eventDescription: 'Customer completed a purchase of $99.99'
|
|
1141
|
+
},
|
|
1142
|
+
timestamp: new Date().toISOString()
|
|
1143
|
+
};
|
|
1144
|
+
|
|
1145
|
+
try {
|
|
1146
|
+
const apiResponse = await hubspotClient.crm.timeline.eventsApi.create(eventData);
|
|
1147
|
+
console.log('Timeline event created:', apiResponse.id);
|
|
1148
|
+
return apiResponse;
|
|
1149
|
+
} catch (error) {
|
|
1150
|
+
console.error('Error creating timeline event:', error.message);
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
```
|
|
1154
|
+
|
|
1155
|
+
## Automation API - Workflows
|
|
1156
|
+
|
|
1157
|
+
### Get All Workflows
|
|
1158
|
+
|
|
1159
|
+
```javascript
|
|
1160
|
+
async function getAllWorkflows() {
|
|
1161
|
+
try {
|
|
1162
|
+
const axios = require('axios');
|
|
1163
|
+
const response = await axios.get(
|
|
1164
|
+
'https://api.hubapi.com/automation/v3/workflows',
|
|
1165
|
+
{
|
|
1166
|
+
headers: {
|
|
1167
|
+
Authorization: `Bearer ${process.env.HUBSPOT_ACCESS_TOKEN}`
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
);
|
|
1171
|
+
console.log(`Found ${response.data.workflows.length} workflows`);
|
|
1172
|
+
return response.data;
|
|
1173
|
+
} catch (error) {
|
|
1174
|
+
console.error('Error fetching workflows:', error.message);
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
```
|
|
1178
|
+
|
|
1179
|
+
### Get Workflow by ID
|
|
1180
|
+
|
|
1181
|
+
```javascript
|
|
1182
|
+
async function getWorkflow(workflowId) {
|
|
1183
|
+
try {
|
|
1184
|
+
const axios = require('axios');
|
|
1185
|
+
const response = await axios.get(
|
|
1186
|
+
`https://api.hubapi.com/automation/v3/workflows/${workflowId}`,
|
|
1187
|
+
{
|
|
1188
|
+
headers: {
|
|
1189
|
+
Authorization: `Bearer ${process.env.HUBSPOT_ACCESS_TOKEN}`
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
);
|
|
1193
|
+
console.log('Workflow:', response.data.name);
|
|
1194
|
+
return response.data;
|
|
1195
|
+
} catch (error) {
|
|
1196
|
+
console.error('Error fetching workflow:', error.message);
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
```
|
|
1200
|
+
|
|
1201
|
+
### Enroll Contact in Workflow
|
|
1202
|
+
|
|
1203
|
+
```javascript
|
|
1204
|
+
async function enrollContactInWorkflow(workflowId, contactEmail) {
|
|
1205
|
+
try {
|
|
1206
|
+
const axios = require('axios');
|
|
1207
|
+
const response = await axios.post(
|
|
1208
|
+
`https://api.hubapi.com/automation/v2/workflows/${workflowId}/enrollments/contacts/${contactEmail}`,
|
|
1209
|
+
{},
|
|
1210
|
+
{
|
|
1211
|
+
headers: {
|
|
1212
|
+
Authorization: `Bearer ${process.env.HUBSPOT_ACCESS_TOKEN}`,
|
|
1213
|
+
'Content-Type': 'application/json'
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
);
|
|
1217
|
+
console.log('Contact enrolled in workflow');
|
|
1218
|
+
return response.data;
|
|
1219
|
+
} catch (error) {
|
|
1220
|
+
console.error('Error enrolling contact in workflow:', error.message);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
```
|
|
1224
|
+
|
|
1225
|
+
## Webhooks API
|
|
1226
|
+
|
|
1227
|
+
### Create Webhook Subscription
|
|
1228
|
+
|
|
1229
|
+
```javascript
|
|
1230
|
+
async function createWebhookSubscription() {
|
|
1231
|
+
const subscriptionObj = {
|
|
1232
|
+
eventType: 'contact.creation',
|
|
1233
|
+
propertyName: undefined,
|
|
1234
|
+
active: true
|
|
1235
|
+
};
|
|
1236
|
+
|
|
1237
|
+
try {
|
|
1238
|
+
const apiResponse = await hubspotClient.webhooks.subscriptionsApi.create(
|
|
1239
|
+
12345, // Your app ID
|
|
1240
|
+
subscriptionObj
|
|
1241
|
+
);
|
|
1242
|
+
console.log('Webhook subscription created:', apiResponse.id);
|
|
1243
|
+
return apiResponse;
|
|
1244
|
+
} catch (error) {
|
|
1245
|
+
console.error('Error creating webhook subscription:', error.message);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
```
|
|
1249
|
+
|
|
1250
|
+
### Get All Webhook Subscriptions
|
|
1251
|
+
|
|
1252
|
+
```javascript
|
|
1253
|
+
async function getWebhookSubscriptions(appId) {
|
|
1254
|
+
try {
|
|
1255
|
+
const apiResponse = await hubspotClient.webhooks.subscriptionsApi.getAll(appId);
|
|
1256
|
+
console.log(`Found ${apiResponse.results.length} webhook subscriptions`);
|
|
1257
|
+
return apiResponse;
|
|
1258
|
+
} catch (error) {
|
|
1259
|
+
console.error('Error fetching webhook subscriptions:', error.message);
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
```
|
|
1263
|
+
|
|
1264
|
+
### Delete Webhook Subscription
|
|
1265
|
+
|
|
1266
|
+
```javascript
|
|
1267
|
+
async function deleteWebhookSubscription(appId, subscriptionId) {
|
|
1268
|
+
try {
|
|
1269
|
+
await hubspotClient.webhooks.subscriptionsApi.archive(appId, subscriptionId);
|
|
1270
|
+
console.log('Webhook subscription deleted');
|
|
1271
|
+
} catch (error) {
|
|
1272
|
+
console.error('Error deleting webhook subscription:', error.message);
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
```
|
|
1276
|
+
|
|
1277
|
+
## Lists API
|
|
1278
|
+
|
|
1279
|
+
### Get All Lists
|
|
1280
|
+
|
|
1281
|
+
```javascript
|
|
1282
|
+
async function getAllLists() {
|
|
1283
|
+
try {
|
|
1284
|
+
const axios = require('axios');
|
|
1285
|
+
const response = await axios.get(
|
|
1286
|
+
'https://api.hubapi.com/contacts/v1/lists',
|
|
1287
|
+
{
|
|
1288
|
+
headers: {
|
|
1289
|
+
Authorization: `Bearer ${process.env.HUBSPOT_ACCESS_TOKEN}`
|
|
1290
|
+
},
|
|
1291
|
+
params: {
|
|
1292
|
+
count: 100,
|
|
1293
|
+
offset: 0
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
);
|
|
1297
|
+
console.log(`Found ${response.data.lists.length} lists`);
|
|
1298
|
+
return response.data;
|
|
1299
|
+
} catch (error) {
|
|
1300
|
+
console.error('Error fetching lists:', error.message);
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
```
|
|
1304
|
+
|
|
1305
|
+
### Add Contact to List
|
|
1306
|
+
|
|
1307
|
+
```javascript
|
|
1308
|
+
async function addContactToList(listId, contactId) {
|
|
1309
|
+
try {
|
|
1310
|
+
const axios = require('axios');
|
|
1311
|
+
const response = await axios.post(
|
|
1312
|
+
`https://api.hubapi.com/contacts/v1/lists/${listId}/add`,
|
|
1313
|
+
{
|
|
1314
|
+
vids: [contactId]
|
|
1315
|
+
},
|
|
1316
|
+
{
|
|
1317
|
+
headers: {
|
|
1318
|
+
Authorization: `Bearer ${process.env.HUBSPOT_ACCESS_TOKEN}`,
|
|
1319
|
+
'Content-Type': 'application/json'
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
);
|
|
1323
|
+
console.log('Contact added to list');
|
|
1324
|
+
return response.data;
|
|
1325
|
+
} catch (error) {
|
|
1326
|
+
console.error('Error adding contact to list:', error.message);
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
```
|
|
1330
|
+
|
|
1331
|
+
### Remove Contact from List
|
|
1332
|
+
|
|
1333
|
+
```javascript
|
|
1334
|
+
async function removeContactFromList(listId, contactId) {
|
|
1335
|
+
try {
|
|
1336
|
+
const axios = require('axios');
|
|
1337
|
+
const response = await axios.post(
|
|
1338
|
+
`https://api.hubapi.com/contacts/v1/lists/${listId}/remove`,
|
|
1339
|
+
{
|
|
1340
|
+
vids: [contactId]
|
|
1341
|
+
},
|
|
1342
|
+
{
|
|
1343
|
+
headers: {
|
|
1344
|
+
Authorization: `Bearer ${process.env.HUBSPOT_ACCESS_TOKEN}`,
|
|
1345
|
+
'Content-Type': 'application/json'
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
);
|
|
1349
|
+
console.log('Contact removed from list');
|
|
1350
|
+
return response.data;
|
|
1351
|
+
} catch (error) {
|
|
1352
|
+
console.error('Error removing contact from list:', error.message);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
```
|
|
1356
|
+
|
|
1357
|
+
## Owners API
|
|
1358
|
+
|
|
1359
|
+
### Get All Owners
|
|
1360
|
+
|
|
1361
|
+
```javascript
|
|
1362
|
+
async function getAllOwners() {
|
|
1363
|
+
try {
|
|
1364
|
+
const apiResponse = await hubspotClient.crm.owners.ownersApi.getPage();
|
|
1365
|
+
console.log(`Found ${apiResponse.results.length} owners`);
|
|
1366
|
+
return apiResponse;
|
|
1367
|
+
} catch (error) {
|
|
1368
|
+
console.error('Error fetching owners:', error.message);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
```
|
|
1372
|
+
|
|
1373
|
+
### Get Owner by ID
|
|
1374
|
+
|
|
1375
|
+
```javascript
|
|
1376
|
+
async function getOwner(ownerId) {
|
|
1377
|
+
try {
|
|
1378
|
+
const apiResponse = await hubspotClient.crm.owners.ownersApi.getById(ownerId);
|
|
1379
|
+
console.log('Owner:', apiResponse.email);
|
|
1380
|
+
return apiResponse;
|
|
1381
|
+
} catch (error) {
|
|
1382
|
+
console.error('Error fetching owner:', error.message);
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
```
|
|
1386
|
+
|
|
1387
|
+
## Error Handling
|
|
1388
|
+
|
|
1389
|
+
### Comprehensive Error Handling
|
|
1390
|
+
|
|
1391
|
+
```javascript
|
|
1392
|
+
async function handleApiCall() {
|
|
1393
|
+
try {
|
|
1394
|
+
const apiResponse = await hubspotClient.crm.contacts.basicApi.getById('12345');
|
|
1395
|
+
return apiResponse;
|
|
1396
|
+
} catch (error) {
|
|
1397
|
+
if (error.statusCode === 401) {
|
|
1398
|
+
console.error('Authentication failed - check your access token');
|
|
1399
|
+
} else if (error.statusCode === 404) {
|
|
1400
|
+
console.error('Resource not found');
|
|
1401
|
+
} else if (error.statusCode === 409) {
|
|
1402
|
+
console.error('Conflict - resource already exists');
|
|
1403
|
+
} else if (error.statusCode === 429) {
|
|
1404
|
+
console.error('Rate limit exceeded - wait before retrying');
|
|
1405
|
+
} else if (error.statusCode >= 500) {
|
|
1406
|
+
console.error('HubSpot server error - try again later');
|
|
1407
|
+
} else {
|
|
1408
|
+
console.error('API error:', error.message);
|
|
1409
|
+
}
|
|
1410
|
+
throw error;
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
```
|
|
1414
|
+
|
|
1415
|
+
### Retry Logic
|
|
1416
|
+
|
|
1417
|
+
```javascript
|
|
1418
|
+
async function apiCallWithRetry(apiCall, maxRetries = 3) {
|
|
1419
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
1420
|
+
try {
|
|
1421
|
+
return await apiCall();
|
|
1422
|
+
} catch (error) {
|
|
1423
|
+
if (error.statusCode === 429 && attempt < maxRetries) {
|
|
1424
|
+
const retryAfter = error.response?.headers['retry-after'] || 1;
|
|
1425
|
+
console.log(`Rate limited. Retrying after ${retryAfter} seconds...`);
|
|
1426
|
+
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
|
|
1427
|
+
} else {
|
|
1428
|
+
throw error;
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
// Usage
|
|
1435
|
+
await apiCallWithRetry(() =>
|
|
1436
|
+
hubspotClient.crm.contacts.basicApi.getById('12345')
|
|
1437
|
+
);
|
|
1438
|
+
```
|
|
1439
|
+
|
|
1440
|
+
## Rate Limits
|
|
1441
|
+
|
|
1442
|
+
HubSpot API has the following rate limits:
|
|
1443
|
+
|
|
1444
|
+
- **Private Apps:** 100 requests per 10 seconds per account
|
|
1445
|
+
- **OAuth Apps:** 100 requests per 10 seconds per app per account
|
|
1446
|
+
- **Search API:** 5 requests per second, 1000 requests per day (per account)
|
|
1447
|
+
- **Batch API:** 100 objects per request, same rate limits as standard endpoints
|
|
1448
|
+
|
|
1449
|
+
The SDK automatically handles rate limiting with the `limiterOptions` configuration.
|
|
1450
|
+
|
|
1451
|
+
## Pagination
|
|
1452
|
+
|
|
1453
|
+
Most list endpoints return paginated results. Use the `after` parameter for pagination:
|
|
1454
|
+
|
|
1455
|
+
```javascript
|
|
1456
|
+
async function paginateThroughContacts() {
|
|
1457
|
+
let after = undefined;
|
|
1458
|
+
let allContacts = [];
|
|
1459
|
+
|
|
1460
|
+
do {
|
|
1461
|
+
const apiResponse = await hubspotClient.crm.contacts.basicApi.getPage(
|
|
1462
|
+
100,
|
|
1463
|
+
after,
|
|
1464
|
+
['email', 'firstname', 'lastname']
|
|
1465
|
+
);
|
|
1466
|
+
|
|
1467
|
+
allContacts.push(...apiResponse.results);
|
|
1468
|
+
after = apiResponse.paging?.next?.after;
|
|
1469
|
+
|
|
1470
|
+
} while (after);
|
|
1471
|
+
|
|
1472
|
+
return allContacts;
|
|
1473
|
+
}
|
|
1474
|
+
```
|
|
1475
|
+
|
|
1476
|
+
## OAuth Implementation
|
|
1477
|
+
|
|
1478
|
+
### Initialize OAuth Provider
|
|
1479
|
+
|
|
1480
|
+
```javascript
|
|
1481
|
+
const hubspot = require('@hubspot/api-client');
|
|
1482
|
+
|
|
1483
|
+
const hubspotClient = new hubspot.Client({
|
|
1484
|
+
clientId: process.env.HUBSPOT_CLIENT_ID,
|
|
1485
|
+
clientSecret: process.env.HUBSPOT_CLIENT_SECRET,
|
|
1486
|
+
redirectUri: 'https://yourapp.com/oauth-callback'
|
|
1487
|
+
});
|
|
1488
|
+
```
|
|
1489
|
+
|
|
1490
|
+
### Get Authorization URL
|
|
1491
|
+
|
|
1492
|
+
```javascript
|
|
1493
|
+
function getAuthorizationUrl() {
|
|
1494
|
+
const authUrl = hubspotClient.oauth.getAuthorizationUrl(
|
|
1495
|
+
process.env.HUBSPOT_CLIENT_ID,
|
|
1496
|
+
process.env.REDIRECT_URI,
|
|
1497
|
+
'contacts crm.objects.contacts.read'
|
|
1498
|
+
);
|
|
1499
|
+
return authUrl;
|
|
1500
|
+
}
|
|
1501
|
+
```
|
|
1502
|
+
|
|
1503
|
+
### Exchange Authorization Code for Tokens
|
|
1504
|
+
|
|
1505
|
+
```javascript
|
|
1506
|
+
async function getTokens(authorizationCode) {
|
|
1507
|
+
try {
|
|
1508
|
+
const tokenResponse = await hubspotClient.oauth.tokensApi.create(
|
|
1509
|
+
'authorization_code',
|
|
1510
|
+
authorizationCode,
|
|
1511
|
+
process.env.REDIRECT_URI,
|
|
1512
|
+
process.env.HUBSPOT_CLIENT_ID,
|
|
1513
|
+
process.env.HUBSPOT_CLIENT_SECRET
|
|
1514
|
+
);
|
|
1515
|
+
|
|
1516
|
+
return {
|
|
1517
|
+
accessToken: tokenResponse.accessToken,
|
|
1518
|
+
refreshToken: tokenResponse.refreshToken,
|
|
1519
|
+
expiresIn: tokenResponse.expiresIn
|
|
1520
|
+
};
|
|
1521
|
+
} catch (error) {
|
|
1522
|
+
console.error('Error exchanging code for tokens:', error.message);
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
```
|
|
1526
|
+
|
|
1527
|
+
### Refresh Access Token
|
|
1528
|
+
|
|
1529
|
+
```javascript
|
|
1530
|
+
async function refreshAccessToken(refreshToken) {
|
|
1531
|
+
try {
|
|
1532
|
+
const tokenResponse = await hubspotClient.oauth.tokensApi.create(
|
|
1533
|
+
'refresh_token',
|
|
1534
|
+
undefined,
|
|
1535
|
+
undefined,
|
|
1536
|
+
process.env.HUBSPOT_CLIENT_ID,
|
|
1537
|
+
process.env.HUBSPOT_CLIENT_SECRET,
|
|
1538
|
+
refreshToken
|
|
1539
|
+
);
|
|
1540
|
+
|
|
1541
|
+
return {
|
|
1542
|
+
accessToken: tokenResponse.accessToken,
|
|
1543
|
+
refreshToken: tokenResponse.refreshToken,
|
|
1544
|
+
expiresIn: tokenResponse.expiresIn
|
|
1545
|
+
};
|
|
1546
|
+
} catch (error) {
|
|
1547
|
+
console.error('Error refreshing token:', error.message);
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
```
|
|
1551
|
+
|
|
1552
|
+
## Custom Objects
|
|
1553
|
+
|
|
1554
|
+
### Create Custom Object Schema
|
|
1555
|
+
|
|
1556
|
+
```javascript
|
|
1557
|
+
async function createCustomObjectSchema() {
|
|
1558
|
+
const schemaObj = {
|
|
1559
|
+
name: 'cars',
|
|
1560
|
+
labels: {
|
|
1561
|
+
singular: 'Car',
|
|
1562
|
+
plural: 'Cars'
|
|
1563
|
+
},
|
|
1564
|
+
primaryDisplayProperty: 'model',
|
|
1565
|
+
requiredProperties: ['model', 'make'],
|
|
1566
|
+
searchableProperties: ['model', 'make', 'year'],
|
|
1567
|
+
properties: [
|
|
1568
|
+
{
|
|
1569
|
+
name: 'model',
|
|
1570
|
+
label: 'Model',
|
|
1571
|
+
type: 'string',
|
|
1572
|
+
fieldType: 'text'
|
|
1573
|
+
},
|
|
1574
|
+
{
|
|
1575
|
+
name: 'make',
|
|
1576
|
+
label: 'Make',
|
|
1577
|
+
type: 'string',
|
|
1578
|
+
fieldType: 'text'
|
|
1579
|
+
},
|
|
1580
|
+
{
|
|
1581
|
+
name: 'year',
|
|
1582
|
+
label: 'Year',
|
|
1583
|
+
type: 'number',
|
|
1584
|
+
fieldType: 'number'
|
|
1585
|
+
}
|
|
1586
|
+
]
|
|
1587
|
+
};
|
|
1588
|
+
|
|
1589
|
+
try {
|
|
1590
|
+
const apiResponse = await hubspotClient.crm.schemas.coreApi.create(schemaObj);
|
|
1591
|
+
console.log('Custom object schema created:', apiResponse.name);
|
|
1592
|
+
return apiResponse;
|
|
1593
|
+
} catch (error) {
|
|
1594
|
+
console.error('Error creating custom object schema:', error.message);
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
```
|
|
1598
|
+
|
|
1599
|
+
### Create Custom Object Instance
|
|
1600
|
+
|
|
1601
|
+
```javascript
|
|
1602
|
+
async function createCustomObject(objectType) {
|
|
1603
|
+
const objectData = {
|
|
1604
|
+
properties: {
|
|
1605
|
+
model: 'Model 3',
|
|
1606
|
+
make: 'Tesla',
|
|
1607
|
+
year: '2024'
|
|
1608
|
+
}
|
|
1609
|
+
};
|
|
1610
|
+
|
|
1611
|
+
try {
|
|
1612
|
+
const apiResponse = await hubspotClient.crm.objects.basicApi.create(
|
|
1613
|
+
objectType,
|
|
1614
|
+
objectData
|
|
1615
|
+
);
|
|
1616
|
+
console.log('Custom object created:', apiResponse.id);
|
|
1617
|
+
return apiResponse;
|
|
1618
|
+
} catch (error) {
|
|
1619
|
+
console.error('Error creating custom object:', error.message);
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
```
|
|
1623
|
+
|
|
1624
|
+
## Complete Example Application
|
|
1625
|
+
|
|
1626
|
+
Here's a complete example that demonstrates multiple API operations:
|
|
1627
|
+
|
|
1628
|
+
```javascript
|
|
1629
|
+
const hubspot = require('@hubspot/api-client');
|
|
1630
|
+
require('dotenv').config();
|
|
1631
|
+
|
|
1632
|
+
const hubspotClient = new hubspot.Client({
|
|
1633
|
+
accessToken: process.env.HUBSPOT_ACCESS_TOKEN
|
|
1634
|
+
});
|
|
1635
|
+
|
|
1636
|
+
async function main() {
|
|
1637
|
+
try {
|
|
1638
|
+
// Create a contact
|
|
1639
|
+
console.log('Creating contact...');
|
|
1640
|
+
const newContact = await hubspotClient.crm.contacts.basicApi.create({
|
|
1641
|
+
properties: {
|
|
1642
|
+
email: 'john.doe@example.com',
|
|
1643
|
+
firstname: 'John',
|
|
1644
|
+
lastname: 'Doe',
|
|
1645
|
+
phone: '555-0100',
|
|
1646
|
+
company: 'Example Corp'
|
|
1647
|
+
}
|
|
1648
|
+
});
|
|
1649
|
+
console.log(`Contact created with ID: ${newContact.id}`);
|
|
1650
|
+
|
|
1651
|
+
// Create a company
|
|
1652
|
+
console.log('\nCreating company...');
|
|
1653
|
+
const newCompany = await hubspotClient.crm.companies.basicApi.create({
|
|
1654
|
+
properties: {
|
|
1655
|
+
name: 'Example Corp',
|
|
1656
|
+
domain: 'example.com',
|
|
1657
|
+
city: 'San Francisco',
|
|
1658
|
+
industry: 'Technology'
|
|
1659
|
+
}
|
|
1660
|
+
});
|
|
1661
|
+
console.log(`Company created with ID: ${newCompany.id}`);
|
|
1662
|
+
|
|
1663
|
+
// Associate contact with company
|
|
1664
|
+
console.log('\nAssociating contact with company...');
|
|
1665
|
+
await hubspotClient.crm.contacts.associationsApi.create(
|
|
1666
|
+
newContact.id,
|
|
1667
|
+
'companies',
|
|
1668
|
+
newCompany.id,
|
|
1669
|
+
'contact_to_company'
|
|
1670
|
+
);
|
|
1671
|
+
console.log('Association created successfully');
|
|
1672
|
+
|
|
1673
|
+
// Create a deal
|
|
1674
|
+
console.log('\nCreating deal...');
|
|
1675
|
+
const newDeal = await hubspotClient.crm.deals.basicApi.create({
|
|
1676
|
+
properties: {
|
|
1677
|
+
dealname: 'Example Deal',
|
|
1678
|
+
dealstage: 'appointmentscheduled',
|
|
1679
|
+
amount: '10000',
|
|
1680
|
+
closedate: '2025-12-31'
|
|
1681
|
+
}
|
|
1682
|
+
});
|
|
1683
|
+
console.log(`Deal created with ID: ${newDeal.id}`);
|
|
1684
|
+
|
|
1685
|
+
// Associate deal with contact
|
|
1686
|
+
console.log('\nAssociating deal with contact...');
|
|
1687
|
+
await hubspotClient.crm.deals.associationsApi.create(
|
|
1688
|
+
newDeal.id,
|
|
1689
|
+
'contacts',
|
|
1690
|
+
newContact.id,
|
|
1691
|
+
'deal_to_contact'
|
|
1692
|
+
);
|
|
1693
|
+
console.log('Deal associated with contact');
|
|
1694
|
+
|
|
1695
|
+
// Search for contacts
|
|
1696
|
+
console.log('\nSearching for leads...');
|
|
1697
|
+
const searchResults = await hubspotClient.crm.contacts.searchApi.doSearch({
|
|
1698
|
+
filterGroups: [
|
|
1699
|
+
{
|
|
1700
|
+
filters: [
|
|
1701
|
+
{
|
|
1702
|
+
propertyName: 'email',
|
|
1703
|
+
operator: 'CONTAINS_TOKEN',
|
|
1704
|
+
value: 'example.com'
|
|
1705
|
+
}
|
|
1706
|
+
]
|
|
1707
|
+
}
|
|
1708
|
+
],
|
|
1709
|
+
properties: ['email', 'firstname', 'lastname', 'company'],
|
|
1710
|
+
limit: 10
|
|
1711
|
+
});
|
|
1712
|
+
console.log(`Found ${searchResults.total} contacts`);
|
|
1713
|
+
|
|
1714
|
+
// List all owners
|
|
1715
|
+
console.log('\nFetching owners...');
|
|
1716
|
+
const owners = await hubspotClient.crm.owners.ownersApi.getPage();
|
|
1717
|
+
console.log(`Found ${owners.results.length} owners`);
|
|
1718
|
+
|
|
1719
|
+
console.log('\nAll operations completed successfully!');
|
|
1720
|
+
} catch (error) {
|
|
1721
|
+
console.error('Error:', error.message);
|
|
1722
|
+
if (error.body) {
|
|
1723
|
+
console.error('Error details:', JSON.stringify(error.body, null, 2));
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
main();
|
|
1729
|
+
```
|
|
1730
|
+
|
|
1731
|
+
## TypeScript Support
|
|
1732
|
+
|
|
1733
|
+
The SDK includes full TypeScript definitions:
|
|
1734
|
+
|
|
1735
|
+
```typescript
|
|
1736
|
+
import { Client } from '@hubspot/api-client';
|
|
1737
|
+
|
|
1738
|
+
const hubspotClient = new Client({
|
|
1739
|
+
accessToken: process.env.HUBSPOT_ACCESS_TOKEN
|
|
1740
|
+
});
|
|
1741
|
+
|
|
1742
|
+
interface ContactProperties {
|
|
1743
|
+
email: string;
|
|
1744
|
+
firstname: string;
|
|
1745
|
+
lastname: string;
|
|
1746
|
+
phone?: string;
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
async function createContact(props: ContactProperties) {
|
|
1750
|
+
const apiResponse = await hubspotClient.crm.contacts.basicApi.create({
|
|
1751
|
+
properties: props
|
|
1752
|
+
});
|
|
1753
|
+
return apiResponse;
|
|
1754
|
+
}
|
|
1755
|
+
```
|
|
1756
|
+
|
|
1757
|
+
## Environment Variables Template
|
|
1758
|
+
|
|
1759
|
+
```bash
|
|
1760
|
+
# .env file
|
|
1761
|
+
HUBSPOT_ACCESS_TOKEN=your_private_app_access_token
|
|
1762
|
+
HUBSPOT_CLIENT_ID=your_client_id
|
|
1763
|
+
HUBSPOT_CLIENT_SECRET=your_client_secret
|
|
1764
|
+
REDIRECT_URI=https://yourapp.com/oauth-callback
|
|
1765
|
+
```
|
|
1766
|
+
|
|
1767
|
+
## API Scopes
|
|
1768
|
+
|
|
1769
|
+
When creating a private app or OAuth app, configure the following scopes based on your needs:
|
|
1770
|
+
|
|
1771
|
+
**CRM:**
|
|
1772
|
+
- `crm.objects.contacts.read` / `crm.objects.contacts.write`
|
|
1773
|
+
- `crm.objects.companies.read` / `crm.objects.companies.write`
|
|
1774
|
+
- `crm.objects.deals.read` / `crm.objects.deals.write`
|
|
1775
|
+
- `crm.objects.owners.read`
|
|
1776
|
+
- `crm.schemas.contacts.read` / `crm.schemas.contacts.write`
|
|
1777
|
+
|
|
1778
|
+
**Marketing:**
|
|
1779
|
+
- `forms` - Read and write forms
|
|
1780
|
+
- `content` - Read and write marketing emails
|
|
1781
|
+
|
|
1782
|
+
**Automation:**
|
|
1783
|
+
- `automation` - Access to workflows
|
|
1784
|
+
|
|
1785
|
+
**Timeline:**
|
|
1786
|
+
- `timeline` - Create timeline events
|
|
1787
|
+
|
|
1788
|
+
## Migration from Legacy API Keys
|
|
1789
|
+
|
|
1790
|
+
If you're using legacy API keys (deprecated), migrate to private apps:
|
|
1791
|
+
|
|
1792
|
+
**Old (Deprecated):**
|
|
1793
|
+
```javascript
|
|
1794
|
+
// DON'T USE THIS
|
|
1795
|
+
const hapikey = 'your-api-key';
|
|
1796
|
+
```
|
|
1797
|
+
|
|
1798
|
+
**New (Correct):**
|
|
1799
|
+
```javascript
|
|
1800
|
+
const hubspotClient = new hubspot.Client({
|
|
1801
|
+
accessToken: process.env.HUBSPOT_ACCESS_TOKEN
|
|
1802
|
+
});
|
|
1803
|
+
```
|
|
1804
|
+
|
|
1805
|
+
Legacy API keys will be revoked on November 19, 2025.
|