@revfleet/hscli 0.8.7 → 0.8.11
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/CHANGELOG.md +247 -0
- package/CONTRIBUTING.md +120 -0
- package/README.md +42 -8
- package/brand/readme-hero.svg +25 -0
- package/dist/cli.js +35 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/account/index.js +5 -6
- package/dist/commands/account/index.js.map +1 -1
- package/dist/commands/api/index.js +43 -3
- package/dist/commands/api/index.js.map +1 -1
- package/dist/commands/auth/index.js +74 -13
- package/dist/commands/auth/index.js.map +1 -1
- package/dist/commands/cms/hubdb.js +31 -0
- package/dist/commands/cms/hubdb.js.map +1 -1
- package/dist/commands/cms/index.js +27 -0
- package/dist/commands/cms/index.js.map +1 -1
- package/dist/commands/cms/source-code.js +21 -0
- package/dist/commands/cms/source-code.js.map +1 -1
- package/dist/commands/communication-preferences/index.js +11 -12
- package/dist/commands/communication-preferences/index.js.map +1 -1
- package/dist/commands/crm/activities.d.ts +3 -0
- package/dist/commands/crm/activities.js +186 -0
- package/dist/commands/crm/activities.js.map +1 -0
- package/dist/commands/crm/index.js +4 -0
- package/dist/commands/crm/index.js.map +1 -1
- package/dist/commands/crm/migration.d.ts +3 -0
- package/dist/commands/crm/migration.js +155 -0
- package/dist/commands/crm/migration.js.map +1 -0
- package/dist/commands/crm/properties.js +105 -18
- package/dist/commands/crm/properties.js.map +1 -1
- package/dist/commands/crm/property-batch.d.ts +34 -0
- package/dist/commands/crm/property-batch.js +205 -0
- package/dist/commands/crm/property-batch.js.map +1 -0
- package/dist/commands/crm/shared.d.ts +1 -0
- package/dist/commands/crm/shared.js +3 -4
- package/dist/commands/crm/shared.js.map +1 -1
- package/dist/commands/doctor/index.js +119 -1
- package/dist/commands/doctor/index.js.map +1 -1
- package/dist/commands/events/index.js +7 -8
- package/dist/commands/events/index.js.map +1 -1
- package/dist/commands/forms/index.js +47 -6
- package/dist/commands/forms/index.js.map +1 -1
- package/dist/commands/forms/legacy-v2.d.ts +6 -0
- package/dist/commands/forms/legacy-v2.js +350 -0
- package/dist/commands/forms/legacy-v2.js.map +1 -0
- package/dist/commands/forms/property-preflight.d.ts +20 -0
- package/dist/commands/forms/property-preflight.js +99 -0
- package/dist/commands/forms/property-preflight.js.map +1 -0
- package/dist/commands/guide/index.d.ts +3 -0
- package/dist/commands/guide/index.js +231 -0
- package/dist/commands/guide/index.js.map +1 -0
- package/dist/commands/marketing/index.js +3 -4
- package/dist/commands/marketing/index.js.map +1 -1
- package/dist/commands/settings/index.js +249 -14
- package/dist/commands/settings/index.js.map +1 -1
- package/dist/core/auth.d.ts +7 -1
- package/dist/core/auth.js +45 -7
- package/dist/core/auth.js.map +1 -1
- package/dist/core/http.d.ts +43 -0
- package/dist/core/http.js +227 -57
- package/dist/core/http.js.map +1 -1
- package/dist/core/output.d.ts +2 -0
- package/dist/core/output.js +1 -1
- package/dist/core/output.js.map +1 -1
- package/dist/core/plugins.d.ts +5 -2
- package/dist/core/plugins.js +18 -1
- package/dist/core/plugins.js.map +1 -1
- package/dist/core/scopes.d.ts +29 -0
- package/dist/core/scopes.js +415 -0
- package/dist/core/scopes.js.map +1 -0
- package/dist/core/telemetry-context.d.ts +13 -0
- package/dist/core/telemetry-context.js +30 -0
- package/dist/core/telemetry-context.js.map +1 -0
- package/dist/mcp/ext-tools.d.ts +1 -1
- package/dist/mcp/ext-tools.js +52 -1
- package/dist/mcp/ext-tools.js.map +1 -1
- package/dist/mcp/hubspot-modules.d.ts +30 -0
- package/dist/mcp/hubspot-modules.js +305 -0
- package/dist/mcp/hubspot-modules.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.js +120 -48
- package/dist/mcp/server.js.map +1 -1
- package/docs/ARCHITECTURE.md +39 -0
- package/docs/CAPABILITY_LIBRARY.md +639 -0
- package/docs/CMS_SETUP.md +349 -0
- package/docs/COMMAND_COMPATIBILITY.md +24 -0
- package/docs/COMMAND_TREE.md +199 -0
- package/docs/COMMERCE_SETUP.md +400 -0
- package/docs/COMPARISON.md +146 -0
- package/docs/COOKBOOK.md +896 -0
- package/docs/INTEGRATIONS_NOTIFICATIONS_SETUP.md +352 -0
- package/docs/MARKETING_SETUP.md +509 -0
- package/docs/MCP.md +172 -0
- package/docs/OPERATIONAL_PLAYBOOKS.md +322 -0
- package/docs/OPERATIONS_SETUP.md +362 -0
- package/docs/PLUGIN_GUIDE.md +158 -0
- package/docs/POLICY_EXAMPLE.json +57 -0
- package/docs/PORTAL_SETUP.md +684 -0
- package/docs/PUBLISHING.md +154 -0
- package/docs/RELEASE_GOVERNANCE.md +34 -0
- package/docs/REPORTING_SETUP.md +310 -0
- package/docs/ROADMAP-DATE-BASED-API.md +103 -0
- package/docs/ROADMAP_PHASE1_TO_3.md +96 -0
- package/docs/SAFETY_MODEL.md +40 -0
- package/docs/SALES_SETUP.md +369 -0
- package/docs/SERVICE_SETUP.md +403 -0
- package/docs/TESTING_PLAN.md +89 -0
- package/docs/TIERS.md +320 -0
- package/docs/TUTORIALS/audit-portal-writes.md +150 -0
- package/docs/TUTORIALS/secure-agent-writes.md +177 -0
- package/docs/TUTORIALS/trace-replay-repro.md +147 -0
- package/docs/WHY_HOW_WHAT.md +81 -0
- package/package.json +7 -2
|
@@ -0,0 +1,684 @@
|
|
|
1
|
+
# Portal Setup Guide
|
|
2
|
+
|
|
3
|
+
How to set up a new HubSpot portal from scratch for use with hscli, in the correct order. Each phase builds on the previous one — skip nothing, follow the sequence.
|
|
4
|
+
|
|
5
|
+
Use the **Setup Checklist** at the bottom to audit an existing portal and find what's missing.
|
|
6
|
+
|
|
7
|
+
### Related Setup Guides
|
|
8
|
+
|
|
9
|
+
This guide covers the portal foundation. For hub-specific configuration, see:
|
|
10
|
+
|
|
11
|
+
| Guide | Covers |
|
|
12
|
+
|-------|--------|
|
|
13
|
+
| [MARKETING_SETUP.md](MARKETING_SETUP.md) | Email, campaigns, forms, ads, social, SEO, lead scoring, ABM |
|
|
14
|
+
| [SALES_SETUP.md](SALES_SETUP.md) | Pipelines, quotes, meetings, sequences, playbooks, forecasting |
|
|
15
|
+
| [SERVICE_SETUP.md](SERVICE_SETUP.md) | Tickets, knowledge base, customer portal, SLAs, feedback surveys |
|
|
16
|
+
| [COMMERCE_SETUP.md](COMMERCE_SETUP.md) | Products, payments, invoices, subscriptions, tax |
|
|
17
|
+
| [CMS_SETUP.md](CMS_SETUP.md) | Domains, templates, blog, pages, file manager, developer tools |
|
|
18
|
+
| [OPERATIONS_SETUP.md](OPERATIONS_SETUP.md) | Data sync, data quality, datasets, custom objects, imports |
|
|
19
|
+
| [REPORTING_SETUP.md](REPORTING_SETUP.md) | Dashboards, custom reports, attribution, analytics, goals |
|
|
20
|
+
| [INTEGRATIONS_NOTIFICATIONS_SETUP.md](INTEGRATIONS_NOTIFICATIONS_SETUP.md) | Marketplace apps, webhooks, notifications, security, account defaults |
|
|
21
|
+
|
|
22
|
+
> Also see: [COMMAND_TREE.md](COMMAND_TREE.md) for CLI commands to automate portal setup
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Phase 1: Account Foundation (UI only)
|
|
27
|
+
|
|
28
|
+
These settings affect everything downstream. Get them right first.
|
|
29
|
+
|
|
30
|
+
### 1.1 Account Defaults
|
|
31
|
+
|
|
32
|
+
**Where:** Settings > Account Management > Account Defaults > General
|
|
33
|
+
|
|
34
|
+
| Setting | What to configure | Why it matters |
|
|
35
|
+
|---------|-------------------|----------------|
|
|
36
|
+
| Account name | Your company or project name | Appears in emails, quotes, reports |
|
|
37
|
+
| Time zone | Your primary business timezone | Affects workflow triggers, email send times, reporting windows |
|
|
38
|
+
| Fiscal year | Start month (e.g., January–December) | Affects goal tracking, forecasting, fiscal-period reports |
|
|
39
|
+
| Company name | Legal entity name | Used in email footers (CAN-SPAM), quotes, invoices |
|
|
40
|
+
| Company address | Full physical address | Required for email compliance (CAN-SPAM/GDPR) |
|
|
41
|
+
| Company domain | Your main website domain | Used as default for tracking and branding |
|
|
42
|
+
|
|
43
|
+
> **API:** Read-only (`GET /account-info/v3/details`). These must be set in the UI.
|
|
44
|
+
|
|
45
|
+
### 1.2 Currency
|
|
46
|
+
|
|
47
|
+
**Where:** Settings > Account Defaults > Currency
|
|
48
|
+
|
|
49
|
+
Set your company (home) currency. Add additional currencies if you sell internationally.
|
|
50
|
+
|
|
51
|
+
| Setting | What to configure |
|
|
52
|
+
|---------|-------------------|
|
|
53
|
+
| Company currency | Your primary currency (e.g., USD, EUR, GBP) |
|
|
54
|
+
| Additional currencies | Any secondary currencies + exchange rates |
|
|
55
|
+
| Number format | Regional format (e.g., 1,234.56 vs 1 234,56) |
|
|
56
|
+
|
|
57
|
+
> **API:** `settings.currencies.read/write` scopes. Currencies can be read and managed via API after initial setup.
|
|
58
|
+
>
|
|
59
|
+
> **Important:** Company currency cannot be changed once set. Choose carefully.
|
|
60
|
+
|
|
61
|
+
### 1.3 Branding
|
|
62
|
+
|
|
63
|
+
**Where:** Settings > Account Defaults > Branding (if available on your plan)
|
|
64
|
+
|
|
65
|
+
| Setting | What to configure |
|
|
66
|
+
|---------|-------------------|
|
|
67
|
+
| Logo | Company logo (used in emails, quotes, chat widget) |
|
|
68
|
+
| Favicon | Browser tab icon for hosted pages |
|
|
69
|
+
| Brand colors | Primary and secondary colors |
|
|
70
|
+
| Fonts | Default fonts for emails and pages |
|
|
71
|
+
|
|
72
|
+
> **API:** UI only. No public API for branding settings.
|
|
73
|
+
|
|
74
|
+
### 1.4 Privacy & Consent
|
|
75
|
+
|
|
76
|
+
**Where:** Settings > Privacy & Consent
|
|
77
|
+
|
|
78
|
+
| Setting | What to configure |
|
|
79
|
+
|---------|-------------------|
|
|
80
|
+
| GDPR toggle | Enable if you process EU personal data |
|
|
81
|
+
| Consent types | Define legal basis types (legitimate interest, consent, etc.) |
|
|
82
|
+
| Cookie banner | Configure consent banner for tracking |
|
|
83
|
+
| Subscription types | Email opt-in/out categories |
|
|
84
|
+
|
|
85
|
+
> **API:** Partial. Consent properties can be set via API; GDPR mode itself is UI-only.
|
|
86
|
+
>
|
|
87
|
+
> **Why now:** Enabling GDPR after data exists creates retroactive compliance problems. Set it before any data enters the portal.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Phase 2: Domain & Email Setup (UI + DNS)
|
|
92
|
+
|
|
93
|
+
### 2.1 Connect Your Domain
|
|
94
|
+
|
|
95
|
+
**Where:** Settings > Content > Domains (or via the domain setup wizard)
|
|
96
|
+
|
|
97
|
+
| Domain type | Purpose | Example |
|
|
98
|
+
|-------------|---------|---------|
|
|
99
|
+
| Website domain | Landing pages, website pages | `www.yourcompany.com` |
|
|
100
|
+
| Email sending domain | Authenticated email delivery | `yourcompany.com` |
|
|
101
|
+
| Blog domain | Blog hosting | `blog.yourcompany.com` |
|
|
102
|
+
| Knowledge base | Help center hosting | `help.yourcompany.com` |
|
|
103
|
+
|
|
104
|
+
**Process:**
|
|
105
|
+
1. Add the domain in HubSpot
|
|
106
|
+
2. HubSpot provides DNS records (CNAME, TXT)
|
|
107
|
+
3. Add records at your DNS registrar
|
|
108
|
+
4. Wait for verification (can take up to 48h, usually minutes)
|
|
109
|
+
|
|
110
|
+
> **API:** Read-only (`GET /cms/v3/domains`). Domain connection requires the UI + DNS configuration.
|
|
111
|
+
|
|
112
|
+
### 2.2 Email Authentication (DKIM, SPF)
|
|
113
|
+
|
|
114
|
+
**Where:** Settings > Marketing > Email > Configuration
|
|
115
|
+
|
|
116
|
+
| Record | Purpose |
|
|
117
|
+
|--------|---------|
|
|
118
|
+
| CNAME (DKIM) | Proves emails are from your domain, not spoofed |
|
|
119
|
+
| TXT (SPF) | Authorizes HubSpot to send email on your behalf |
|
|
120
|
+
| DMARC | Policy for handling failed authentication (set at your DNS) |
|
|
121
|
+
|
|
122
|
+
HubSpot provides the specific DNS records. Add them at your registrar and verify.
|
|
123
|
+
|
|
124
|
+
> **Why now:** Without email authentication, marketing and transactional emails may land in spam. Must be done before sending any emails.
|
|
125
|
+
|
|
126
|
+
### 2.3 Tracking Code
|
|
127
|
+
|
|
128
|
+
**Where:** Settings > Tracking & Analytics > Tracking Code
|
|
129
|
+
|
|
130
|
+
Install the HubSpot tracking code on your website:
|
|
131
|
+
- **HubSpot-hosted pages:** Automatic, no action needed
|
|
132
|
+
- **External website:** Copy the JavaScript snippet and add it to your site's `<head>` tag
|
|
133
|
+
|
|
134
|
+
> **API:** The tracking code API can push events, but installing the snippet is manual.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Phase 3: Users & Teams (UI + API)
|
|
139
|
+
|
|
140
|
+
### 3.1 Invite Users
|
|
141
|
+
|
|
142
|
+
**Where:** Settings > Account Management > Users & Teams > Add users
|
|
143
|
+
|
|
144
|
+
| Setting | What to configure |
|
|
145
|
+
|---------|-------------------|
|
|
146
|
+
| Email addresses | Invite by email |
|
|
147
|
+
| Seats | Assign seat types (Core, Sales, Service, etc.) |
|
|
148
|
+
| Permission set | Super Admin, Admin, or custom permission sets |
|
|
149
|
+
|
|
150
|
+
**Process:**
|
|
151
|
+
1. Click **Add users** and enter email addresses
|
|
152
|
+
2. Assign a seat type (determines which tools they access)
|
|
153
|
+
3. Assign a permission set (determines what they can do)
|
|
154
|
+
4. Users receive an email invitation and must accept
|
|
155
|
+
|
|
156
|
+
> **API:** Yes — `settings.users.read/write` scopes. The User Provisioning API (`/settings/v3/users`) supports inviting and managing users. Permission sets are available through an internal HubSpot session-auth endpoint in hscli:
|
|
157
|
+
> `hscli settings permission-sets create --portal-id <id> --cookie-file cookies.txt --csrf <token> --data '{...}' --force`.
|
|
158
|
+
|
|
159
|
+
### 3.2 Create Teams
|
|
160
|
+
|
|
161
|
+
**Where:** Settings > Users & Teams > Teams tab
|
|
162
|
+
|
|
163
|
+
Teams enable:
|
|
164
|
+
- Record ownership segmentation (e.g., "Sales East" vs "Sales West")
|
|
165
|
+
- Team-based reporting and dashboards
|
|
166
|
+
- Permission hierarchies
|
|
167
|
+
|
|
168
|
+
> **API:** Teams are readable via API (`GET /settings/v3/users/teams`). Creation is done in the UI.
|
|
169
|
+
|
|
170
|
+
### 3.3 Verify Owners
|
|
171
|
+
|
|
172
|
+
Users who can own CRM records appear as "owners." After inviting users, verify they show up:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# List all owners in the portal
|
|
176
|
+
hscli crm owners list
|
|
177
|
+
|
|
178
|
+
# Filter by email
|
|
179
|
+
hscli crm owners list --email "user@yourcompany.com"
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
> **Important:** Note owner IDs — you'll need them for record creation, imports, and bulk operations.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Phase 4: Private App & CLI Authentication (UI + CLI)
|
|
187
|
+
|
|
188
|
+
### 4.1 Create a Private App
|
|
189
|
+
|
|
190
|
+
**Where:** Settings > Integrations > Private Apps (or Legacy Apps)
|
|
191
|
+
|
|
192
|
+
1. Click **Create legacy app** (or **Create a private app**)
|
|
193
|
+
2. Name it (e.g., `hscli`)
|
|
194
|
+
3. Grant the required scopes:
|
|
195
|
+
|
|
196
|
+
**Minimum scopes for full hscli functionality:**
|
|
197
|
+
|
|
198
|
+
| Category | Scopes |
|
|
199
|
+
|----------|--------|
|
|
200
|
+
| **CRM Objects** | `crm.objects.contacts.read/write`, `crm.objects.companies.read/write`, `crm.objects.deals.read/write`, `crm.objects.deals.sensitive.read` |
|
|
201
|
+
| **CRM Schemas** | `crm.schemas.contacts.read/write`, `crm.schemas.companies.read/write`, `crm.schemas.deals.read/write` |
|
|
202
|
+
| **Tickets** | `tickets`, `tickets.sensitive` |
|
|
203
|
+
| **Pipelines** | `crm.pipelines.orders.read/write` |
|
|
204
|
+
| **Owners** | `crm.objects.owners.read` |
|
|
205
|
+
| **Lists** | `crm.lists.read/write` |
|
|
206
|
+
| **Custom Objects** | `crm.objects.custom.sensitive.read/write` |
|
|
207
|
+
| **Imports** | `crm.import` |
|
|
208
|
+
| **Marketing** | `marketing-email`, `marketing.campaigns.read/write` |
|
|
209
|
+
| **Forms** | `forms` |
|
|
210
|
+
| **Files** | `files` |
|
|
211
|
+
| **CMS** | `content` |
|
|
212
|
+
| **Workflows** | `automation` |
|
|
213
|
+
| **Conversations** | `conversations.read/write` |
|
|
214
|
+
| **Settings** | `settings.users.read/write`, `settings.currencies.read/write` |
|
|
215
|
+
|
|
216
|
+
4. Click **Create app** and copy the access token
|
|
217
|
+
|
|
218
|
+
**Token format by hublet:**
|
|
219
|
+
- US: `pat-na1-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX`
|
|
220
|
+
- EU: `pat-eu1-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX`
|
|
221
|
+
|
|
222
|
+
### 4.2 Authenticate hscli
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
# Build hscli (first time only)
|
|
226
|
+
cd hscli-main && npm install && npm run build
|
|
227
|
+
|
|
228
|
+
# Authenticate (pipe to avoid token in shell history)
|
|
229
|
+
printf '%s' 'pat-eu1-XXXX' | hscli auth login --token-stdin
|
|
230
|
+
|
|
231
|
+
# Verify
|
|
232
|
+
hscli auth whoami
|
|
233
|
+
hscli auth token-info
|
|
234
|
+
|
|
235
|
+
# Check capabilities
|
|
236
|
+
hscli doctor capabilities --refresh
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Expected `auth whoami` output:** Portal ID, hublet, uiDomain, authenticated user email.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Phase 5: Data Model — Properties (CLI)
|
|
244
|
+
|
|
245
|
+
Properties define the fields on each CRM object. Standard properties exist by default; add custom properties before importing any data.
|
|
246
|
+
|
|
247
|
+
### 5.1 Review existing properties
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
# List properties per object type
|
|
251
|
+
hscli crm properties list contacts
|
|
252
|
+
hscli crm properties list companies
|
|
253
|
+
hscli crm properties list deals
|
|
254
|
+
hscli crm properties list tickets
|
|
255
|
+
|
|
256
|
+
# Full schema introspection (includes metadata)
|
|
257
|
+
hscli crm describe contacts
|
|
258
|
+
hscli crm describe deals
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### 5.2 Create custom properties
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# Example: dropdown property on contacts
|
|
265
|
+
hscli crm properties create contacts --data '{
|
|
266
|
+
"name": "lead_source_detail",
|
|
267
|
+
"label": "Lead Source Detail",
|
|
268
|
+
"type": "enumeration",
|
|
269
|
+
"fieldType": "select",
|
|
270
|
+
"groupName": "contactinformation",
|
|
271
|
+
"options": [
|
|
272
|
+
{"label": "Organic Search", "value": "organic_search", "displayOrder": 0},
|
|
273
|
+
{"label": "Paid Ads", "value": "paid_ads", "displayOrder": 1},
|
|
274
|
+
{"label": "Referral", "value": "referral", "displayOrder": 2}
|
|
275
|
+
]
|
|
276
|
+
}' --force
|
|
277
|
+
|
|
278
|
+
# Example: number property on deals
|
|
279
|
+
hscli crm properties create deals --data '{
|
|
280
|
+
"name": "mrr",
|
|
281
|
+
"label": "Monthly Recurring Revenue",
|
|
282
|
+
"type": "number",
|
|
283
|
+
"fieldType": "number",
|
|
284
|
+
"groupName": "dealinformation"
|
|
285
|
+
}' --force
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
> Default behavior is `--dry-run`. Always dry-run first, then add `--force` to commit.
|
|
289
|
+
|
|
290
|
+
### 5.3 Update existing properties
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
hscli crm properties update contacts --data '{
|
|
294
|
+
"name": "lead_source_detail",
|
|
295
|
+
"label": "Lead Source (Detailed)",
|
|
296
|
+
"options": [
|
|
297
|
+
{"label": "Organic Search", "value": "organic_search", "displayOrder": 0},
|
|
298
|
+
{"label": "Paid Ads", "value": "paid_ads", "displayOrder": 1},
|
|
299
|
+
{"label": "Referral", "value": "referral", "displayOrder": 2},
|
|
300
|
+
{"label": "Partner", "value": "partner", "displayOrder": 3}
|
|
301
|
+
]
|
|
302
|
+
}' --force
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Phase 6: Data Model — Pipelines (UI + CLI)
|
|
308
|
+
|
|
309
|
+
Pipelines define how deals and tickets flow through your process.
|
|
310
|
+
|
|
311
|
+
### 6.1 Configure Deal Pipeline
|
|
312
|
+
|
|
313
|
+
**Where:** Settings > Objects > Deals > Pipelines tab
|
|
314
|
+
|
|
315
|
+
Design your stages with probabilities:
|
|
316
|
+
|
|
317
|
+
| Stage | Probability | Meaning |
|
|
318
|
+
|-------|-------------|---------|
|
|
319
|
+
| Prospect | 10% | Initial contact, not yet qualified |
|
|
320
|
+
| Qualification | 30% | Evaluating fit and budget |
|
|
321
|
+
| Proposal | 60% | Proposal sent, awaiting decision |
|
|
322
|
+
| Negotiation | 80% | Terms being discussed |
|
|
323
|
+
| Won | 100% | Deal closed successfully |
|
|
324
|
+
| Lost | 0% | Deal did not close |
|
|
325
|
+
|
|
326
|
+
### 6.2 Configure Ticket Pipeline
|
|
327
|
+
|
|
328
|
+
**Where:** Settings > Objects > Tickets > Pipelines tab
|
|
329
|
+
|
|
330
|
+
Design your statuses:
|
|
331
|
+
|
|
332
|
+
| Status | Open/Closed |
|
|
333
|
+
|--------|-------------|
|
|
334
|
+
| New | Open |
|
|
335
|
+
| Waiting on contact | Open |
|
|
336
|
+
| Waiting on us | Open |
|
|
337
|
+
| Closed | Closed |
|
|
338
|
+
|
|
339
|
+
### 6.3 Verify via CLI
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
# List pipelines and their stages
|
|
343
|
+
hscli crm pipelines list deals
|
|
344
|
+
hscli crm pipelines list tickets
|
|
345
|
+
|
|
346
|
+
# Get detailed pipeline info (stage IDs, probabilities)
|
|
347
|
+
hscli crm pipelines get deals
|
|
348
|
+
hscli crm pipelines get tickets
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
> **Note:** The Pipelines API (`/crm/v3/pipelines`) supports full CRUD. Pipelines can also be created via API if you have the `crm.pipelines.orders.read/write` scope.
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## Phase 7: Data Model — Custom Objects (CLI, if needed)
|
|
356
|
+
|
|
357
|
+
Custom objects extend the CRM beyond contacts, companies, deals, and tickets.
|
|
358
|
+
|
|
359
|
+
### 7.1 List existing schemas
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
hscli crm custom-objects schemas list
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### 7.2 Create a custom object
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
hscli crm custom-objects schemas create --data '{
|
|
369
|
+
"name": "project",
|
|
370
|
+
"labels": {"singular": "Project", "plural": "Projects"},
|
|
371
|
+
"primaryDisplayProperty": "project_name",
|
|
372
|
+
"requiredProperties": ["project_name"],
|
|
373
|
+
"properties": [
|
|
374
|
+
{"name": "project_name", "label": "Project Name", "type": "string", "fieldType": "text"},
|
|
375
|
+
{"name": "status", "label": "Status", "type": "enumeration", "fieldType": "select",
|
|
376
|
+
"options": [
|
|
377
|
+
{"label": "Planning", "value": "planning"},
|
|
378
|
+
{"label": "Active", "value": "active"},
|
|
379
|
+
{"label": "Complete", "value": "complete"}
|
|
380
|
+
]},
|
|
381
|
+
{"name": "budget", "label": "Budget", "type": "number", "fieldType": "number"}
|
|
382
|
+
],
|
|
383
|
+
"associatedObjects": ["CONTACT", "COMPANY", "DEAL"]
|
|
384
|
+
}' --force
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## Phase 8: Test & Validate (CLI)
|
|
390
|
+
|
|
391
|
+
Before importing data at scale, create one record of each type to verify the data model.
|
|
392
|
+
|
|
393
|
+
### 8.1 Create a test contact
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
# Dry-run first
|
|
397
|
+
hscli crm contacts create --data '{
|
|
398
|
+
"properties": {
|
|
399
|
+
"email": "setup-test@example.com",
|
|
400
|
+
"firstname": "Setup",
|
|
401
|
+
"lastname": "Test",
|
|
402
|
+
"hubspot_owner_id": "<OWNER_ID>"
|
|
403
|
+
}
|
|
404
|
+
}'
|
|
405
|
+
|
|
406
|
+
# Execute
|
|
407
|
+
hscli crm contacts create --data '{
|
|
408
|
+
"properties": {
|
|
409
|
+
"email": "setup-test@example.com",
|
|
410
|
+
"firstname": "Setup",
|
|
411
|
+
"lastname": "Test",
|
|
412
|
+
"hubspot_owner_id": "<OWNER_ID>"
|
|
413
|
+
}
|
|
414
|
+
}' --force
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### 8.2 Create and associate records
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
# Create a company
|
|
421
|
+
hscli crm companies create --data '{
|
|
422
|
+
"properties": {"name": "Test Company", "domain": "testco.com"}
|
|
423
|
+
}' --force
|
|
424
|
+
|
|
425
|
+
# Associate contact → company
|
|
426
|
+
hscli crm associations create contacts <contactId> companies <companyId> --force
|
|
427
|
+
|
|
428
|
+
# Create a deal in the pipeline
|
|
429
|
+
hscli crm deals create --data '{
|
|
430
|
+
"properties": {
|
|
431
|
+
"dealname": "Test Deal",
|
|
432
|
+
"pipeline": "<pipelineId>",
|
|
433
|
+
"dealstage": "<stageId>",
|
|
434
|
+
"amount": "10000",
|
|
435
|
+
"hubspot_owner_id": "<OWNER_ID>"
|
|
436
|
+
}
|
|
437
|
+
}' --force
|
|
438
|
+
|
|
439
|
+
# Associate deal → contact and deal → company
|
|
440
|
+
hscli crm associations create deals <dealId> contacts <contactId> --force
|
|
441
|
+
hscli crm associations create deals <dealId> companies <companyId> --force
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### 8.3 Validate data
|
|
445
|
+
|
|
446
|
+
```bash
|
|
447
|
+
# Validate a payload against the schema before creating
|
|
448
|
+
hscli crm validate contacts --data '{
|
|
449
|
+
"properties": {"email": "test@example.com", "firstname": "Test"}
|
|
450
|
+
}'
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## Phase 9: Data Import (CLI)
|
|
456
|
+
|
|
457
|
+
Once the data model is validated, import your data.
|
|
458
|
+
|
|
459
|
+
### 9.1 Single records
|
|
460
|
+
|
|
461
|
+
```bash
|
|
462
|
+
hscli crm contacts create --data '{...}' --force
|
|
463
|
+
hscli crm companies create --data '{...}' --force
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
### 9.2 Batch operations
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
hscli crm contacts batch-upsert --data '{
|
|
470
|
+
"inputs": [
|
|
471
|
+
{"properties": {"email": "alice@example.com", "firstname": "Alice"}, "idProperty": "email"},
|
|
472
|
+
{"properties": {"email": "bob@example.com", "firstname": "Bob"}, "idProperty": "email"}
|
|
473
|
+
]
|
|
474
|
+
}' --force
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### 9.3 CSV imports
|
|
478
|
+
|
|
479
|
+
```bash
|
|
480
|
+
hscli crm imports create --data '<import-payload>' --force
|
|
481
|
+
|
|
482
|
+
# Check import status
|
|
483
|
+
hscli crm imports list
|
|
484
|
+
hscli crm imports get <importId>
|
|
485
|
+
hscli crm imports errors <importId>
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### Import safety rules
|
|
489
|
+
|
|
490
|
+
- **Validate first:** Create a single test record before bulk operations
|
|
491
|
+
- **5-error hard stop:** If >5 errors on the same endpoint, stop and diagnose
|
|
492
|
+
- **Rate limits:** ~100 requests/10s for private apps. Use sequential processing with 1-2s pauses per 5 records
|
|
493
|
+
- **Idempotent re-runs:** Check for existing records before creating duplicates
|
|
494
|
+
- **Always assign owners:** Never import records without an owner
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
498
|
+
## Phase 10: Engagement Tools (UI + CLI)
|
|
499
|
+
|
|
500
|
+
### 10.1 Email Configuration
|
|
501
|
+
|
|
502
|
+
**Where:** Settings > Marketing > Email
|
|
503
|
+
|
|
504
|
+
| Setting | What to configure |
|
|
505
|
+
|---------|-------------------|
|
|
506
|
+
| Subscription types | Define email categories (Marketing, Sales, Newsletter, etc.) |
|
|
507
|
+
| Email footer | Company name, address (required by CAN-SPAM) |
|
|
508
|
+
| Default "from" address | noreply@, marketing@, etc. |
|
|
509
|
+
|
|
510
|
+
### 10.2 Forms
|
|
511
|
+
|
|
512
|
+
```bash
|
|
513
|
+
# List existing forms
|
|
514
|
+
hscli forms list
|
|
515
|
+
|
|
516
|
+
# Create a form
|
|
517
|
+
hscli forms create --data '{...}' --force
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
### 10.3 Workflows
|
|
521
|
+
|
|
522
|
+
**Where:** Automation > Workflows (UI only for building; `automation` scope for custom actions)
|
|
523
|
+
|
|
524
|
+
```bash
|
|
525
|
+
# List workflows
|
|
526
|
+
hscli workflows flows list
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
---
|
|
530
|
+
|
|
531
|
+
## Setup Checklist
|
|
532
|
+
|
|
533
|
+
Use this to verify a new portal or audit an existing one. Items are in dependency order.
|
|
534
|
+
|
|
535
|
+
### Phase 1 — Account Foundation (UI)
|
|
536
|
+
```
|
|
537
|
+
[ ] Account name set
|
|
538
|
+
[ ] Time zone configured
|
|
539
|
+
[ ] Fiscal year set
|
|
540
|
+
[ ] Company name and address filled in (email compliance)
|
|
541
|
+
[ ] Company currency set (cannot be changed later)
|
|
542
|
+
[ ] Additional currencies added (if multi-currency)
|
|
543
|
+
[ ] Branding configured (logo, colors, favicon)
|
|
544
|
+
[ ] Privacy & consent settings enabled (GDPR if applicable)
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
### Phase 2 — Domains & Email (UI + DNS)
|
|
548
|
+
```
|
|
549
|
+
[ ] Website domain connected and verified
|
|
550
|
+
[ ] Email sending domain authenticated (DKIM + SPF)
|
|
551
|
+
[ ] DMARC record configured at DNS registrar
|
|
552
|
+
[ ] Tracking code installed on external website
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
### Phase 3 — Users & Teams (UI)
|
|
556
|
+
```
|
|
557
|
+
[ ] Users invited with correct seats and permissions
|
|
558
|
+
[ ] Teams created (if using team-based segmentation)
|
|
559
|
+
[ ] Owners verified: hscli crm owners list
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Phase 4 — CLI Authentication
|
|
563
|
+
```
|
|
564
|
+
[ ] Private App created with required scopes
|
|
565
|
+
[ ] hscli authenticated: hscli auth whoami
|
|
566
|
+
[ ] Token info verified: hscli auth token-info
|
|
567
|
+
[ ] Capabilities checked: hscli doctor capabilities --refresh
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### Phase 5 — Properties (CLI)
|
|
571
|
+
```
|
|
572
|
+
[ ] Contact properties reviewed/created
|
|
573
|
+
[ ] Company properties reviewed/created
|
|
574
|
+
[ ] Deal properties reviewed/created
|
|
575
|
+
[ ] Ticket properties reviewed/created
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### Phase 6 — Pipelines (UI, verified via CLI)
|
|
579
|
+
```
|
|
580
|
+
[ ] Deal pipeline stages configured with probabilities
|
|
581
|
+
[ ] Ticket pipeline statuses configured (open/closed)
|
|
582
|
+
[ ] Pipelines verified: hscli crm pipelines list deals
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
### Phase 7 — Custom Objects (CLI, if needed)
|
|
586
|
+
```
|
|
587
|
+
[ ] Custom object schemas created
|
|
588
|
+
[ ] Custom object properties defined
|
|
589
|
+
[ ] Associations configured
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
### Phase 8 — Validation (CLI)
|
|
593
|
+
```
|
|
594
|
+
[ ] Test contact created and verified
|
|
595
|
+
[ ] Test company created and associated
|
|
596
|
+
[ ] Test deal created in correct pipeline/stage
|
|
597
|
+
[ ] Associations verified between objects
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### Phase 9 — Data Import (CLI)
|
|
601
|
+
```
|
|
602
|
+
[ ] Data imported (contacts, companies, deals, tickets)
|
|
603
|
+
[ ] Import errors reviewed and resolved
|
|
604
|
+
[ ] Owner assignment verified on imported records
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
### Phase 10 — Engagement Tools (UI + CLI)
|
|
608
|
+
```
|
|
609
|
+
[ ] Email subscription types configured
|
|
610
|
+
[ ] Email footer set (company address)
|
|
611
|
+
[ ] Forms created (if needed)
|
|
612
|
+
[ ] Workflows built (if needed)
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
---
|
|
616
|
+
|
|
617
|
+
## Quick Audit Script
|
|
618
|
+
|
|
619
|
+
Run this to quickly assess what's configured in an existing portal:
|
|
620
|
+
|
|
621
|
+
```bash
|
|
622
|
+
#!/bin/bash
|
|
623
|
+
echo "=== Auth & Connectivity ==="
|
|
624
|
+
hscli auth whoami
|
|
625
|
+
hscli doctor capabilities --refresh
|
|
626
|
+
|
|
627
|
+
echo "=== Owners ==="
|
|
628
|
+
hscli crm owners list
|
|
629
|
+
|
|
630
|
+
echo "=== Pipelines ==="
|
|
631
|
+
hscli crm pipelines list deals
|
|
632
|
+
hscli crm pipelines list tickets
|
|
633
|
+
|
|
634
|
+
echo "=== Property Counts ==="
|
|
635
|
+
hscli crm properties list contacts --json 2>/dev/null | grep -c '"name"' || echo "contacts: error"
|
|
636
|
+
hscli crm properties list companies --json 2>/dev/null | grep -c '"name"' || echo "companies: error"
|
|
637
|
+
hscli crm properties list deals --json 2>/dev/null | grep -c '"name"' || echo "deals: error"
|
|
638
|
+
hscli crm properties list tickets --json 2>/dev/null | grep -c '"name"' || echo "tickets: error"
|
|
639
|
+
|
|
640
|
+
echo "=== Custom Objects ==="
|
|
641
|
+
hscli crm custom-objects schemas list
|
|
642
|
+
|
|
643
|
+
echo "=== Record Counts ==="
|
|
644
|
+
hscli crm contacts search --data '{"filterGroups":[], "limit": 1}' --json 2>/dev/null
|
|
645
|
+
hscli crm companies search --data '{"filterGroups":[], "limit": 1}' --json 2>/dev/null
|
|
646
|
+
hscli crm deals search --data '{"filterGroups":[], "limit": 1}' --json 2>/dev/null
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
---
|
|
650
|
+
|
|
651
|
+
## API vs UI Reference
|
|
652
|
+
|
|
653
|
+
| Step | What | API support | hscli command |
|
|
654
|
+
|------|------|-------------|----------------|
|
|
655
|
+
| Account defaults | Name, timezone, currency | Read-only | — |
|
|
656
|
+
| Branding | Logo, colors, fonts | None | — |
|
|
657
|
+
| Domains | Website, email sending | Read-only | — |
|
|
658
|
+
| Email auth | DKIM, SPF | None (DNS manual) | — |
|
|
659
|
+
| Tracking code | JS snippet | Push events only | — |
|
|
660
|
+
| Privacy/consent | GDPR, cookie banner | Partial | — |
|
|
661
|
+
| Users | Invite, permissions | Full CRUD; permission sets require session auth | `hscli settings users list`, `hscli settings permission-sets list` |
|
|
662
|
+
| Owners | List portal owners | Read | `hscli crm owners list` |
|
|
663
|
+
| Properties | Object fields | Full CRUD | `hscli crm properties list/create/update` |
|
|
664
|
+
| Pipelines | Deal/ticket stages | Full CRUD | `hscli crm pipelines list/get` |
|
|
665
|
+
| Custom objects | Schema + records | Full CRUD | `hscli crm custom-objects schemas list/create` |
|
|
666
|
+
| Data import | Bulk CSV | Full | `hscli crm imports create` |
|
|
667
|
+
| Records | CRUD + search | Full | `hscli crm <object> list/get/create/update/delete` |
|
|
668
|
+
| Associations | Record linking | Full | `hscli crm associations create/list/remove` |
|
|
669
|
+
| Forms | Lead capture | Full CRUD | `hscli forms list/create` |
|
|
670
|
+
| Workflows | Automation | Limited | `hscli workflows flows list` |
|
|
671
|
+
| Marketing | Email, campaigns | Partial | `hscli marketing emails/campaigns list` |
|
|
672
|
+
|
|
673
|
+
---
|
|
674
|
+
|
|
675
|
+
## Hublet Reference
|
|
676
|
+
|
|
677
|
+
hscli auto-detects the hublet from the token prefix and routes API calls to the correct endpoint.
|
|
678
|
+
|
|
679
|
+
| Hublet | Token prefix | API base URL | UI domain |
|
|
680
|
+
|--------|-------------|-------------|-----------|
|
|
681
|
+
| US | `pat-na1-*` | `https://api.hubapi.com` | `app.hubspot.com` |
|
|
682
|
+
| EU | `pat-eu1-*` | `https://api-eu1.hubapi.com` | `app-eu1.hubspot.com` |
|
|
683
|
+
|
|
684
|
+
Never hardcode `api.hubapi.com` — it defaults to US and will fail for EU portals.
|