@revfleet/hscli 0.8.6 → 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.
Files changed (77) hide show
  1. package/CHANGELOG.md +240 -0
  2. package/CONTRIBUTING.md +120 -0
  3. package/README.md +14 -6
  4. package/brand/readme-hero.svg +25 -0
  5. package/dist/cli.js +10 -0
  6. package/dist/cli.js.map +1 -1
  7. package/dist/commands/account/index.js +5 -6
  8. package/dist/commands/account/index.js.map +1 -1
  9. package/dist/commands/api/index.js +43 -3
  10. package/dist/commands/api/index.js.map +1 -1
  11. package/dist/commands/auth/index.js +32 -6
  12. package/dist/commands/auth/index.js.map +1 -1
  13. package/dist/commands/cms/hubdb.js +64 -1
  14. package/dist/commands/cms/hubdb.js.map +1 -1
  15. package/dist/commands/cms/index.js +27 -0
  16. package/dist/commands/cms/index.js.map +1 -1
  17. package/dist/commands/cms/source-code.js +21 -0
  18. package/dist/commands/cms/source-code.js.map +1 -1
  19. package/dist/commands/communication-preferences/index.js +11 -12
  20. package/dist/commands/communication-preferences/index.js.map +1 -1
  21. package/dist/commands/crm/shared.d.ts +1 -0
  22. package/dist/commands/crm/shared.js +3 -4
  23. package/dist/commands/crm/shared.js.map +1 -1
  24. package/dist/commands/events/index.js +7 -8
  25. package/dist/commands/events/index.js.map +1 -1
  26. package/dist/commands/marketing/index.js +58 -3
  27. package/dist/commands/marketing/index.js.map +1 -1
  28. package/dist/commands/settings/index.js +12 -13
  29. package/dist/commands/settings/index.js.map +1 -1
  30. package/dist/commands/workflows/index.js +43 -0
  31. package/dist/commands/workflows/index.js.map +1 -1
  32. package/dist/core/http.d.ts +27 -0
  33. package/dist/core/http.js +102 -18
  34. package/dist/core/http.js.map +1 -1
  35. package/dist/core/plugins.d.ts +5 -2
  36. package/dist/core/plugins.js +18 -1
  37. package/dist/core/plugins.js.map +1 -1
  38. package/dist/core/telemetry-context.d.ts +13 -0
  39. package/dist/core/telemetry-context.js +30 -0
  40. package/dist/core/telemetry-context.js.map +1 -0
  41. package/dist/mcp/hubspot-modules.d.ts +30 -0
  42. package/dist/mcp/hubspot-modules.js +305 -0
  43. package/dist/mcp/hubspot-modules.js.map +1 -0
  44. package/dist/mcp/server.d.ts +2 -0
  45. package/dist/mcp/server.js +30 -26
  46. package/dist/mcp/server.js.map +1 -1
  47. package/docs/ARCHITECTURE.md +39 -0
  48. package/docs/CAPABILITY_LIBRARY.md +638 -0
  49. package/docs/CMS_SETUP.md +349 -0
  50. package/docs/COMMAND_COMPATIBILITY.md +24 -0
  51. package/docs/COMMAND_TREE.md +183 -0
  52. package/docs/COMMERCE_SETUP.md +400 -0
  53. package/docs/COMPARISON.md +146 -0
  54. package/docs/COOKBOOK.md +800 -0
  55. package/docs/INTEGRATIONS_NOTIFICATIONS_SETUP.md +352 -0
  56. package/docs/MARKETING_SETUP.md +503 -0
  57. package/docs/MCP.md +171 -0
  58. package/docs/OPERATIONAL_PLAYBOOKS.md +322 -0
  59. package/docs/OPERATIONS_SETUP.md +362 -0
  60. package/docs/PLUGIN_GUIDE.md +158 -0
  61. package/docs/POLICY_EXAMPLE.json +57 -0
  62. package/docs/PORTAL_SETUP.md +683 -0
  63. package/docs/PUBLISHING.md +154 -0
  64. package/docs/RELEASE_GOVERNANCE.md +34 -0
  65. package/docs/REPORTING_SETUP.md +310 -0
  66. package/docs/ROADMAP-DATE-BASED-API.md +103 -0
  67. package/docs/ROADMAP_PHASE1_TO_3.md +96 -0
  68. package/docs/SAFETY_MODEL.md +37 -0
  69. package/docs/SALES_SETUP.md +369 -0
  70. package/docs/SERVICE_SETUP.md +403 -0
  71. package/docs/TESTING_PLAN.md +89 -0
  72. package/docs/TIERS.md +320 -0
  73. package/docs/TUTORIALS/audit-portal-writes.md +150 -0
  74. package/docs/TUTORIALS/secure-agent-writes.md +177 -0
  75. package/docs/TUTORIALS/trace-replay-repro.md +147 -0
  76. package/docs/WHY_HOW_WHAT.md +81 -0
  77. package/package.json +7 -2
