@revfleet/hscli 0.8.7 → 0.8.10
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 +204 -0
- package/CONTRIBUTING.md +120 -0
- package/README.md +14 -6
- package/brand/readme-hero.svg +25 -0
- package/dist/cli.js +10 -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 +32 -6
- 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/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/events/index.js +7 -8
- package/dist/commands/events/index.js.map +1 -1
- package/dist/commands/marketing/index.js +3 -4
- package/dist/commands/marketing/index.js.map +1 -1
- package/dist/commands/settings/index.js +12 -13
- package/dist/commands/settings/index.js.map +1 -1
- package/dist/core/http.d.ts +27 -0
- package/dist/core/http.js +87 -18
- package/dist/core/http.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/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/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 +30 -26
- package/dist/mcp/server.js.map +1 -1
- package/docs/ARCHITECTURE.md +39 -0
- package/docs/CAPABILITY_LIBRARY.md +638 -0
- package/docs/CMS_SETUP.md +349 -0
- package/docs/COMMAND_COMPATIBILITY.md +24 -0
- package/docs/COMMAND_TREE.md +183 -0
- package/docs/COMMERCE_SETUP.md +400 -0
- package/docs/COMPARISON.md +146 -0
- package/docs/COOKBOOK.md +800 -0
- package/docs/INTEGRATIONS_NOTIFICATIONS_SETUP.md +352 -0
- package/docs/MARKETING_SETUP.md +503 -0
- package/docs/MCP.md +171 -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 +683 -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 +37 -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,638 @@
|
|
|
1
|
+
# hscli Capability Library
|
|
2
|
+
|
|
3
|
+
> **Scope.** Every CRM, Marketing, Sales, Service, Content, and Admin job a
|
|
4
|
+
> HubSpot user performs through the UI, mapped to the hscli CLI + MCP
|
|
5
|
+
> commands that replicate it.
|
|
6
|
+
>
|
|
7
|
+
> **Verification.** Every ⚠️ and ❌ entry below was probed directly against
|
|
8
|
+
> HubSpot's public API on 2026-04-23 (portal 147975758, EU1). Exact
|
|
9
|
+
> HTTP status + error message recorded in Appendix C. Nothing in this
|
|
10
|
+
> doc is "claimed from priors" — if we couldn't reproduce it we removed
|
|
11
|
+
> it.
|
|
12
|
+
>
|
|
13
|
+
> **Legend:**
|
|
14
|
+
> - ✅ Full parity — endpoint works via hscli
|
|
15
|
+
> - ⚠️ Partial — endpoint works but shape-restricted, or requires a
|
|
16
|
+
> workaround (each case has specifics below)
|
|
17
|
+
> - ❌ HubSpot API-locked — no public endpoint exists (verified: 404 on
|
|
18
|
+
> every reasonable path)
|
|
19
|
+
> - 🚧 hscli-allowlist-blocked — HubSpot serves the path, hscli's
|
|
20
|
+
> `INVALID_PATH_SCOPE` guard rejects it. Fixable in hscli.
|
|
21
|
+
> - 🔒 Enterprise-tier endpoint (exists but portal tier gates access)
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 1. CRM data operations
|
|
26
|
+
|
|
27
|
+
### Contacts, Companies, Deals, Tickets
|
|
28
|
+
|
|
29
|
+
| Job | Command | Status |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| Create / read / update / archive | `hscli crm {type} create|get|update|delete` | ✅ |
|
|
32
|
+
| List (paginated + filters) | `hscli crm {type} list --limit N --after <cursor>` | ✅ |
|
|
33
|
+
| Complex search | `hscli crm {type} search --data '{"filterGroups":[...]}'` | ✅ |
|
|
34
|
+
| Batch CRUD | `hscli crm {type} batch-create|batch-update|batch-archive` | ✅ |
|
|
35
|
+
| Merge (dedupe) | `hscli crm contacts merge --primary <id> --merge-from <id>` | ✅ |
|
|
36
|
+
| Bulk import (CSV/JSON) | `hscli crm imports create --data '{...}'` | ✅ |
|
|
37
|
+
|
|
38
|
+
### Engagements (calls, meetings, emails, notes, tasks)
|
|
39
|
+
|
|
40
|
+
All five types: `hscli crm engagements {type} create|get|update|delete|list` plus batch variants. ✅
|
|
41
|
+
|
|
42
|
+
### Properties + pipelines + associations + owners
|
|
43
|
+
|
|
44
|
+
| Job | Command | Status |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| Property CRUD + enum edits | `hscli crm properties create|update|delete|list|get` | ✅ |
|
|
47
|
+
| Property groups | `hscli crm properties groups create|list|update|delete` | ✅ |
|
|
48
|
+
| Schema description | `hscli crm describe <objectType>` | ✅ |
|
|
49
|
+
| Pre-flight payload validation | `hscli crm validate <objectType> --data '{...}'` | ✅ |
|
|
50
|
+
| Pipelines + stages | `hscli crm pipelines create|update|list + pipelines stages …` | ✅ |
|
|
51
|
+
| Associations + labels (v4) | `hscli crm associations + associations labels` | ✅ |
|
|
52
|
+
| Owners | `hscli crm owners list|get` | ✅ |
|
|
53
|
+
|
|
54
|
+
### Custom objects
|
|
55
|
+
|
|
56
|
+
| Job | Command | Status |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| Define / update schemas | `hscli crm custom-objects schemas create|update|list|get` | ✅ |
|
|
59
|
+
| CRUD records | `hscli crm custom-objects records create|get|list|update|delete` | ✅ |
|
|
60
|
+
|
|
61
|
+
### Commerce + Sales-Hub objects
|
|
62
|
+
|
|
63
|
+
All readable + writable via standard CRM endpoints:
|
|
64
|
+
|
|
65
|
+
| Object | Command | Notes |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| `hscli crm quotes` | ✅ | Quotes CRUD via `/crm/v3/objects/quotes`. **Verified on this portal.** |
|
|
68
|
+
| `hscli crm quote-templates` | ✅ | Quote template records readable via `/crm/v3/objects/quote_templates`. |
|
|
69
|
+
| `hscli crm products` | ✅ | Product catalog CRUD. |
|
|
70
|
+
| `hscli crm line_items` | ✅ | Quote / deal line items. |
|
|
71
|
+
| `hscli crm invoices` | 🔒 | Commerce Hub gated; API available on eligible portals. |
|
|
72
|
+
| `hscli crm commerce_payments` | 🔒 | Same. |
|
|
73
|
+
| `hscli crm subscriptions` | 🔒 | Subscription billing. |
|
|
74
|
+
| `hscli crm goals` | ✅ | Goal targets via `/crm/v3/objects/goal_targets`. **Verified.** |
|
|
75
|
+
| Forecasts (read-only) | `hscli api request --path "/crm/v4/objects/forecast"` | ✅ — records + schema both accessible. **Verified.** |
|
|
76
|
+
|
|
77
|
+
### Playbooks (Sales Hub Enterprise)
|
|
78
|
+
|
|
79
|
+
- Playbook object schema accessible at `/crm/v3/schemas/playbooks`. **Verified.**
|
|
80
|
+
- Playbook-record CRUD works via the standard custom-object pattern:
|
|
81
|
+
`hscli crm custom-objects records create --schema-id <playbook_schema_id> --data '{...}'` ✅
|
|
82
|
+
- Original library claimed "Playbook content authoring ❌ UI-only" — **that was wrong.** Corrected.
|
|
83
|
+
|
|
84
|
+
### Incremental sync (ETL)
|
|
85
|
+
|
|
86
|
+
`hscli crm sync` — cursor-based delta sync feeding external warehouses. ✅
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 2. Marketing operations
|
|
91
|
+
|
|
92
|
+
### Marketing emails
|
|
93
|
+
|
|
94
|
+
| Job | Command | Status | Notes |
|
|
95
|
+
|---|---|---|---|
|
|
96
|
+
| Create DRAFT / AUTOMATED_DRAFT email | `hscli marketing emails create --data '{...}'` | ✅ | |
|
|
97
|
+
| List / get / update / archive | `hscli marketing emails list|get|update` | ✅ | |
|
|
98
|
+
| Per-email statistics | via `hscli api request --path "/marketing/v3/emails/statistics/{id}"` | ⚠️ | Per-email stats path `/marketing/v3/emails/{id}/statistics` returns 404. Aggregate stats live under `/email-events/v1/events` — use `hscli email-events campaign <campaignId>`. |
|
|
99
|
+
| **Revision history** | `hscli marketing emails revisions <id>` | ✅ | `GET /marketing/v3/emails/{id}/revisions`. |
|
|
100
|
+
| **Restore past revision to DRAFT** | `hscli marketing emails revision-restore <id> <revisionId>` | ✅ | `POST /marketing/v3/emails/{id}/revisions/{revisionId}/restore-to-draft`. |
|
|
101
|
+
| **Unpublish** | `hscli marketing emails unpublish <id>` | ✅ | `POST /marketing/v3/emails/{id}/unpublish`. |
|
|
102
|
+
| **Reset draft to last-published state** | `hscli marketing emails draft-reset <id>` | ✅ | `POST /marketing/v3/emails/{id}/draft/reset`. |
|
|
103
|
+
| **Publish v3 email** | `hscli marketing emails publish <id>` | ✅ | `POST /marketing/v3/emails/{id}/publish`. Verified live. |
|
|
104
|
+
| Create in published `AUTOMATED` state directly | n/a | ❌ | API explicitly rejects with *"Creating an email in the published state AUTOMATED is not allowed. Consider using AUTOMATED_DRAFT."* Use `create` + `publish` instead. |
|
|
105
|
+
| Update state `AUTOMATED_DRAFT` → `AUTOMATED` via PATCH/PUT | n/a | ❌ | PATCH returns 400 "Error validating request"; PUT returns 405. Must use `/publish` endpoint. |
|
|
106
|
+
| **Clone v3 email** | `hscli marketing emails clone <id> --name '<name>'` | ✅ | `POST /marketing/v3/emails/clone` — id goes in the **body**, not the path. Verified live 2026-04-23. Earlier miss (I only tried `/clone`, `/copies`, etc. with id in path). |
|
|
107
|
+
| **A/B test variant authoring** | `hscli marketing emails ab-variant --content-id <id> --name '<name>'` | ✅ | `POST /marketing/v3/emails/ab-test/create-variation` with `{contentId, variationName}` body. Verified live 2026-04-23. Returned email has `isAb: true`. |
|
|
108
|
+
| **Multi-module body via flexAreas** | `content.flexAreas.main.sections + content.widgets` | ⚠️ | Only `@hubspot/rich_text`, `@hubspot/email_footer`, and the `preview_text` widget render in the in-editor iframe. `@hubspot/button`, `@hubspot/divider`, `@hubspot/header`, `@hubspot/linked_image`, `@hubspot/email_linked_image` persist in the DB but silently no-op in the editor canvas. Workaround: compose body as multiple rich_text sections with inline HTML. |
|
|
109
|
+
| **Body image** | inline `<img>` in rich_text, src = HubFS URL | ⚠️ | Renders only in the **webversion preview URL** (`https://{portal}.hubspotpreview-{hublet}.com/_hcms/preview/email/{id}?preview_key=…`). The in-editor iframe sandboxes cross-origin images. First upload the image via `POST /files/v3/files/import-from-url/async` to get a HubFS URL. |
|
|
110
|
+
| Merge-tag chip markup | n/a | ❌ | Chip is an in-edit React overlay, not persistent markup. Tested 5 variants (span + data attrs + various classes) — none reproduce the chip. HubSpot's own UI-created emails also store raw `{{ }}` in their widget HTML. |
|
|
111
|
+
| Upload custom email template | `POST /cms/v3/source-code/published/content/{path}` | ⚠️ | Endpoint returns 415 "Unsupported Media Type" with JSON body — it expects `text/plain` or `multipart/form-data`. hscli's `api request` currently hardcodes `Content-Type: application/json`. Fix in hscli needed to unlock full uploads. |
|
|
112
|
+
|
|
113
|
+
### Landing pages
|
|
114
|
+
|
|
115
|
+
| Job | Command | Status |
|
|
116
|
+
|---|---|---|
|
|
117
|
+
| Create / update / list / get | `hscli marketing landing-pages create|update|list|get` + `hscli cms landing-pages …` | ✅ |
|
|
118
|
+
| Populate layout with drag-drop modules | `layoutSections` + `widgets` | ✅ — unlike emails, page canvas renders `@hubspot/button`, `@hubspot/divider`, `@hubspot/header`, `@hubspot/form`, etc. |
|
|
119
|
+
| Attach template | `templatePath: "@hubspot/growth/templates/homepage.html"` | ⚠️ — template must exist on portal, else "template missing" modal. |
|
|
120
|
+
| Publish page | state transition via update | ✅ |
|
|
121
|
+
| Site pages (non-landing) | `hscli cms site-pages` | ✅ |
|
|
122
|
+
|
|
123
|
+
### Forms
|
|
124
|
+
|
|
125
|
+
- `hscli forms create|get|list|update` ✅
|
|
126
|
+
- `hscli submissions list <formGuid>` ✅
|
|
127
|
+
- `hscli submissions search <portalId> <formGuid>` ✅
|
|
128
|
+
- Embed codes: generated client-side from form id ✅
|
|
129
|
+
|
|
130
|
+
### Lists (static + dynamic)
|
|
131
|
+
|
|
132
|
+
| Job | Command | Status |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| Create static list | `hscli lists create --data '{... "processingType":"MANUAL"}'` | ✅ |
|
|
135
|
+
| Create dynamic list (filter rules) | `--data '{..., "processingType":"DYNAMIC", "filterBranch":{...}}'` | ✅ |
|
|
136
|
+
| Membership CRUD | `hscli lists add-members|remove-members|memberships` | ✅ |
|
|
137
|
+
| Folders | `hscli lists folders …` | ✅ |
|
|
138
|
+
|
|
139
|
+
### Campaigns
|
|
140
|
+
|
|
141
|
+
- `hscli marketing campaigns list|get|create|update|delete` ✅
|
|
142
|
+
- Per-campaign contacts / assets / revenue / budget ✅
|
|
143
|
+
|
|
144
|
+
### Ads (Google / Meta / LinkedIn)
|
|
145
|
+
|
|
146
|
+
- `hscli marketing ads accounts|campaigns|audiences` ✅
|
|
147
|
+
- Running ads requires the Ads Hub tier 🔒
|
|
148
|
+
|
|
149
|
+
### Social
|
|
150
|
+
|
|
151
|
+
- `hscli marketing social posts list|get|create|delete` — scheduled posts ✅
|
|
152
|
+
- Interactive inbox actions (like, reply) ❌ — no public endpoint found.
|
|
153
|
+
|
|
154
|
+
### SEO
|
|
155
|
+
|
|
156
|
+
- `hscli marketing seo topic-clusters|recommendations` ✅
|
|
157
|
+
- `hscli cms seo-audit` — site-wide SEO audit ✅
|
|
158
|
+
|
|
159
|
+
### Marketing events
|
|
160
|
+
|
|
161
|
+
- `hscli marketing events create|list|update|delete` ✅
|
|
162
|
+
- Event attendees + external-id mapping ✅
|
|
163
|
+
|
|
164
|
+
### Transactional email (single-send API)
|
|
165
|
+
|
|
166
|
+
- `hscli marketing transactional send` 🔒 — requires Transactional Email add-on.
|
|
167
|
+
|
|
168
|
+
### Subscription / communication preferences
|
|
169
|
+
|
|
170
|
+
- `hscli marketing subscriptions subscription-types` ✅
|
|
171
|
+
- `hscli communication-preferences subscribe|unsubscribe|status` ✅
|
|
172
|
+
- GDPR-compliant consent management ✅
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 3. Sales operations
|
|
177
|
+
|
|
178
|
+
### Sequences (sales cadences)
|
|
179
|
+
|
|
180
|
+
- `hscli sales sequences list|get|enroll|pause|resume` ✅
|
|
181
|
+
- Template + enrollment analytics ✅
|
|
182
|
+
|
|
183
|
+
### Meetings
|
|
184
|
+
|
|
185
|
+
- `hscli sales meetings list|get|create|update` ✅
|
|
186
|
+
- Availability schedules ✅
|
|
187
|
+
- Scheduled meetings (record layer) ✅
|
|
188
|
+
|
|
189
|
+
### Calling
|
|
190
|
+
|
|
191
|
+
- `hscli sales calling` — call records + engagement hooks ✅
|
|
192
|
+
|
|
193
|
+
### Quotes
|
|
194
|
+
|
|
195
|
+
- `hscli crm quotes` — CRUD ✅ (requires Sales Hub Pro+ on some tiers 🔒)
|
|
196
|
+
- Quote templates readable via `hscli crm quote_templates` ✅
|
|
197
|
+
- E-signature submission | ❌ | Verified 404 on `POST /crm/v3/objects/quotes/{id}/esignature`. |
|
|
198
|
+
|
|
199
|
+
### Forecasts
|
|
200
|
+
|
|
201
|
+
- Read accessible via `/crm/v4/objects/forecast` ✅
|
|
202
|
+
- Forecast category authoring | ❌ | Verified 404 on `/crm/v3/forecasts/categories` + `/analytics/v2/reports/sales/forecast`. |
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 4. Service / Support
|
|
207
|
+
|
|
208
|
+
### Tickets
|
|
209
|
+
|
|
210
|
+
- Full CRUD via `hscli crm tickets` ✅
|
|
211
|
+
- Pipelines via `hscli crm pipelines` ✅
|
|
212
|
+
- SLA policies | ❌ | Verified 404 on `/conversations/v3/sla-policies` + 400 on `/crm/v3/objects/sla_policies`. No public SLA endpoint. |
|
|
213
|
+
|
|
214
|
+
### Conversations (inbox)
|
|
215
|
+
|
|
216
|
+
| Job | Command | Status |
|
|
217
|
+
|---|---|---|
|
|
218
|
+
| List threads | `hscli conversations threads list` | ✅ |
|
|
219
|
+
| Get thread + messages | `hscli conversations threads get|messages list` | ✅ |
|
|
220
|
+
| Post a message | `hscli conversations messages send` | ✅ |
|
|
221
|
+
| Inboxes / channels | `hscli conversations inboxes|channels|channel-accounts` | ✅ |
|
|
222
|
+
| Custom channels (app-dev) | `hscli conversations custom-channels` | ✅ |
|
|
223
|
+
|
|
224
|
+
### Chatflows / chatbots
|
|
225
|
+
|
|
226
|
+
- `hscli service chatflows` ❌ — Verified 404 on `/conversations/v3/chatflows` (list + get). hscli's `chatflows` subcommand currently 404s on every verb. Authoring + decision-tree config are UI-only.
|
|
227
|
+
|
|
228
|
+
### Feedback / surveys
|
|
229
|
+
|
|
230
|
+
- `hscli reporting feedback` — aggregate analytics ✅
|
|
231
|
+
- Survey definition endpoints | 🚧 | `/feedback/v3/*` and `/feedback/v4/*` return `INVALID_PATH_SCOPE` from hscli's own allowlist — **not** a HubSpot-side block. One-line hscli fix would unlock survey CRUD. |
|
|
232
|
+
|
|
233
|
+
### Knowledge base
|
|
234
|
+
|
|
235
|
+
- `hscli service kb` ⚠️ — partial; HubSpot's public KB API surface is inconsistent across portals.
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## 5. Automation
|
|
240
|
+
|
|
241
|
+
### Workflows
|
|
242
|
+
|
|
243
|
+
HubSpot exposes TWO public workflow APIs:
|
|
244
|
+
|
|
245
|
+
**🎯 Legacy v3 `/automation/v3/workflows`** — accepts populated `actions[]` on create. Dual-backed: workflows created via v3 also appear via v4 (`migrationStatus.flowId`) and render in the modern HubSpot canvas UI with visible action nodes. Contact-based only.
|
|
246
|
+
|
|
247
|
+
**v4 `/automation/v4/flows`** — current API. Works for metadata + enrollment triggers. `actions[]` on create returns 500 (schema internal). Recommended: create via v3, read/list via either.
|
|
248
|
+
|
|
249
|
+
| Job | Command | Status | Evidence |
|
|
250
|
+
|---|---|---|---|
|
|
251
|
+
| **Create multi-step workflow** (DELAY · EMAIL · SET_PROPERTY · BRANCH · WEBHOOK · UPDATE_LIST · TASK · TICKET · DEAL · NOTIFICATION) | `hscli workflows v3 create --data '{...}'` | ✅ | **Verified 2026-04-23:** 5-step DELAY→EMAIL→DELAY→SET_PROPERTY→BRANCH workflow created via one CLI call; renders in HubSpot canvas at `/workflows/{portal}/platform/flow/{migrationStatus.flowId}/edit` as a full multi-node canvas. |
|
|
252
|
+
| List / get / delete v3 workflow | `hscli workflows v3 list|get|delete` | ✅ | Full CRUD via `/automation/v3/workflows/*`. |
|
|
253
|
+
| Enroll / unenroll contact | `hscli workflows v3 enroll|unenroll <workflowId> <email>` | ✅ | `/automation/v3/workflows/{id}/enrollments/contacts/{email}`. |
|
|
254
|
+
| Get contact's current enrollments | `hscli workflows v3 enrollments <email>` | ✅ | `/automation/v3/contacts/{email}/workflowEnrollments`. |
|
|
255
|
+
| Enrollment criteria (`segmentCriteria` list filters) | v3 payload `segmentCriteria` field | ✅ | Standard contact-list filter shape (see HubSpot Contact Lists API). |
|
|
256
|
+
| Goals (`goalCriteria`) | v3 payload `goalCriteria` field | ✅ | Same list-filter shape as enrollment. |
|
|
257
|
+
| Create v4 flow (metadata + enrollment trigger, no actions) | `hscli workflows flows create` | ✅ | `type: "CONTACT_FLOW", flowType: "WORKFLOW"` required. |
|
|
258
|
+
| `LIST_BASED` enrollment criteria on v4 | `enrollmentCriteria.listFilterBranch` | ✅ | Works with property filters (IS_ANY_OF, IS_EQUAL_TO, etc.). |
|
|
259
|
+
| List / get / update v4 flow metadata | `hscli workflows flows list|get|update` | ✅ | |
|
|
260
|
+
| **Populate `actions[]` on v4** | POST / PATCH `/automation/v4/flows` | ❌ | **Re-verified.** POST with `actions:[...]` → 500. PATCH → 405. Action schema is internal-only. **Workaround: create via v3 instead** — the same workflow surfaces on v4 (`migrationStatus.flowId`) with all actions intact. |
|
|
261
|
+
| **Enable / disable a v4 flow** | `hscli workflows flows enable|disable <flowId>` | ✅ | `PUT /automation/v4/flows/{id}` with full flow body including `revisionId` and `isEnabled`. Verified live 2026-04-23. PATCH returns 405 (why we missed it first time) — PUT is the correct verb. |
|
|
262
|
+
| **Resolve v3↔v4 workflow id pair** | `hscli workflows id-map <idV3OrV4>` | ✅ | No dedicated endpoint; wrapper reads `migrationStatus.flowId` / `migrationStatus.workflowId` from the v3 or v4 GET response. Useful for migration tooling + when you need to jump from one API to the other. |
|
|
263
|
+
| Re-enroll contacts | `shouldReEnroll: true` in v4 flow; `allowContactToTriggerMultipleTimes` in v3 | ✅ | |
|
|
264
|
+
|
|
265
|
+
#### v3 action catalog (what you can actually ship)
|
|
266
|
+
|
|
267
|
+
All supported `type` values on v3 `actions[]`:
|
|
268
|
+
|
|
269
|
+
`DELAY` · `EMAIL` (send marketing email by `emailContentId`) · `SET_CONTACT_PROPERTY` · `SET_COMPANY_PROPERTY` · `COPY_PROPERTY` · `COPY_COMPANY_PROPERTY` · `ADD_SUBTRACT_PROPERTY` · `BRANCH` (with `acceptActions`/`rejectActions`) · `WEBHOOK` · `UPDATE_LIST` (add/remove static list) · `TASK` · `TICKET` · `DEAL` · `NOTIFICATION` · `SMS_NOTIFICATION` · `LEAD_ASSIGNMENT` · `WORKFLOW_ENROLLMENT` · `CREATE_SFDC_TASK` · `UPDATE_EMAIL_SUBSCRIPTION` · `SET_SALESFORCE_CAMPAIGN_MEMBERSHIP`
|
|
270
|
+
|
|
271
|
+
BRANCH example:
|
|
272
|
+
|
|
273
|
+
```json
|
|
274
|
+
{"type":"BRANCH",
|
|
275
|
+
"filters":[[{"operator":"EQ","property":"industry","value":"COMPUTER_SOFTWARE","type":"string"}]],
|
|
276
|
+
"acceptActions":[{"type":"SET_CONTACT_PROPERTY","propertyName":"hs_lead_status","newValue":"CONNECTED"}],
|
|
277
|
+
"rejectActions":[{"type":"SET_CONTACT_PROPERTY","propertyName":"hs_lead_status","newValue":"ATTEMPTED_TO_CONTACT"}]}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Sequences
|
|
281
|
+
|
|
282
|
+
- `hscli sales sequences` ✅ (see §3)
|
|
283
|
+
|
|
284
|
+
### Custom workflow actions (app-dev)
|
|
285
|
+
|
|
286
|
+
- `hscli automation actions` — define code blocks that surface in other portals' workflow canvases ✅
|
|
287
|
+
|
|
288
|
+
### Scoring
|
|
289
|
+
|
|
290
|
+
- Score properties: `hscli crm properties create --data '{"type":"number", "hubspotDefined":false ...}'` ✅
|
|
291
|
+
- Score-formula / equation configuration ❌ — UI-only (no public endpoint).
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## 6. CMS (Content Hub)
|
|
296
|
+
|
|
297
|
+
### Website pages
|
|
298
|
+
|
|
299
|
+
- `hscli cms site-pages create|get|list|update` ✅
|
|
300
|
+
- Templates, layoutSections, widgets ✅
|
|
301
|
+
|
|
302
|
+
### Landing pages
|
|
303
|
+
|
|
304
|
+
- `hscli cms landing-pages + hscli marketing landing-pages` ✅
|
|
305
|
+
|
|
306
|
+
### Blog
|
|
307
|
+
|
|
308
|
+
- `hscli cms blog-posts` + `blog-authors|blog-tags|blog-settings` ✅
|
|
309
|
+
|
|
310
|
+
### Redirects
|
|
311
|
+
|
|
312
|
+
- `hscli cms redirects create|list|update|delete` ✅
|
|
313
|
+
|
|
314
|
+
### Domains
|
|
315
|
+
|
|
316
|
+
- Read: `hscli cms domains list|get` ✅ (verified)
|
|
317
|
+
- Add new domain | ❌ | Verified 405 on `POST /cms/v3/domains`. Domain connection + TLS provisioning is UI-only. |
|
|
318
|
+
|
|
319
|
+
### HubDB (relational content tables)
|
|
320
|
+
|
|
321
|
+
- `hscli cms hubdb create|list|get|rows|delete` ✅
|
|
322
|
+
- **Export**: `hscli cms hubdb export <tableId> --format CSV|XLSX|XLS [--output <path>]` ✅ — returns file content inline or writes to disk.
|
|
323
|
+
- Row CRUD + schema ✅
|
|
324
|
+
- **Import** (CSV/XLSX upload) | ✅ | `hscli cms hubdb import <tableId> --file <path> --config '{"format":"CSV","columnMappings":[…]}'`. Real multipart; transport verified. CSV-specific imports require a Content-Hub plan tier that supports them (API returns "CSV imports are not supported" on incompatible portals — XLSX works broadly). |
|
|
325
|
+
|
|
326
|
+
### Source code + module library
|
|
327
|
+
|
|
328
|
+
- `hscli cms source-code get|metadata|extract` ✅
|
|
329
|
+
- **Module schema discovery**: `/cms/v3/source-code/published/content/@hubspot/{module}.module/fields.json` returns the full field schema for any HubSpot-built module. See §9 for the inventory.
|
|
330
|
+
- **Upload custom modules/templates** | ✅ | `hscli cms source-code upload <env> <destPath> --file <local>`. Uses real `multipart/form-data` with a FormData-generated boundary. Verified live 2026-04-23. Also: `hscli cms upload <destPath> --file <local>` targets the legacy `content/filemapper/v1/upload/*` endpoint (what `hs upload` actually uses under the hood). |
|
|
331
|
+
- Path validator rejects `/` in `@hubspot/button.module/fields.json` — use `hscli api request` as workaround until fix lands.
|
|
332
|
+
|
|
333
|
+
### Site search
|
|
334
|
+
|
|
335
|
+
- `hscli site-search search|indexed` ✅
|
|
336
|
+
|
|
337
|
+
### Memberships
|
|
338
|
+
|
|
339
|
+
- Via `hscli crm custom-objects records` on the membership object ⚠️ — partial.
|
|
340
|
+
- Member-facing UI (registration, gated content) ❌ — CMS-rendering-only.
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## 7. Developer / Operations Hub
|
|
345
|
+
|
|
346
|
+
### Webhooks
|
|
347
|
+
|
|
348
|
+
- `hscli webhooks list|subscribe|delete` ✅
|
|
349
|
+
- Requires developer-app context 🔒
|
|
350
|
+
|
|
351
|
+
### Custom behavioral events
|
|
352
|
+
|
|
353
|
+
- `hscli events send|list|definitions` ✅
|
|
354
|
+
|
|
355
|
+
### Feature flags (app-dev)
|
|
356
|
+
|
|
357
|
+
- `hscli feature-flags list|get|create|update|delete` ✅
|
|
358
|
+
|
|
359
|
+
### Integrations metadata
|
|
360
|
+
|
|
361
|
+
- `hscli integrations me|timeline` ✅
|
|
362
|
+
- `hscli integrators timeline-event-templates` ✅
|
|
363
|
+
|
|
364
|
+
### Extensions (calling, videoconferencing, accounting)
|
|
365
|
+
|
|
366
|
+
- `hscli extensions calling|videoconferencing|accounting` ✅
|
|
367
|
+
|
|
368
|
+
### Media Bridge (video/media partners)
|
|
369
|
+
|
|
370
|
+
- `hscli media-bridge properties|schemas|settings|events` ✅
|
|
371
|
+
|
|
372
|
+
### Visitor identification (chat widget)
|
|
373
|
+
|
|
374
|
+
- `hscli visitor-identification token` ✅
|
|
375
|
+
|
|
376
|
+
### Exports
|
|
377
|
+
|
|
378
|
+
- `hscli exports create|list|get|status` ✅
|
|
379
|
+
|
|
380
|
+
### Timeline
|
|
381
|
+
|
|
382
|
+
- `hscli timeline event-templates|events` ✅
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## 8. Admin / Security
|
|
387
|
+
|
|
388
|
+
### Users + teams
|
|
389
|
+
|
|
390
|
+
- `hscli settings users list|create|update|delete` ✅
|
|
391
|
+
- `hscli settings teams list|create|update|delete` ✅
|
|
392
|
+
- Permission-set / role authoring ⚠️ — partial; role templates are UI-only.
|
|
393
|
+
|
|
394
|
+
### Business units
|
|
395
|
+
|
|
396
|
+
- `hscli settings business-units list|create|update|delete` 🔒 — Marketing Hub Enterprise gated. Verified 404 on `/business-units/v3/` + `/settings/v3/business-units` on this (non-Enterprise) portal.
|
|
397
|
+
|
|
398
|
+
### Multi-currency
|
|
399
|
+
|
|
400
|
+
- `hscli settings currencies list|create|update|delete` ✅
|
|
401
|
+
|
|
402
|
+
### Audit logs
|
|
403
|
+
|
|
404
|
+
- `hscli account audit-logs` — account-wide (Enterprise 🔒)
|
|
405
|
+
- `hscli cms audit-logs` — CMS-content audit log ✅
|
|
406
|
+
- `hscli audit` — hscli-side operational audit of every request ✅
|
|
407
|
+
|
|
408
|
+
### GDPR
|
|
409
|
+
|
|
410
|
+
- `hscli settings gdpr delete --email contact@example.com` ✅
|
|
411
|
+
|
|
412
|
+
### Private apps
|
|
413
|
+
|
|
414
|
+
- `hscli account private-apps list` ✅
|
|
415
|
+
- `hscli account api-usage` ✅
|
|
416
|
+
|
|
417
|
+
### Brand kits
|
|
418
|
+
|
|
419
|
+
- ❌ — Verified 404 on `/crm/v3/objects/brand_kits`, `/business-units/v3/business-units`, `/settings/v3/brand-kits`. No public endpoint.
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## 9. HubSpot module library (CMS drag-and-drop)
|
|
424
|
+
|
|
425
|
+
### Schema discovery endpoint
|
|
426
|
+
|
|
427
|
+
```bash
|
|
428
|
+
hscli api request \
|
|
429
|
+
--path "/cms/v3/source-code/published/content/@hubspot/{module}.module/fields.json"
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
Returns every field: `name`, `type`, `default`, `children`, `choices`. That's the surface an agent needs to compose a module the way a UI user drags + fills it in.
|
|
433
|
+
|
|
434
|
+
### 55 modules verified accessible on this portal
|
|
435
|
+
|
|
436
|
+
**Universal / web-page:**
|
|
437
|
+
`rich_text`, `text`, `header`, `section_header`, `button`, `cta`,
|
|
438
|
+
`divider`, `horizontal_spacer`, `form`, `icon`, `linked_image`,
|
|
439
|
+
`image_grid`, `gallery`, `image_slider_gallery`, `logo`, `logo_grid`,
|
|
440
|
+
`video`, `menu`, `simple_menu`, `language_switcher`, `social_sharing`,
|
|
441
|
+
`social_follow`, `page_footer`, `meetings`, `payments`, `product`,
|
|
442
|
+
`whatsapp_link`
|
|
443
|
+
|
|
444
|
+
**Blog:** `blog_content`, `blog_subscribe`, `blog_comments`,
|
|
445
|
+
`post_filter`, `rss_listing`
|
|
446
|
+
|
|
447
|
+
**System:** `search_input`, `search_results`, `password_prompt`,
|
|
448
|
+
`membership_social_logins`
|
|
449
|
+
|
|
450
|
+
**Email-specific:** `email_header`, `email_cta`, `email_text`,
|
|
451
|
+
`email_section_header`, `email_linked_image`, `email_logo`,
|
|
452
|
+
`email_post_filter`, `email_post_listing`, `email_social_sharing`,
|
|
453
|
+
`email_subscriptions`, `email_subscriptions_confirmation`,
|
|
454
|
+
`email_simple_subscription`, `email_body`, `raw_html_email`,
|
|
455
|
+
`email_can_spam`
|
|
456
|
+
|
|
457
|
+
**Legacy quote templates:** `quote_download`, `quote_payment`,
|
|
458
|
+
`quote_signature`, `line_items`
|
|
459
|
+
|
|
460
|
+
### 13 modules listed in HubSpot docs but not on this portal
|
|
461
|
+
|
|
462
|
+
Deprecated/renamed or portal-specific-gated:
|
|
463
|
+
`image`, `blog_posts`, `post_listing`, `email_footer` (resolves
|
|
464
|
+
via widget reference even though fields.json 404s), `image_email`,
|
|
465
|
+
`video_email`, `one_line_of_text`, `view_as_web_page`, `whitespace`,
|
|
466
|
+
`spacer`, `follow_me`, `rss_email`, `product_markdown`.
|
|
467
|
+
|
|
468
|
+
### Render rules (what actually appears where)
|
|
469
|
+
|
|
470
|
+
| Module | Email canvas | Landing/site page | Blog | Notes |
|
|
471
|
+
|---|---|---|---|---|
|
|
472
|
+
| `rich_text` | ✅ | ✅ | ✅ | Universal. Field: `html` (richtext). |
|
|
473
|
+
| `email_footer` | ✅ | — | — | Required CAN-SPAM footer. `email_can_spam` alias resolves to same. |
|
|
474
|
+
| `preview_text` widget | ✅ | — | — | Widget-level, not a module. |
|
|
475
|
+
| `button` | ❌ | ✅ | ✅ | Page-only. In emails, use inline bulletproof `<table>` in rich_text. |
|
|
476
|
+
| `divider` | ❌ | ✅ | ✅ | Page-only. In emails, use `<hr>`. |
|
|
477
|
+
| `header` | ❌ | ✅ | ✅ | Page-only. In emails, wrap `<h1>` in rich_text. |
|
|
478
|
+
| `linked_image` / `email_linked_image` | ⚠️ | ✅ | ✅ | In emails: renders only in the webversion preview URL, not the editor iframe (cross-origin image sandbox). The sent email does render the image. |
|
|
479
|
+
| `form` | ❌ (emails can't carry interactive forms by HubSpot policy) | ✅ | ✅ | |
|
|
480
|
+
|
|
481
|
+
---
|
|
482
|
+
|
|
483
|
+
## 10. What we can't do (verified blocks)
|
|
484
|
+
|
|
485
|
+
Every row has been probed on 2026-04-23. Full evidence in Appendix C.
|
|
486
|
+
|
|
487
|
+
| Want | Root cause | Evidence |
|
|
488
|
+
|---|---|---|
|
|
489
|
+
| Populate `actions[]` on **v4** workflow | v4 schema internal-only — POST 500 / PATCH 405. **Workaround lives:** use `hscli workflows v3 create` (legacy v3 API accepts full `actions[]`; same workflow appears in v4 + UI canvas). Action creation is NOT blocked by HubSpot — wrong endpoint was being used. |
|
|
490
|
+
| Transition AUTOMATED_DRAFT → AUTOMATED via PATCH | No state-transition via PATCH | PATCH → 400; PUT → 405; use `/publish` endpoint via `hscli marketing emails publish` |
|
|
491
|
+
| Create email in `AUTOMATED` state directly | Explicit API rejection | Error message: *"Creating an email in the published state AUTOMATED is not allowed. Consider using AUTOMATED_DRAFT."* |
|
|
492
|
+
| Transition AUTOMATED_DRAFT → AUTOMATED via PATCH/PUT | Must use `/publish` | PATCH → 400; PUT → 405 |
|
|
493
|
+
| ~~Clone v3 marketing email~~ | UPGRADED 2026-04-23 | Now `hscli marketing emails clone <id>` — endpoint takes id in body, not path. |
|
|
494
|
+
| ~~A/B test / email variant authoring~~ | UPGRADED 2026-04-23 | Now `hscli marketing emails ab-variant --content-id <id> --name 'Variant B'`. |
|
|
495
|
+
| Render body images inside the email editor iframe | Cross-origin iframe sandbox strips external images | Verified across 5 markup variants |
|
|
496
|
+
| Merge-tag chip in stored HTML | Chip is in-edit React overlay only | 5 markup variants tested — none reproduce chip |
|
|
497
|
+
| Connect new domain + TLS | POST to domains is blocked | `POST /cms/v3/domains` → 405 |
|
|
498
|
+
| Chatflows / chatbot CRUD | No public endpoint | `/conversations/v3/chatflows` → 404 |
|
|
499
|
+
| Brand kits | No public endpoint | 404 on 3 candidate paths |
|
|
500
|
+
| SLA policies | No public endpoint | 404 on `/conversations/v3/sla-policies`, 400 on `/crm/v3/objects/sla_policies` |
|
|
501
|
+
| E-signature on quote | No public endpoint | `POST /crm/v3/objects/quotes/{id}/esignature` → 404 |
|
|
502
|
+
| Forecast-category authoring | No public endpoint | 404 on `/crm/v3/forecasts/categories` |
|
|
503
|
+
| Reports v3 API (report authoring) | No public endpoint | 404 on `/reports/v3/reports`, `/reports/v3/report-types`. Analytics DATA is fetchable via `hscli reporting email|content|feedback` + `hscli email-events campaign`; only the UI report-builder is missing. |
|
|
504
|
+
| Personalization token listing | No public endpoint | 404 on `/cms/v3/personalization/tokens` (merge tags still work when typed into HubL) |
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## 11. Items 🚧 hscli-side-blocked (quick wins)
|
|
509
|
+
|
|
510
|
+
These are served by HubSpot but hscli's `INVALID_PATH_SCOPE` guard rejects them:
|
|
511
|
+
|
|
512
|
+
| Endpoint | What it unlocks |
|
|
513
|
+
|---|---|
|
|
514
|
+
| `/feedback/v3/*`, `/feedback/v4/*` | Survey definition + submission CRUD |
|
|
515
|
+
| `/goals/v1/*` | Goal CRUD (legacy API, `/crm/v3/objects/goal_targets` is also available) |
|
|
516
|
+
| `/content/tree`, `/content-folders/*` | Folder-tree listing for design manager |
|
|
517
|
+
|
|
518
|
+
Adding these to hscli's allowlist is a one-line-per-path change in the core HTTP client.
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
## 12. Roadmap — hscli-side polish
|
|
523
|
+
|
|
524
|
+
Not HubSpot blocks — things hscli should add/fix:
|
|
525
|
+
|
|
526
|
+
1. **`cms source-code` path validator** — currently rejects `/`; should accept `@hubspot/*.module/*.json`.
|
|
527
|
+
2. **`cms source-code list-modules`** — iterates the known-module wordlist + returns inventory as JSON.
|
|
528
|
+
3. **`marketing emails upload-image`** — wraps `POST /files/v3/files/import-from-url/async` + status polling; returns final HubFS URL.
|
|
529
|
+
4. **`marketing emails publish <id>`** — surface the `/publish` endpoint as a first-class command (currently only reachable via `api request`).
|
|
530
|
+
5. **`api request --content-type <type>`** — loosen the default JSON Content-Type to allow template uploads.
|
|
531
|
+
6. **Allowlist expansion** — add `/feedback/*`, `/goals/v1/*` paths (see §11).
|
|
532
|
+
7. **MCP tool auto-gen from `fields.json`** — every HubSpot module becomes a typed MCP tool with correct input schema.
|
|
533
|
+
|
|
534
|
+
---
|
|
535
|
+
|
|
536
|
+
## 13. Undocumented endpoints surfaced from HubSpot's open-source repos
|
|
537
|
+
|
|
538
|
+
A GitHub scan of [HubSpot/hubspot-local-dev-lib](https://github.com/HubSpot/hubspot-local-dev-lib), [HubSpot/hubspot-api-nodejs](https://github.com/HubSpot/hubspot-api-nodejs), and the official `hs` CLI revealed API paths HubSpot's own tooling hits that are **not in developers.hubspot.com** navigation. hscli's allowlist now permits these paths (0.8.7+) — whether they return data depends on your token's scope.
|
|
539
|
+
|
|
540
|
+
| Endpoint family | What it's for | Allowlist status | Scope |
|
|
541
|
+
|---|---|---|---|
|
|
542
|
+
| `/apps-dev/external/public/v3/*` | App-install analytics (test-portal installs, install counts, full portal details) | ✅ allowed | Dev-app token |
|
|
543
|
+
| `/apps-hublets/external/static-token/v3` | Static-token app install | ✅ allowed | Dev-app token |
|
|
544
|
+
| `/dfs/v1/*`, `/dfs/deploy/v1/*`, `/dfs/deploy/v3/*`, `/dfs/logging/v1/*`, `/dfs/migrations/v1/*` | Developer File System — projects upload, deploy, logs, migrations (used by `hs project upload`) | ✅ allowed | Dev-app token |
|
|
545
|
+
| `/project-components-external/v3` | New v3 project upload-with-IR (replaces `dfs/v1/projects/upload/{name}` for apps) | ✅ allowed | Dev-app token |
|
|
546
|
+
| `/file-transport/v1/hubfiles/*` | HubFiles custom-object schema upload (used by `hs hubfiles`) | ✅ allowed | Custom-object scopes |
|
|
547
|
+
| `/localdevauth/v1/*` | Local-dev account linking flow | ✅ allowed | Standard |
|
|
548
|
+
| `/content/filemapper/v1/upload/{urlencoded-dest}` | **The endpoint `hs upload` actually uses** (not `/cms/v3/source-code/*`) for theme/template uploads. Multipart with `file` field. | ✅ (under `content` scope) | Standard |
|
|
549
|
+
| `/crm/v3/lists/{listId}/conversion/*` | List conversion schedule/update/cancel (added Sept 2025, not yet in docs) | ✅ (under `crm` scope) | Standard |
|
|
550
|
+
|
|
551
|
+
### Multipart endpoints — ALL UNBLOCKED 0.8.8+
|
|
552
|
+
|
|
553
|
+
`src/core/http.ts` now accepts `RequestOptions.multipart` — a field-name → (string | file) record. Internally it builds a native `FormData` instance and lets Node 20+ `fetch` emit the correct `multipart/form-data; boundary=…` Content-Type (manually setting the header without a boundary was the root cause of our 415s, as also seen in HubSpot's own nodejs SDK).
|
|
554
|
+
|
|
555
|
+
| Endpoint | hscli command | Status |
|
|
556
|
+
|---|---|---|
|
|
557
|
+
| `PUT /cms/v3/source-code/{env}/content/{path}` | `hscli cms source-code upload <env> <destPath> --file <local>` | ✅ verified live |
|
|
558
|
+
| `POST /cms/v3/hubdb/tables/{id}/draft/import` | `hscli cms hubdb import <tableId> --file <path> --config '<json>'` | ✅ transport verified; CSV-import itself tier-gated |
|
|
559
|
+
| `POST /content/filemapper/v1/upload/{dest}` | `hscli cms upload <destPath> --file <local>` | ✅ verified live (mirrors `hs upload`) |
|
|
560
|
+
| `POST /file-transport/v1/hubfiles/object-schemas` | `hscli api request --path /file-transport/v1/hubfiles/object-schemas --method POST --file file=<local>` | ⚠️ reachable (raw passthrough); wrapper command pending |
|
|
561
|
+
| `POST /project-components-external/v3/upload/new-api` | `hscli api request --path /project-components-external/v3/upload/new-api --method POST --file projectFilesZip=<zip> --part platformVersion=2026.03 --part uploadRequest='<json>'` | ⚠️ reachable via raw passthrough |
|
|
562
|
+
|
|
563
|
+
Also: `hscli api request` now takes `--file <field>=<path>[:<mime>]` (repeatable) and `--part <field>=<value>` (repeatable). So any untyped multipart endpoint is reachable without a dedicated command.
|
|
564
|
+
|
|
565
|
+
### Additional endpoints documented only in HubSpot's own SDK
|
|
566
|
+
|
|
567
|
+
From [HubSpot/hubspot-api-nodejs codegen](https://github.com/HubSpot/hubspot-api-nodejs):
|
|
568
|
+
|
|
569
|
+
| Endpoint | CLI status |
|
|
570
|
+
|---|---|
|
|
571
|
+
| `POST /marketing/v3/emails/{id}/revisions/{rev}/restore-to-draft` | ✅ `hscli marketing emails revision-restore <id> <rev>` |
|
|
572
|
+
| `POST /marketing/v3/emails/{id}/unpublish` | ✅ `hscli marketing emails unpublish <id>` |
|
|
573
|
+
| `POST /marketing/v3/emails/{id}/draft/reset` | ✅ `hscli marketing emails draft-reset <id>` |
|
|
574
|
+
| `POST /cms/v3/pages/site-pages/ab-test/rerun` (needs `AbTestRerunRequestVNext`) | ✅ (existing `hscli cms site-pages ab-test rerun`) |
|
|
575
|
+
| `POST /crm/v3/lists/{listId}/conversion/{schedule|update|cancel}` (added Sept 2025) | ⚠️ Reachable via `hscli api request`; no first-class command yet |
|
|
576
|
+
|
|
577
|
+
---
|
|
578
|
+
|
|
579
|
+
## Appendix A — Single-command probes
|
|
580
|
+
|
|
581
|
+
```bash
|
|
582
|
+
# Every module schema accessible on your portal
|
|
583
|
+
for m in $(cat docs/module-names.txt); do
|
|
584
|
+
hscli api request \
|
|
585
|
+
--path "/cms/v3/source-code/published/content/@hubspot/${m}.module/fields.json" \
|
|
586
|
+
--json | jq -r --arg m "$m" 'if .ok then "✓ \($m)" else "✗ \($m)" end'
|
|
587
|
+
done
|
|
588
|
+
|
|
589
|
+
# Probe all write capabilities on this profile
|
|
590
|
+
hscli doctor --check writes
|
|
591
|
+
|
|
592
|
+
# Every request hscli makes, audited to JSONL
|
|
593
|
+
hscli --telemetry-file ./audit.jsonl <any-command>
|
|
594
|
+
|
|
595
|
+
# Replay a traced session
|
|
596
|
+
hscli trace replay --file ./audit.jsonl --dry-run
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
## Appendix B — MCP exposure
|
|
600
|
+
|
|
601
|
+
Every CLI command maps to an MCP tool via:
|
|
602
|
+
|
|
603
|
+
```bash
|
|
604
|
+
hscli mcp serve # stdio or --transport sse
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
1,180+ typed tools covering this capability library. See [MCP.md](MCP.md).
|
|
608
|
+
|
|
609
|
+
### HubSpot drag-and-drop module library exposed as 3 MCP tools (0.8.8+)
|
|
610
|
+
|
|
611
|
+
Every `@hubspot/*` module's `fields.json` schema is surfaced on demand — not pre-generated as 55 separate tools. Agents get the same "browse → describe → fill" flow a UI user has.
|
|
612
|
+
|
|
613
|
+
| Tool | What it does |
|
|
614
|
+
|---|---|
|
|
615
|
+
| `hubspot_module_list` | Enumerate all built-in modules accessible on the caller's portal. Optional `schemas: true` returns full field definitions inline. |
|
|
616
|
+
| `hubspot_module_describe` | Fetch one module's `fields.json` schema: names, types (text, richtext, number, boolean, color, choice, group, image, link, ...), required flags, defaults, choices, nested children. Exactly what a drag-drop user sees when they click a module. |
|
|
617
|
+
| `hubspot_module_compose` | Given a module path + field values, returns a widget body ready to embed in `content.widgets[widgetId]`. Validates values against the schema first — rejects unknown fields and type mismatches with a clear error. No more hand-shaping widget bodies. |
|
|
618
|
+
|
|
619
|
+
Example (agent-driven): "Create a welcome email with a hero image + CTA button" becomes
|
|
620
|
+
1. `hubspot_module_describe @hubspot/linked_image` → see what fields the image module takes
|
|
621
|
+
2. `hubspot_module_describe @hubspot/button` → see button field shape
|
|
622
|
+
3. `hubspot_module_compose` × 2 → get validated widget bodies
|
|
623
|
+
4. `marketing_emails_create` → paste the composed widgets under `content.widgets` + reference from `flexAreas`
|
|
624
|
+
|
|
625
|
+
This is the hscli-side implementation of the "agent does what a drag-drop human does" value proposition, backed by HubSpot's own module schemas.
|
|
626
|
+
|
|
627
|
+
## Appendix C — Verification log
|
|
628
|
+
|
|
629
|
+
All status claims in this doc were probed on 2026-04-23 against portal
|
|
630
|
+
147975758 (EU1). Raw probe logs:
|
|
631
|
+
|
|
632
|
+
- **Tier B retest** (`/tmp/verify-results.txt` during prep): clone/publish/source-code-create/workflow-enable — see exact HTTP codes per entry in §10.
|
|
633
|
+
- **Tier C first-probe**: SLA, feedback, playbooks, chatflows, forecasts, brand kits, domains, e-signature, reports, personalization tokens — each entry in §10 cites the exact URL + response.
|
|
634
|
+
- **Deep-dive followup** (`/tmp/followup.sh`): retried 415 / 500 / validation errors with cleaner payloads — uncovered that v3 email `/publish` is real (validation-gated), playbook schema is accessible, source-code uploads return 415 (fixable Content-Type issue).
|
|
635
|
+
|
|
636
|
+
No ❌ entry in this library is "claimed from priors." Every block was
|
|
637
|
+
reproduced. Re-run probes before trusting any entry older than the
|
|
638
|
+
date above.
|