This handles the full lifecycle of custom CRM object schemas in HubSpot: list what exists, inspect definitions, create new object types with properties and associations, update labels, and delete schemas (with a three-step safety flow since it's destructive and wipes all records). It's schema management only. Once you've defined a custom object, all the normal record operations (CRUD, search, bulk upsert) work through the standard objects commands covered in bulk-operations. The create flow is straightforward JSON, and the delete protection is solid: dry run first, get a digest, then confirm within five minutes using the schema name. If you're extending HubSpot's data model beyond contacts and deals, this is how you do it.
npx -y skills add hubspot/agent-cli-skills --skill custom-object-management --agent claude-codeInstalls into .claude/skills of the current project.
hubspot schemas --help is authoritative. Subcommands: list, get, create, update (metadata only), delete (destructive). Schema writes require a private app token with crm.schemas.custom.write. Read bulk-operations/SKILL.md first — every command here uses its JSONL conventions, and schemas delete uses its dry-run / digest / confirm flow.
hubspot schemas list # JSONL: name, label, singular, objectTypeId, source
hubspot schemas list | jq 'select(.source=="custom")' # custom only
hubspot objects types | jq -c 'select(.source=="custom")' # same set, also shown to confirm `--type` resolves
name is what every other command takes. objectTypeId (e.g. 2-12345678) is only needed for workflow PLATFORM_FLOW targets.
hubspot schemas get pets
Returns the full definition — properties, associations, labels, requiredProperties, primaryDisplayProperty, fullyQualifiedName. Reshape with jq as needed (see bulk-operations/resources/json-patterns.md).
Build a JSON body and pipe it (or pass --file). Minimal valid body:
{
"name": "equipment",
"labels": {"singular": "Equipment", "plural": "Equipment"},
"primaryDisplayProperty": "equipment_name",
"requiredProperties": ["equipment_name"],
"properties": [
{"name": "equipment_name", "label": "Name", "type": "string", "fieldType": "text"}
],
"associatedObjects": ["contacts"]
}
cat equipment-schema.json | hubspot schemas create --dry-run # preview
hubspot schemas create --file equipment-schema.json # execute
Add more properties later with hubspot properties create --type <name> ....
update patches labels / description only. Property edits go through hubspot properties.
echo '{"labels":{"singular":"Device","plural":"Devices"}}' | hubspot schemas update equipment
update also supports --dry-run → digest → re-run with --digest --confirm <name> (see bulk-operations/SKILL.md for the pattern).
Schema delete is destructive and irreversible — it permanently removes the schema and every record of that type. It is gated as MetadataDestroy: every delete requires --dry-run first, then re-run with --digest <hash> --confirm <name> within 5 minutes.
Follow the three-step flow documented in bulk-operations/SKILL.md ("Safe destructive workflow"). For schemas, the confirm value is the schema name:
hubspot schemas delete equipment --dry-run
# → digest=blast-... ; apply_command_hint shows: --digest <hash> --confirm 'equipment'
hubspot schemas delete equipment --digest <hash> --confirm equipment
Check hubspot history --since 24h --kind MetadataDestroy to audit recent schema deletes.
Once a schema exists, all hubspot objects ... commands accept its name as --type (e.g. --type pets). Record CRUD, search, association, bulk upsert — all identical to standard objects. Don't re-implement those flows here; see bulk-operations/SKILL.md and crm-lookup.
sickn33/antigravity-awesome-skills
moizibnyousaf/ai-agent-skills
github/awesome-copilot