@@ -0,0 +1,322 @@
1
+ # Operational Playbooks
2
+
3
+ Incident response procedures for hscli operations.
4
+
5
+ ---
6
+
7
+ ## 1. Token Compromise
8
+
9
+ **Severity:** Critical
10
+
11
+ ### Symptoms
12
+ - Unexpected API activity on HubSpot portal (unknown writes, bulk deletes)
13
+ - Token appears in logs, error messages, or third-party systems
14
+ - HubSpot reports suspicious API usage via email
15
+
16
+ ### Diagnosis
17
+ ```bash
18
+ # Check recent telemetry for unusual activity
19
+ cat ~/.revfleet/telemetry.jsonl | grep '"method":"DELETE"' | tail -20
20
+
21
+ # Check which profiles exist
22
+ hscli auth profiles
23
+
24
+ # Inspect token scopes
25
+ hscli auth token-info --profile <profile>
26
+ ```
27
+
28
+ ### Immediate Response
29
+ 1. **Revoke the token** in HubSpot portal: Settings > Integrations > Private Apps > Revoke
30
+ 2. **Rotate credentials**: generate a new private app token with minimum necessary scopes
31
+ 3. **If vault was encrypted**: re-encrypt with a new passphrase
32
+ ```bash
33
+ export HSCLI_VAULT_PASSPHRASE="new-passphrase"
34
+ hscli auth decrypt # with old passphrase
35
+ hscli auth login --token "pat-xxx-new-token"
36
+ hscli auth encrypt # with new passphrase
37
+ ```
38
+ 4. **Audit recent actions** via HubSpot audit log (Settings > Account > Audit Logs)
39
+
40
+ ### Recovery
41
+ ```bash
42
+ # Login with new token
43
+ hscli auth login --token "pat-eu1-new-token" --profile production
44
+
45
+ # Verify connectivity
46
+ hscli crm contacts list --limit 1 --profile production
47
+
48
+ # Lock to read-only while investigating
49
+ hscli auth set-mode production read-only
50
+ ```
51
+
52
+ ### Prevention
53
+ - Always use encrypted vault (`hscli auth encrypt`)
54
+ - Never pass tokens as CLI arguments in shared environments — use `--token-stdin`
55
+ - Set profiles to `read-only` by default; switch to `read-write` only when needed
56
+ - Review `HSCLI_TELEMETRY_FILE` logs regularly
57
+
58
+ ---
59
+
60
+ ## 2. Rate Limit Exhaustion
61
+
62
+ **Severity:** High
63
+
64
+ ### Symptoms
65
+ - `RATE_LIMIT_DAILY_EXHAUSTED` error
66
+ - `HTTP_RETRY_EXHAUSTED` after 429 responses
67
+ - Increasingly long pauses between API calls (pacing)
68
+
69
+ ### Diagnosis
70
+ ```bash
71
+ # Check telemetry for 429 responses
72
+ cat ~/.revfleet/telemetry.jsonl | grep '"status":429' | wc -l
73
+
74
+ # Check current rate limit state via a simple request
75
+ hscli crm contacts list --limit 1 --telemetry-file /tmp/ratelimit-check.jsonl
76
+ cat /tmp/ratelimit-check.jsonl
77
+ ```
78
+
79
+ ### Mitigation
80
+ 1. **Stop batch operations** immediately
81
+ 2. **Wait for reset**: daily quota resets at UTC midnight
82
+ 3. **Reduce batch sizes**: use `--limit 10` instead of `--limit 100`
83
+ 4. **Space out requests**: add delays between sync pull runs
84
+
85
+ ```bash
86
+ # Small incremental sync instead of bulk
87
+ hscli crm sync pull contacts --limit 10 --max-pages 1
88
+
89
+ # Check if quota has recovered
90
+ hscli crm contacts list --limit 1
91
+ ```
92
+
93
+ ### Prevention
94
+ - Use `--telemetry-file` to monitor API usage patterns
95
+ - Run batch operations during off-peak hours
96
+ - Set `--max-pages` limits on sync operations
97
+ - Use `--limit` to control page sizes
98
+
99
+ ---
100
+
101
+ ## 3. Vault Passphrase Loss
102
+
103
+ **Severity:** High
104
+
105
+ ### Symptoms
106
+ - `VAULT_PASSPHRASE_REQUIRED` error on any command
107
+ - Cannot read or write auth profiles
108
+
109
+ ### Diagnosis
110
+ ```bash
111
+ # Confirm vault is encrypted
112
+ ls -la ~/.revfleet/auth.enc
113
+
114
+ # Check if plain auth.json exists as backup
115
+ ls -la ~/.revfleet/auth.json
116
+ ```
117
+
118
+ ### Recovery
119
+
120
+ **If `auth.json` backup exists:**
121
+ ```bash
122
+ # Remove encrypted vault, use plain file
123
+ rm ~/.revfleet/auth.enc
124
+ # Verify access
125
+ hscli auth profiles
126
+ # Re-encrypt with new passphrase
127
+ export HSCLI_VAULT_PASSPHRASE="new-passphrase"
128
+ hscli auth encrypt
129
+ ```
130
+
131
+ **If no backup exists:**
132
+ ```bash
133
+ # Remove encrypted vault
134
+ rm ~/.revfleet/auth.enc
135
+ # Re-authenticate with each profile
136
+ hscli auth login --token "pat-xxx-token" --profile default
137
+ hscli auth login --token "pat-xxx-other" --profile staging
138
+ # Re-encrypt
139
+ export HSCLI_VAULT_PASSPHRASE="new-passphrase"
140
+ hscli auth encrypt
141
+ ```
142
+
143
+ ### Prevention
144
+ - Store vault passphrase in a password manager (1Password, Bitwarden)
145
+ - For CI: store in encrypted secrets (GitHub Secrets, Vault)
146
+ - Keep a secure backup of `auth.json` before encrypting
147
+
148
+ ---
149
+
150
+ ## 4. API Contract Drift
151
+
152
+ **Severity:** Medium
153
+
154
+ ### Symptoms
155
+ - Console warnings: `Schema validation warning: ...`
156
+ - With `HSCLI_STRICT_SCHEMAS=1`: `SCHEMA_VALIDATION_ERROR` errors
157
+ - Unexpected response shapes or missing fields
158
+
159
+ ### Diagnosis
160
+ ```bash
161
+ # Enable strict mode to surface all validation failures
162
+ HSCLI_STRICT_SCHEMAS=1 hscli crm contacts list --limit 1
163
+
164
+ # Check HubSpot API changelog
165
+ # https://developers.hubspot.com/changelog
166
+
167
+ # Test specific endpoints
168
+ hscli api request --method GET --path "/crm/v3/objects/contacts?limit=1" --json
169
+ ```
170
+
171
+ ### Mitigation
172
+ 1. **Non-strict mode (default)**: warnings are logged but commands continue working
173
+ 2. **Update schemas**: modify `src/core/schemas.ts` to match new API shapes
174
+ 3. **Use passthrough**: all schemas use `.passthrough()` so extra fields are preserved
175
+
176
+ ### Escalation
177
+ - File an issue with the exact response shape and expected schema
178
+ - Check HubSpot developer forum for known API changes
179
+ - Temporarily disable strict mode: `unset HSCLI_STRICT_SCHEMAS`
180
+
181
+ ---
182
+
183
+ ## 5. Capability/Tier Mismatch
184
+
185
+ **Severity:** Medium
186
+
187
+ ### Symptoms
188
+ - `ENDPOINT_NOT_AVAILABLE` error
189
+ - `CAPABILITY_UNSUPPORTED` error
190
+ - `CAPABILITY_SCOPE_MISSING` in strict mode
191
+
192
+ ### Diagnosis
193
+ ```bash
194
+ # Check what capabilities are available
195
+ hscli doctor capabilities --refresh --json
196
+
197
+ # Check token scopes
198
+ hscli auth token-info
199
+
200
+ # Test the specific endpoint directly
201
+ hscli api request --method GET --path "/marketing/v3/emails?limit=1"
202
+ ```
203
+
204
+ ### Resolution
205
+ 1. **Missing scopes**: create a new private app with required scopes in HubSpot
206
+ 2. **Tier limitation**: upgrade HubSpot plan (e.g., Marketing Hub for email API)
207
+ 3. **Use fallback**: the error message includes a fallback command
208
+ 4. **Clear stale cache**:
209
+ ```bash
210
+ rm ~/.revfleet/capabilities.json
211
+ hscli doctor capabilities --refresh
212
+ ```
213
+
214
+ ---
215
+
216
+ ## 6. EU1/Hublet Routing Errors
217
+
218
+ **Severity:** High
219
+
220
+ ### Symptoms
221
+ - 401/403 errors on EU1 portal despite valid token
222
+ - Data from wrong portal (NA data instead of EU)
223
+ - `doctor hublet-check` reports mismatches
224
+
225
+ ### Diagnosis
226
+ ```bash
227
+ # Run hublet consistency check
228
+ hscli doctor hublet-check --json
229
+
230
+ # Verify profile configuration
231
+ hscli auth profile-show --profile default
232
+ ```
233
+
234
+ ### Resolution
235
+ ```bash
236
+ # Re-login — hublet auto-detected from token prefix
237
+ hscli auth login --token "pat-eu1-your-token"
238
+
239
+ # Verify routing
240
+ hscli doctor hublet-check
241
+ # Should show: hublet=eu1, apiDomain=api-eu1.hubapi.com
242
+
243
+ # If using HubSpot's official @hubspot/cli too, ensure its ~/.hscli.config.yml has env: eu1
244
+ ```
245
+
246
+ ### Prevention
247
+ - Always use `pat-eu1-*` tokens for EU1 portals
248
+ - Run `hscli doctor hublet-check` after initial setup
249
+ - Check `apiDomain` in profile: `hscli auth profile-show`
250
+
251
+ ---
252
+
253
+ ## 7. Permission Profile Lockout
254
+
255
+ **Severity:** Low
256
+
257
+ ### Symptoms
258
+ - `PERMISSION_DENIED` error: "Profile 'X' is configured as read-only"
259
+ - Write operations fail despite `--force`
260
+
261
+ ### Diagnosis
262
+ ```bash
263
+ # Check current mode
264
+ hscli auth profile-show --profile <name>
265
+ # Look for: "mode": "read-only"
266
+ ```
267
+
268
+ ### Recovery
269
+ ```bash
270
+ # Switch back to read-write
271
+ hscli auth set-mode <profile> read-write
272
+
273
+ # Verify
274
+ hscli --force crm contacts create --data '{"properties":{"email":"test@example.com"}}' --dry-run
275
+ ```
276
+
277
+ ### Audit
278
+ - Check who changed the mode and when (git log if config is versioned)
279
+ - Consider if read-only was set intentionally for safety
280
+
281
+ ---
282
+
283
+ ## 8. Rollback Procedure
284
+
285
+ **Severity:** Varies
286
+
287
+ ### When to Rollback
288
+ - New version introduces breaking changes
289
+ - Plugin causes unexpected behavior
290
+ - Build artifacts are corrupted
291
+
292
+ ### Steps
293
+ ```bash
294
+ # Check recent commits
295
+ git log --oneline -10
296
+
297
+ # Rollback to previous known-good commit
298
+ git checkout <commit-hash>
299
+
300
+ # Rebuild
301
+ npm ci && npm run build
302
+
303
+ # Verify
304
+ npm test
305
+ hscli crm contacts list --limit 1
306
+ ```
307
+
308
+ ### Post-Rollback
309
+ 1. Verify all tests pass: `npm test`
310
+ 2. Verify auth still works: `hscli auth profiles`
311
+ 3. Check MCP server if used: verify `.mcp.json` points to correct `dist/cli.js`
312
+ 4. Document the rollback reason for post-mortem
313
+
314
+ ---
315
+
316
+ ## General Escalation Path
317
+
318
+ 1. **Check docs**: `docs/COOKBOOK.md`, `docs/PLUGIN_GUIDE.md`
319
+ 2. **Check diagnostics**: `hscli doctor hublet-check`, `hscli doctor capabilities --refresh`
320
+ 3. **Enable telemetry**: `--telemetry-file /tmp/debug.jsonl`
321
+ 4. **Enable strict mode**: `HSCLI_STRICT_SCHEMAS=1 HSCLI_STRICT_CAPABILITIES=1`
322
+ 5. **File issue**: include error code, redacted command, and telemetry output
@@ -0,0 +1,362 @@
1
+ # Operations Setup Guide
2
+
3
+ > See also: [PORTAL_SETUP.md](PORTAL_SETUP.md) · [REPORTING_SETUP.md](REPORTING_SETUP.md) · [INTEGRATIONS_NOTIFICATIONS_SETUP.md](INTEGRATIONS_NOTIFICATIONS_SETUP.md)
4
+
5
+ Complete configuration guide for HubSpot Operations Hub settings. Covers data sync, data quality, workflows, datasets, custom properties, and data management.
6
+
7
+ **Prerequisites:**
8
+ - Portal authenticated (`hscli auth whoami`)
9
+ - Private App scopes: `crm.objects.contacts.read/write`, `crm.schemas.contacts.read`
10
+ - Operations Hub license (Starter/Professional/Enterprise for advanced features)
11
+
12
+ ---
13
+
14
+ ## 1. Data Sync
15
+
16
+ **Where:** Settings > Integrations > Data Sync (or Connected Apps)
17
+
18
+ ### 1.1 Two-Way Sync Configuration
19
+
20
+ | Setting | What to configure | Why it matters |
21
+ |---------|-------------------|----------------|
22
+ | Connected app | Select third-party app to sync | Bidirectional data flow |
23
+ | Sync direction | Two-way, HubSpot → app, or app → HubSpot | Controls data flow direction |
24
+ | Object mapping | Map HubSpot objects to app objects | Correct data alignment |
25
+ | Field mapping | Map HubSpot properties to app fields | Accurate data transfer |
26
+ | Sync rules | How conflicts are resolved (most recent wins, prefer HubSpot, prefer app) | Data consistency |
27
+ | Filter rules | Which records to sync (e.g., only active customers) | Prevent syncing irrelevant data |
28
+ | Initial sync | Full historical sync vs. going-forward only | Complete vs. fresh-start data |
29
+
30
+ ### 1.2 Common Data Sync Integrations
31
+
32
+ | App | Objects synced | Use case |
33
+ |-----|---------------|----------|
34
+ | Salesforce | Contacts, Companies, Deals, Activities | CRM bidirectional sync |
35
+ | Microsoft Dynamics | Contacts, Companies, Deals | CRM sync |
36
+ | Mailchimp | Contacts, Lists | Email marketing sync |
37
+ | Google Contacts | Contacts | Address book sync |
38
+ | NetSuite | Contacts, Companies, Products, Invoices | ERP sync |
39
+ | QuickBooks | Contacts, Invoices, Products | Accounting sync |
40
+ | Zendesk | Contacts, Tickets | Support data sync |
41
+
42
+ ### 1.3 Sync Health Monitoring
43
+
44
+ | Metric | What to monitor | Action |
45
+ |--------|----------------|--------|
46
+ | Sync errors | Failed record syncs | Review and fix field mapping issues |
47
+ | Sync lag | Time delay between systems | Check API rate limits |
48
+ | Record count | Total records synced | Verify expected volume |
49
+ | Conflict resolution | How conflicts were handled | Audit data accuracy |
50
+
51
+ ---
52
+
53
+ ## 2. Data Quality
54
+
55
+ **Where:** Operations > Data Quality (Operations Hub Professional+)
56
+
57
+ ### 2.1 Data Quality Command Center
58
+
59
+ | Feature | Configuration | Purpose |
60
+ |---------|--------------|---------|
61
+ | Property insights | Auto-detected issues per property | Identify data problems |
62
+ | Data health trends | Dashboard of data quality over time | Track improvement |
63
+ | Fix recommendations | Suggested fixes for common issues | Guided cleanup |
64
+ | Duplicate management | Detect and merge duplicate records | Data deduplication |
65
+
66
+ ### 2.2 Data Quality Automation
67
+
68
+ | Rule type | Example | Purpose |
69
+ |-----------|---------|---------|
70
+ | Capitalize names | "john doe" → "John Doe" | Consistent formatting |
71
+ | Fix phone format | Various formats → standardized | Consistent phone numbers |
72
+ | Clean dates | Various date formats → ISO standard | Consistent date formatting |
73
+ | Trim whitespace | Remove leading/trailing spaces | Clean data entry |
74
+ | Standardize state | "calif." → "California" | Consistent address data |
75
+
76
+ **hscli:**
77
+ ```bash
78
+ # Search for contacts with data issues (e.g., missing email)
79
+ hscli crm contacts search --data '{
80
+ "filterGroups": [{
81
+ "filters": [{
82
+ "propertyName": "email",
83
+ "operator": "NOT_HAS_PROPERTY"
84
+ }]
85
+ }],
86
+ "limit": 50
87
+ }'
88
+
89
+ # Bulk update to fix formatting
90
+ hscli crm contacts batch update --data '{
91
+ "inputs": [
92
+ {"id": "123", "properties": {"firstname": "John"}},
93
+ {"id": "456", "properties": {"firstname": "Jane"}}
94
+ ]
95
+ }' --force
96
+ ```
97
+
98
+ ### 2.3 Duplicate Management
99
+
100
+ **Where:** Contacts > Actions > Manage Duplicates (or Operations > Data Quality)
101
+
102
+ | Setting | What to configure | Why it matters |
103
+ |---------|-------------------|----------------|
104
+ | Detection rules | Match by email, name, phone, company | Find potential duplicates |
105
+ | Auto-merge rules | Which record wins (most recent, most complete) | Automated cleanup |
106
+ | Manual review queue | Review suggested merges before applying | Prevent false merges |
107
+ | Merge behavior | Primary record + merged data | Data preservation |
108
+
109
+ ---
110
+
111
+ ## 3. Workflows (Programmable Automation)
112
+
113
+ **Where:** Automation > Workflows
114
+
115
+ ### 3.1 Operations-Specific Workflow Actions
116
+
117
+ | Action | Description | Use case |
118
+ |--------|-------------|----------|
119
+ | **Custom code** | Run JavaScript/Python in workflow | Complex data transformations |
120
+ | **Webhook** | Call external API | Trigger actions in other systems |
121
+ | **Format data** | Transform property values | Standardize data on the fly |
122
+ | **Create/update records** | CRM operations within workflow | Cross-object automation |
123
+ | **Data sync trigger** | Trigger sync on record change | Real-time data sync |
124
+
125
+ ### 3.2 Custom Code Actions (Operations Hub Professional+)
126
+
127
+ | Feature | Configuration | Purpose |
128
+ |---------|--------------|---------|
129
+ | Language | Node.js 18 (JavaScript) | Custom logic |
130
+ | Inputs | Define input properties from enrollment trigger | Pass data into code |
131
+ | Outputs | Define output properties | Pass results to next action |
132
+ | Secrets | Store API keys securely | Secure external API calls |
133
+ | Timeout | Max 20 seconds execution | Performance guardrail |
134
+
135
+ ```javascript
136
+ // Example: Enrich company data with external API
137
+ exports.main = async (event, callback) => {
138
+ const domain = event.inputFields['company_domain'];
139
+ const response = await fetch(`https://api.enrichment.com/company?domain=${domain}`, {
140
+ headers: { 'Authorization': `Bearer ${process.env.ENRICHMENT_API_KEY}` }
141
+ });
142
+ const data = await response.json();
143
+ callback({
144
+ outputFields: {
145
+ industry: data.industry,
146
+ employee_count: data.employees,
147
+ annual_revenue: data.revenue
148
+ }
149
+ });
150
+ };
151
+ ```
152
+
153
+ ### 3.3 Webhook Actions
154
+
155
+ | Setting | What to configure | Why it matters |
156
+ |---------|-------------------|----------------|
157
+ | URL | Endpoint to call | External system integration |
158
+ | Method | POST, GET, PUT, DELETE | API operation type |
159
+ | Headers | Auth headers, content type | API authentication |
160
+ | Body | JSON payload with HubSpot data | Data to send |
161
+ | Response mapping | Map response to HubSpot properties | Update CRM from response |
162
+
163
+ ---
164
+
165
+ ## 4. Datasets
166
+
167
+ **Where:** Reports > Datasets (Operations Hub Professional+)
168
+
169
+ ### 4.1 Dataset Configuration
170
+
171
+ | Setting | What to configure | Why it matters |
172
+ |---------|-------------------|----------------|
173
+ | Data sources | Select CRM objects to include | Define data scope |
174
+ | Joins | How objects relate (contacts + deals + companies) | Cross-object analysis |
175
+ | Calculated fields | Custom formulas on existing data | Derived metrics |
176
+ | Filters | Which records to include | Focused datasets |
177
+ | Permissions | Who can use the dataset | Data governance |
178
+
179
+ ### 4.2 Calculated Field Types
180
+
181
+ | Type | Example | Formula |
182
+ |------|---------|---------|
183
+ | Date math | Days since last activity | `DATEDIFF(NOW(), last_activity_date)` |
184
+ | String manipulation | Full name from first + last | `CONCAT(firstname, " ", lastname)` |
185
+ | Conditional | Lead grade based on score | `IF(score > 80, "A", IF(score > 50, "B", "C"))` |
186
+ | Aggregation | Total deal value per company | `SUM(deal_amount)` |
187
+ | Math | Discount percentage | `(original_price - sale_price) / original_price` |
188
+
189
+ ### 4.3 Dataset Best Practices
190
+
191
+ | Practice | Why |
192
+ |----------|-----|
193
+ | Name clearly | Easy discovery for report builders |
194
+ | Document calculated fields | Others understand the logic |
195
+ | Limit scope | Performance and relevance |
196
+ | Test with sample data | Verify calculations before sharing |
197
+ | Set permissions | Prevent unauthorized access to sensitive data |
198
+
199
+ ---
200
+
201
+ ## 5. Custom Properties & Objects
202
+
203
+ ### 5.1 Property Management Strategy
204
+
205
+ **Where:** Settings > Properties
206
+
207
+ | Guideline | Recommendation | Why |
208
+ |-----------|---------------|-----|
209
+ | Naming convention | `snake_case` with prefix (e.g., `ops_sync_status`) | Avoid conflicts, easy identification |
210
+ | Property groups | Organize related properties into groups | Clean UI for users |
211
+ | Required fields | Only require what's truly necessary | Balance data quality with usability |
212
+ | Field validation | Use appropriate field types and validation | Prevent bad data at entry |
213
+ | Documentation | Maintain a property dictionary | Team knows what each property means |
214
+
215
+ **hscli:**
216
+ ```bash
217
+ # List all contact properties
218
+ hscli crm properties list contacts --limit 100
219
+
220
+ # Create a custom property
221
+ hscli crm properties create contacts --data '{
222
+ "name": "ops_data_source",
223
+ "label": "Data Source",
224
+ "type": "enumeration",
225
+ "fieldType": "select",
226
+ "groupName": "contactinformation",
227
+ "options": [
228
+ {"label": "Website", "value": "website", "displayOrder": 0},
229
+ {"label": "Import", "value": "import", "displayOrder": 1},
230
+ {"label": "API", "value": "api", "displayOrder": 2},
231
+ {"label": "Integration", "value": "integration", "displayOrder": 3}
232
+ ]
233
+ }' --force
234
+
235
+ # Delete a property (careful!)
236
+ hscli crm properties delete contacts <propertyName> --force
237
+ ```
238
+
239
+ ### 5.2 Custom Objects (Enterprise)
240
+
241
+ **Where:** Settings > Objects > Custom Objects
242
+
243
+ | Setting | What to configure | Why it matters |
244
+ |---------|-------------------|----------------|
245
+ | Object name | Singular and plural labels | UI display |
246
+ | Primary display property | Which property shows in record title | Quick identification |
247
+ | Properties | Custom properties for the object | Data model |
248
+ | Associations | Links to standard objects (contacts, companies, deals) | Relational data |
249
+ | Pipelines | Optional pipeline for status tracking | Process management |
250
+
251
+ **hscli:**
252
+ ```bash
253
+ # List custom objects (schemas)
254
+ hscli crm schemas list
255
+
256
+ # Create a custom object
257
+ hscli crm schemas create --data '{
258
+ "name": "project",
259
+ "labels": {"singular": "Project", "plural": "Projects"},
260
+ "primaryDisplayProperty": "project_name",
261
+ "properties": [
262
+ {"name": "project_name", "label": "Project Name", "type": "string", "fieldType": "text"},
263
+ {"name": "project_status", "label": "Status", "type": "enumeration", "fieldType": "select",
264
+ "options": [{"label": "Active", "value": "active"}, {"label": "Complete", "value": "complete"}]},
265
+ {"name": "start_date", "label": "Start Date", "type": "date", "fieldType": "date"}
266
+ ],
267
+ "associatedObjects": ["CONTACT", "COMPANY"]
268
+ }' --force
269
+ ```
270
+
271
+ ---
272
+
273
+ ## 6. Import & Export
274
+
275
+ **Where:** Contacts > Import (or any object > Import)
276
+
277
+ ### 6.1 Import Settings
278
+
279
+ | Setting | What to configure | Why it matters |
280
+ |---------|-------------------|----------------|
281
+ | File format | CSV or XLSX | Data source format |
282
+ | Object type | Which CRM object to import to | Target destination |
283
+ | Column mapping | Map file columns to HubSpot properties | Correct data placement |
284
+ | Import type | Create new, update existing, or both | Control record creation |
285
+ | Deduplication | Match on email, record ID, or custom property | Prevent duplicates |
286
+ | List creation | Auto-create list of imported records | Track imported batch |
287
+
288
+ ### 6.2 Import Best Practices
289
+
290
+ | Practice | Why |
291
+ |----------|-----|
292
+ | Clean data before import | Garbage in, garbage out |
293
+ | Test with small sample first | Verify mapping before bulk import |
294
+ | Include unique identifier | Email for contacts, domain for companies |
295
+ | Use consistent date format | YYYY-MM-DD or MM/DD/YYYY |
296
+ | Remove duplicates in source file | Don't create duplicate CRM records |
297
+ | Back up before large imports | Safety net |
298
+
299
+ **hscli:**
300
+ ```bash
301
+ # Import contacts from CSV
302
+ hscli crm imports create --file ./contacts.csv --object contacts --force
303
+
304
+ # Check import status
305
+ hscli crm imports list --limit 10
306
+ ```
307
+
308
+ ---
309
+
310
+ ## Setup Checklist
311
+
312
+ ### Data Sync
313
+ ```
314
+ [ ] Key integrations identified for data sync
315
+ [ ] Sync direction configured per integration
316
+ [ ] Field mappings defined and tested
317
+ [ ] Conflict resolution rules set
318
+ [ ] Filter rules configured (which records to sync)
319
+ [ ] Sync health monitoring in place
320
+ ```
321
+
322
+ ### Data Quality
323
+ ```
324
+ [ ] Data quality command center reviewed
325
+ [ ] Formatting automation rules created (names, phones, dates)
326
+ [ ] Duplicate detection rules configured
327
+ [ ] Initial duplicate review and merge completed
328
+ [ ] Ongoing data quality monitoring established
329
+ ```
330
+
331
+ ### Workflows
332
+ ```
333
+ [ ] Custom code actions created for complex logic (if needed)
334
+ [ ] Webhook integrations configured
335
+ [ ] Data formatting workflows active
336
+ [ ] Cross-object automation workflows built
337
+ ```
338
+
339
+ ### Datasets
340
+ ```
341
+ [ ] Key datasets created for reporting
342
+ [ ] Calculated fields defined and tested
343
+ [ ] Dataset permissions set
344
+ [ ] Report builders trained on available datasets
345
+ ```
346
+
347
+ ### Properties & Objects
348
+ ```
349
+ [ ] Property naming convention established
350
+ [ ] Property groups organized
351
+ [ ] Unnecessary properties archived
352
+ [ ] Custom objects created (if needed)
353
+ [ ] Association relationships configured
354
+ ```
355
+
356
+ ### Import/Export
357
+ ```
358
+ [ ] Import process documented
359
+ [ ] Import templates created (CSV with correct columns)
360
+ [ ] Initial data import completed and verified
361
+ [ ] Ongoing import process established (if recurring)
362
+ ```