bulk-operations
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseResources
资源
| File | When to use |
|---|---|
| Reshape patterns for turning a read into an update payload, a search into a delete list, a CSV into an upsert stream. |
| 文件 | 使用场景 |
|---|---|
| 用于将读取结果转换为更新负载、搜索结果转换为删除列表、CSV转换为新增/更新流的格式转换模式。 |
Source of truth
权威参考
hubspot <command> --help--help--helphubspot objects typeshubspot <command> --help--help--helphubspot objects typesOutput shape
输出格式
Every read command (, , ) emits JSONL — one JSON object per line:
listsearchgetjson
{"id":"123","properties":{"email":"jane@example.com","firstname":"Jane"},"createdAt":"...","updatedAt":"...","archived":false,"url":"..."}--properties email,firstname.propertiesjq.properties.email.prop_emailWrite commands (, , , , , ) accept JSONL on stdin and emit JSONL — one result per input line: or . Order of results matches input order.
createupdateupsertdeletemergeassociations create{"id":"123","ok":true,"data":{...}}{"id":"123","ok":false,"error":{"status":...,"message":"..."}}所有读取命令(、、)都会输出JSONL——每行一个JSON对象:
listsearchgetjson
{"id":"123","properties":{"email":"jane@example.com","firstname":"Jane"},"createdAt":"...","updatedAt":"...","archived":false,"url":"..."}--properties email,firstname.propertiesjq.properties.email.prop_email写入命令(、、、、、)从标准输入接收JSONL,并输出JSONL——每行输入对应一行结果: 或 。结果顺序与输入顺序一致。
createupdateupsertdeletemergeassociations create{"id":"123","ok":true,"data":{...}}{"id":"123","ok":false,"error":{"status":...,"message":"..."}}Read in batch — never one-by-one
批量读取——切勿逐个读取
The CLI accepts multiple IDs natively. Never pipe IDs into — that spawns one CLI process per record.
xargs -I{} hubspot objects get ...bash
undefinedCLI原生支持多个ID。切勿将ID通过管道传递给——这会为每条记录启动一个CLI进程。
xargs -I{} hubspot objects get ...bash
undefinedPositional args (small, known list)
位置参数(少量、已知列表)
hubspot objects get --type contacts 12345 67890 23456 --properties email,firstname
hubspot objects get --type contacts 12345 67890 23456 --properties email,firstname
Stdin from another command — one CLI call total
从其他命令获取标准输入——仅一次CLI调用
hubspot associations list --from companies:67890 --to contacts
| jq -c '{id}'
| hubspot objects get --type contacts --properties email,firstname,jobtitle
| jq -c '{id}'
| hubspot objects get --type contacts --properties email,firstname,jobtitle
hubspot associations list --from companies:67890 --to contacts
| jq -c '{id}'
| hubspot objects get --type contacts --properties email,firstname,jobtitle
| jq -c '{id}'
| hubspot objects get --type contacts --properties email,firstname,jobtitle
Bare IDs on stdin also work
标准输入中的纯ID也可使用
printf '12345\n67890\n23456\n' | hubspot objects get --type contacts --properties email
A single `hubspot objects get` reads up to ~100 IDs per call via the batch endpoint. For more, page in chunks of 100.printf '12345\n67890\n23456\n' | hubspot objects get --type contacts --properties email
单次`hubspot objects get`调用通过批量端点最多读取约100个ID。如需处理更多ID,可按100个为一组进行分页读取。Bulk flow: paginate first, then reshape, then write
批量流程:先分页,再转换格式,最后写入
When operating on all records of a type (or all matches of a filter), always start with — never run a bare or to "check how many there are." A bare call returns at most 100 records and you will have to re-fetch them anyway.
pagination-loop.shlistsearchThe canonical bulk pattern is:
- Paginate all records to a JSONL file
- Reshape with into the write payload
jq - Pipe to the write command (,
update, etc.) withdeletefirst--dry-run
当操作某类所有记录(或符合筛选条件的所有记录)时,务必从开始——切勿直接运行或来"查看记录数量"。直接调用最多返回100条记录,之后你仍需重新获取完整数据。
pagination-loop.shlistsearch标准的批量操作模式为:
- 分页获取所有记录并保存到JSONL文件
- 使用转换格式为写入负载
jq - 通过管道传递到写入命令(、
update等),并先使用delete预执行--dry-run
Pagination
分页
listsearchresources/pagination-loop.shbash
bash resources/pagination-loop.sh <object_type> <output_file> [properties] [extra_flags...]Examples:
bash
undefinedlistsearchresources/pagination-loop.shbash
bash resources/pagination-loop.sh <object_type> <output_file> [properties] [extra_flags...]示例:
bash
undefinedAll contacts with specific properties
获取包含指定属性的所有联系人
bash resources/pagination-loop.sh contacts /tmp/contacts.jsonl email,firstname,lastname
bash resources/pagination-loop.sh contacts /tmp/contacts.jsonl email,firstname,lastname
Search with a filter (passes extra flags through to the CLI)
带筛选条件的搜索(将额外参数传递给CLI)
bash resources/pagination-loop.sh contacts /tmp/leads.jsonl email,firstname '--filter' 'lifecyclestage=lead'
bash resources/pagination-loop.sh contacts /tmp/leads.jsonl email,firstname '--filter' 'lifecyclestage=lead'
All deals, default properties
获取所有交易,使用默认属性
bash resources/pagination-loop.sh deals /tmp/deals.jsonl
The script pages through `--after` cursors automatically, prints progress to stderr, and writes JSONL to the output file. Run it as a single foreground command — do not background it or reconstruct the loop inline.bash resources/pagination-loop.sh deals /tmp/deals.jsonl
该脚本会自动通过`--after`游标进行分页,将进度信息输出到标准错误流,并将JSONL写入输出文件。请将其作为单个前台命令运行——不要后台运行或手动重构循环逻辑。Write in batch — always pipe
批量写入——始终使用管道
Write commands accept JSONL on stdin. The transformation between a read shape and a write shape is a reshape:
jq| Write command | Required per-line shape |
|---|---|
| |
| |
| |
| |
| |
| |
Use plural object names in / (, not ).
fromtocontacts:contact:写入命令从标准输入接收JSONL。读取格式到写入格式的转换可通过完成:
jq| 写入命令 | 每行所需格式 |
|---|---|
| |
| |
| |
| |
| |
| |
在/中使用复数对象名称(,而非)。
fromtocontacts:contact:Safe destructive workflow
安全破坏性工作流
Every destructive op (, , bulk ) supports . The gating depends on row count:
deletemergeupdate--dry-run≤100 rows — dry-run emits one preview line per record:
json
{"ok":true,"dry_run":true,"executed":false,"mutation_kind":"RecordMutation","command":"objects delete contacts","target":{"kind":"contacts_record","id":"123","name":"123"}}Re-run without to execute.
--dry-run>100 rows — dry-run emits a single line with a digest and an :
BulkDataapply_command_hintjson
{"ok":true,"dry_run":true,"executed":false,"mutation_kind":"BulkData","portal":"123456","target":{"name":"202 records"},"impact":{"records_affected":202,"reversible":false},"digest":"blast-29cfdd48b583","expires_in_seconds":300,"apply_command_hint":"hubspot objects delete contacts --digest blast-29cfdd48b583 --confirm '202'"}You must re-run with within 5 minutes. The value is the record count (deletes) or the secondary ID (merge). Read it off .
--digest <hash> --confirm <value>confirmapply_command_hintThree-step pattern:
bash
undefined所有破坏性操作(、、批量)均支持参数。验证机制取决于记录数量:
deletemergeupdate--dry-run≤100条记录——预执行会为每条记录输出一行预览信息:
json
{"ok":true,"dry_run":true,"executed":false,"mutation_kind":"RecordMutation","command":"objects delete contacts","target":{"kind":"contacts_record","id":"123","name":"123"}}移除参数重新运行即可执行操作。
--dry-run>100条记录——预执行会输出一行信息,包含摘要和:
BulkDataapply_command_hintjson
{"ok":true,"dry_run":true,"executed":false,"mutation_kind":"BulkData","portal":"123456","target":{"name":"202 records"},"impact":{"records_affected":202,"reversible":false},"digest":"blast-29cfdd48b583","expires_in_seconds":300,"apply_command_hint":"hubspot objects delete contacts --digest blast-29cfdd48b583 --confirm '202'"}你必须在5分钟内使用参数重新运行命令。的值为记录数量(删除操作)或次要ID(合并操作),可从中获取。
--digest <hash> --confirm <value>confirmapply_command_hint三步操作模式:
bash
undefined1. Preview
1. 预览
hubspot objects search --type contacts --filter "lifecyclestage=subscriber"
| jq -c '{id}'
| hubspot objects delete --type contacts --dry-run
| tee /tmp/preview.jsonl
| jq -c '{id}'
| hubspot objects delete --type contacts --dry-run
| tee /tmp/preview.jsonl
hubspot objects search --type contacts --filter "lifecyclestage=subscriber"
| jq -c '{id}'
| hubspot objects delete --type contacts --dry-run
| tee /tmp/preview.jsonl
| jq -c '{id}'
| hubspot objects delete --type contacts --dry-run
| tee /tmp/preview.jsonl
2. Lift the digest + confirm value (only present for >100 rows)
2. 提取摘要和确认值(仅当记录数>100时存在)
digest=$(jq -r 'select(.mutation_kind=="BulkData") | .digest' /tmp/preview.jsonl)
confirm=$(jq -r 'select(.mutation_kind=="BulkData") | .impact.records_affected' /tmp/preview.jsonl)
digest=$(jq -r 'select(.mutation_kind=="BulkData") | .digest' /tmp/preview.jsonl)
confirm=$(jq -r 'select(.mutation_kind=="BulkData") | .impact.records_affected' /tmp/preview.jsonl)
3. Execute — re-pipe the SAME inputs
3. 执行——传递相同的输入
hubspot objects search --type contacts --filter "lifecyclestage=subscriber"
| jq -c '{id}'
| hubspot objects delete --type contacts --digest "$digest" --confirm "$confirm"
| jq -c '{id}'
| hubspot objects delete --type contacts --digest "$digest" --confirm "$confirm"
undefinedhubspot objects search --type contacts --filter "lifecyclestage=subscriber"
| jq -c '{id}'
| hubspot objects delete --type contacts --digest "$digest" --confirm "$confirm"
| jq -c '{id}'
| hubspot objects delete --type contacts --digest "$digest" --confirm "$confirm"
undefinedRecovery via hubspot history
hubspot history通过hubspot history
进行恢复
hubspot historyEvery destructive op (and its dry-run) is logged locally. Check what happened in the last hour and what's reversible:
bash
hubspot history --since 1h --format table
hubspot history --since 24h --kind BulkData # only bulk ops
hubspot history --since 7d --kind MetadataDestroy # schema deleteshistory所有破坏性操作(及其预执行)都会在本地记录。查看过去一小时内的操作记录以及可恢复的内容:
bash
hubspot history --since 1h --format table
hubspot history --since 24h --kind BulkData # 仅查看批量操作
hubspot history --since 7d --kind MetadataDestroy # 仅查看架构删除操作historyUpsert beats search-then-create
Upsert优于搜索后创建
For "create if missing, update if present" (the enrichment pattern), use — one CLI call per record, no race condition:
upsertbash
cat external.jsonl \
| jq -c '{idProperty:"email", id:.email, properties:{firstname:.first, lastname:.last, company:.company}}' \
| hubspot objects upsert --type contacts --dry-run对于"不存在则创建,存在则更新"(数据补全模式),请使用——每条记录仅需一次CLI调用,无竞态条件:
upsertbash
cat external.jsonl \
| jq -c '{idProperty:"email", id:.email, properties:{firstname:.first, lastname:.last, company:.company}}' \
| hubspot objects upsert --type contacts --dry-runOr set idProperty once:
或一次性设置idProperty参数:
cat external.jsonl
| jq -c '{id:.email, properties:{firstname:.first}}'
| hubspot objects upsert --type contacts --id-property email
| jq -c '{id:.email, properties:{firstname:.first}}'
| hubspot objects upsert --type contacts --id-property email
undefinedcat external.jsonl
| jq -c '{id:.email, properties:{firstname:.first}}'
| hubspot objects upsert --type contacts --id-property email
| jq -c '{id:.email, properties:{firstname:.first}}'
| hubspot objects upsert --type contacts --id-property email
undefinedRate-limit hygiene
限流规范
There is no true batch endpoint behind // — the CLI issues one API call per stdin line. Test with before piping a 50k-row file. If the API starts 429ing, the per-line output will show — split your input file and retry the failed lines.
updatedeleteupserthead -n 50{"ok":false,"error":{"status":429,...}}updatedeleteupserthead -n 50{"ok":false,"error":{"status":429,...}}Common reshapes
常见格式转换
See for the full set. The two you need 90% of the time:
resources/json-patterns.mdbash
undefined完整的转换模式请查看。90%的场景中你会用到以下两种:
resources/json-patterns.mdbash
undefinedRead → update payload
读取结果 → 更新负载
hubspot objects search --type contacts --filter "industry=Tech"
| jq -c '{id, properties:{lifecyclestage:"marketingqualifiedlead"}}'
| hubspot objects update --type contacts
| jq -c '{id, properties:{lifecyclestage:"marketingqualifiedlead"}}'
| hubspot objects update --type contacts
hubspot objects search --type contacts --filter "industry=Tech"
| jq -c '{id, properties:{lifecyclestage:"marketingqualifiedlead"}}'
| hubspot objects update --type contacts
| jq -c '{id, properties:{lifecyclestage:"marketingqualifiedlead"}}'
| hubspot objects update --type contacts
Search → delete list
搜索结果 → 删除列表
hubspot objects search --type contacts --filter "!email"
| jq -c '{id}'
| hubspot objects delete --type contacts --dry-run
| jq -c '{id}'
| hubspot objects delete --type contacts --dry-run
undefinedhubspot objects search --type contacts --filter "!email"
| jq -c '{id}'
| hubspot objects delete --type contacts --dry-run
| jq -c '{id}'
| hubspot objects delete --type contacts --dry-run
undefinedKnown constraints
已知限制
- Some destructive operations may be blocked under user-OAuth (browser login); set (private app token) when running deletes if the CLI returns a permission error.
HUBSPOT_ACCESS_TOKEN - returns CRM users; there is no
hubspot owners listobject. For team-level operations, group byteamsclient-side.hubspot_owner_id - No Lists API, no sequences/cadences API in the current CLI surface.
- 在用户OAuth(浏览器登录)模式下,部分破坏性操作可能被阻止;如果CLI返回权限错误,请在运行删除操作时设置(私有应用令牌)。
HUBSPOT_ACCESS_TOKEN - 返回CRM用户;目前没有
hubspot owners list对象。如需进行团队级操作,请在客户端按teams分组。hubspot_owner_id - 当前CLI界面中没有Lists API和序列/节奏(sequences/cadences)API。