Agent skill

Hubspot Bulk Migration

by jeremylongshore in jeremylongshore/tons-of-skills-marketplace

Bulk-migrate CRM data into HubSpot from Salesforce, Pipedrive, or Copper — or export off HubSpot — with field mapping, ID continuity, association re-linking, dedup safety, rate-limit budgeting, and…

MITAuto-check passedSales & Support

Install Hubspot Bulk Migration

skills CLI
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill hubspot-bulk-migration -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install jeremylongshore/tons-of-skills-marketplace hubspot-bulk-migration --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/.curated/hubspot-bulk-migration .claude/skills/hubspot-bulk-migration && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
hubspot-bulk-migration
GitHub stars
2.8k
Token cost
~3.9k tokens
SKILL.md length
804 words
Files
3 (incl. references)
Skills in repo
3,342
Repo updated
First seen
Licence
MIT

At a glance

Bulk-migrate CRM data into HubSpot from Salesforce, Pipedrive, or Copper — or export off HubSpot — with field mapping, ID continuity, association re-linking, dedup safety, rate-limit budgeting, and…

  • Works in 5 steps: Create custom properties for ID continuity → Validate field types (dry-run before any… → Rate-budgeted batch import — contacts… → …
  • Migrating any source CRM to HubSpot
  • SKILL.md covers Overview, Prerequisites, Instructions and Error Handling, plus 3 more sections
  • Calls curl, jq and pip; reaches api.hubapi.com; needs HUBSPOT_ACCESS_TOKEN

What it does

Hubspot Bulk Migration is an agent skill from jeremylongshore/tons-of-skills-marketplace. Bulk-migrate CRM data into HubSpot from Salesforce, Pipedrive, or Copper — or export off HubSpot — with field mapping, ID continuity, association re-linking, dedup safety, rate-limit budgeting, and rollback mitigation across 100K+ record datasets. Use when migrating any source CRM to HubSpot, recovering from a failed import with duplicate or unlinked records, or exporting out of HubSpot before switching platforms. Trigger with "hubspot bulk migration", "salesforce to hubspot", "pipedrive to hubspot", "copper to…

Its SKILL.md is about 3.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 3 other files, including reference files (for example `references/API_REFERENCE.md` and `references/implementation-guide.md`). Compatibility notes: Designed for Claude Code

It sits in Sales & Support, covering CRM management. It works with HubSpot and Salesforce. The repository describes itself as: Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com. The licence is MIT.

When your agent uses it

  • Migrating any source CRM to HubSpot
  • Recovering from a failed import with duplicate
  • Unlinked records
  • Exporting out of HubSpot before switching platforms

Example prompts

  • “hubspot bulk migration”
  • “salesforce to hubspot”
  • “pipedrive to hubspot”
  • “/hubspot-bulk-migration”

Requirements

  • Python 3
  • A credential in HUBSPOT_ACCESS_TOKEN
  • Compatibility (from SKILL.md): Designed for Claude Code
  • Pre-approved tools (allowed-tools): Read, Bash(curl:*), Bash(jq:*), Bash(python3:*)

Workflow steps

5 steps, taken from the step headings in SKILL.md.

  1. Create custom properties for ID continuity
  2. Validate field types (dry-run before any writes)
  3. Rate-budgeted batch import — contacts first, companies second, deals third
  4. Re-link associations (two-pass — after all objects are imported)
  5. Rollback using ID map

What it can do on your machine

Read from SKILL.md and the folder at commit cfae287. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Read
    • Bash(curl:*)
    • Bash(jq:*)
    • Bash(python3:*)

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • curl
    • jq
    • pip

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • api.hubapi.com

    Also links to:

    • developers.hubspot.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • HUBSPOT_ACCESS_TOKEN

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

  • Compatibility

    Designed for Claude Code

    From compatibility in the SKILL.md frontmatter.

Context cost

Hubspot Bulk Migration loads about 3.9k tokens when it runs, and up to ~13k if it reads all its reference files. Until then it costs about 169 tokens; SKILL.md has 804 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~169
When it runs · the whole SKILL.md, loaded when a task matches
~3.9k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~13k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from jeremylongshore/tons-of-skills-marketplace at commit cfae287, republished under its MIT licence (© jeremylongshore). 804 words, ~3,937 tokens.

Download SKILL.mdSave it as .claude/skills/hubspot-bulk-migration/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.
name
hubspot-bulk-migration
description
Bulk-migrate CRM data into HubSpot from Salesforce, Pipedrive, or Copper — or export off HubSpot — with field mapping, ID continuity, association re-linking, dedup safety, rate-limit budgeting, and rollback mitigation across 100K+ record datasets. Use when migrating any source CRM to HubSpot, recovering from a failed import with duplicate or unlinked records, or exporting out of HubSpot before switching platforms. Trigger with "hubspot bulk migration", "salesforce to hubspot", "pipedrive to hubspot", "copper to hubspot", "migrate off hubspot", "hubspot import dedup", "hubspot association relink", "hubspot field mapping", "hubspot id continuity".
allowed-tools
Read, Bash(curl:*), Bash(jq:*), Bash(python3:*)
compatibility
Designed for Claude Code
version
2.9.0
license
MIT
author
Jeremy Longshore <jeremy@intentsolutions.io>
tags
hubspot, migration, data-engineering, salesforce, import

HubSpot Bulk Migration

Overview

Move CRM data into HubSpot from Salesforce, Pipedrive, or Copper — or extract it back out — without losing cross-system IDs, breaking associations, or flooding the portal with duplicates. This is not a data-mapping worksheet. It is the code, sequencing, and guardrails your migration runs at 2am against 150K records when the daily API quota is finite, HubSpot has no bulk-delete API, and a bad import leaves permanent junk that requires a support ticket to remove.

The six production failures this skill addresses:

  1. ID continuity loss — source CRM IDs are not preserved in HubSpot. Fix: create a custom source_crm_id property on every object type before the first record lands, and write the source ID into it during import.
  2. Association re-creation failure — contacts, companies, and deals in the source are associated; batch-importing them independently creates records without associations unless a second pass re-links them after all IDs are known. Fix: import in order (companies → contacts → deals), then re-link in three association passes.
  3. Import dedup missing existing records — HubSpot's batch upsert deduplicates contacts by email, but only when email matches exactly. Missing or differently-formatted emails create duplicates. Fix: normalize email to lowercase + trimmed before every import; use batch/upsert not batch/create for contacts.
  4. Field type mismatch — source date fields in M/D/Y format fail HubSpot's ISO 8601 validation; multi-picklist values not in HubSpot's allowed enumeration are silently dropped. Fix: run a pre-migration dry-run that validates every field against HubSpot's property schema before writing a single record.
  5. Rate limit exhaustion — 100K contacts at 100/batch equals 1,000 API calls; association re-linking doubles that. Combined with retries, a naive migration burns the 500K daily quota before finishing. Fix: budget calls per run, sleep between burst windows, and use the CSV import API for volumes above 10K.
  6. Rollback impossibility — HubSpot has no bulk-delete API. Fix: maintain a local source_id → hubspot_id mapping file throughout the migration so batch/archive calls are programmable.

Auth: set HUBSPOT_ACCESS_TOKEN environment variable to a private app token with CRM write scopes. For token caching, rotation, and multi-portal routing see the hubspot-auth skill in this pack.

Prerequisites

  • HubSpot private app token with scopes: crm.objects.contacts.write, crm.objects.companies.write, crm.objects.deals.write, crm.associations.write, crm.schemas.contacts.write
  • Python 3.10+ (pip install requests)
  • Source CRM data exported to CSV or available via API
  • HUBSPOT_ACCESS_TOKEN set in environment

Instructions

Step 1: Create custom properties for ID continuity

Before importing a single record, create a custom property on every object type to store the source CRM's record ID. Treat 409 CONFLICT as success — property creation is idempotent.

python
import os, requests

TOKEN = os.environ["HUBSPOT_ACCESS_TOKEN"]
BASE  = "https://api.hubapi.com"
HDRS  = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}

def create_source_id_property(object_type: str, source_crm: str) -> None:
    prop_name = f"{source_crm}_id"
    payload = {
        "name": prop_name,
        "label": f"{source_crm.title()} ID",
        "type": "string",
        "fieldType": "text",
        "groupName": f"{object_type}information",
        "description": f"Original {source_crm.title()} record ID. Do not modify.",
    }
    resp = requests.post(f"{BASE}/crm/v3/properties/{object_type}", headers=HDRS, json=payload)
    if resp.status_code not in (200, 201, 409):
        resp.raise_for_status()

for obj in ["contacts", "companies", "deals"]:
    create_source_id_property(obj, "salesforce")  # or "pipedrive", "copper"
Step 2: Validate field types (dry-run before any writes)

Pull HubSpot's property schema and validate every field in your source CSV before touching the API. Catches date format mismatches and invalid enum values upfront.

python
import csv, json, re
from datetime import datetime

def get_property_schema(object_type: str) -> dict:
    resp = requests.get(f"{BASE}/crm/v3/properties/{object_type}", headers=HDRS)
    resp.raise_for_status()
    return {p["name"]: p for p in resp.json()["results"]}

def validate_record(record: dict, schema: dict) -> list[str]:
    errors = []
    for field, value in record.items():
        if not value or field not in schema:
            continue
        prop = schema[field]
        if prop.get("type") == "date":
            try:
                datetime.strptime(str(value), "%Y-%m-%d")
            except ValueError:
                errors.append(f"{field}='{value}' must be YYYY-MM-DD")
        if prop.get("type") == "enumeration":
            allowed = {o["value"] for o in prop.get("options", [])}
            if allowed and str(value) not in allowed:
                errors.append(f"{field}='{value}' not in allowed values: {sorted(allowed)}")
    return errors

Full dry-run driver and field-by-field transform helpers in implementation-guide.md.

Step 3: Rate-budgeted batch import — contacts first, companies second, deals third

Import in dependency order. Track the source_id → hubspot_id mapping per batch. Save the map to disk after every batch — a mid-run crash leaves a complete map for the records that did land.

python
import time, json

def batch_import(records, object_type, source_id_field, batch_size=100):
    """Import records and return {source_id: hubspot_id} mapping."""
    endpoint = "upsert" if object_type == "contacts" else "create"
    url = f"{BASE}/crm/v3/objects/{object_type}/batch/{endpoint}"
    id_map, errors = {}, []
    batches = [records[i:i+batch_size] for i in range(0, len(records), batch_size)]

    for n, batch in enumerate(batches, 1):
        if endpoint == "upsert":
            payload = {"inputs": [{"idProperty": "email", "id": r.get("email",""), "properties": r} for r in batch]}
        else:
            payload = {"inputs": [{"properties": r} for r in batch]}

        resp = requests.post(url, headers=HDRS, json=payload)
        daily_left = int(resp.headers.get("X-HubSpot-RateLimit-Daily-Remaining", 500_000))
        if resp.status_code == 429:
            time.sleep(int(resp.headers.get("Retry-After", 10)))
            resp = requests.post(url, headers=HDRS, json=payload)
        if resp.status_code not in (200, 201, 207):
            errors.append({"batch": n, "status": resp.status_code})
            continue
        # Daily quota guard — 500K is the Professional/Enterprise daily limit
        if daily_left < 10_000:
            raise RuntimeError(f"Daily quota critical: {daily_left} remaining. Resume tomorrow.")
        for result_item, orig in zip(resp.json().get("results", []), batch):
            src_id = orig.get(source_id_field, "")
            hs_id  = result_item.get("id", "")
            if src_id and hs_id:
                id_map[src_id] = hs_id
        print(f"  Batch {n}/{len(batches)}: {len(batch)} records, daily_left={daily_left}")
        time.sleep(0.12)   # stay below 90 req/10s burst ceiling

    return id_map, errors

def save_id_map(id_map: dict, path: str) -> None:
    existing = {}
    try:
        with open(path) as f: existing = json.load(f)
    except FileNotFoundError: pass
    existing.update(id_map)
    with open(path, "w") as f: json.dump(existing, f, indent=2)
Show full SKILL.md (301 more words)Show less
python
def relink_associations(source_assocs, from_id_map, to_id_map,
                         from_type, to_type, type_id, batch_size=100):
    """Re-create associations using v4 API. Returns {linked, skipped, errors}."""
    url = f"{BASE}/crm/v4/associations/{from_type}/{to_type}/batch/create"
    linked = skipped = 0
    errors = []
    batches = [source_assocs[i:i+batch_size] for i in range(0, len(source_assocs), batch_size)]
    for batch in batches:
        inputs = []
        for a in batch:
            fhs = from_id_map.get(a["from_source_id"])
            ths = to_id_map.get(a["to_source_id"])
            if not fhs or not ths:
                skipped += 1; continue
            inputs.append({"from": {"id": fhs}, "to": {"id": ths},
                            "types": [{"associationCategory": "HUBSPOT_DEFINED", "associationTypeId": type_id}]})
        if not inputs: continue
        resp = requests.post(url, headers=HDRS, json={"inputs": inputs})
        if resp.status_code == 429:
            time.sleep(int(resp.headers.get("Retry-After", 10)))
            resp = requests.post(url, headers=HDRS, json={"inputs": inputs})
        if resp.status_code not in (200, 201, 207):
            errors.append({"status": resp.status_code, "body": resp.text[:200]})
        else:
            linked += len(inputs)
        time.sleep(0.12)
    return {"linked": linked, "skipped": skipped, "errors": errors}

# Standard association type IDs — full table in API_REFERENCE.md
CONTACT_TO_COMPANY, DEAL_TO_CONTACT, DEAL_TO_COMPANY = 1, 3, 5
Step 5: Rollback using ID map
python
def rollback_migration(id_map_path: str, object_type: str, dry_run: bool = True) -> dict:
    """Archive all records created during migration. Always dry_run=True first."""
    with open(id_map_path) as f:
        id_map = json.load(f)
    hubspot_ids = list(id_map.values())
    archived, errors = 0, []
    for i in range(0, len(hubspot_ids), 100):
        batch = hubspot_ids[i:i+100]
        if dry_run:
            print(f"Would archive: {batch[:3]}...")
            archived += len(batch); continue
        resp = requests.post(f"{BASE}/crm/v3/objects/{object_type}/batch/archive",
                             headers=HDRS, json={"inputs": [{"id": hid} for hid in batch]})
        if resp.status_code == 204:
            archived += len(batch)
        else:
            errors.append({"status": resp.status_code})
        time.sleep(0.12)
    return {"archived": archived, "errors": errors, "dry_run": dry_run}

Error Handling

HTTP StatusErrorRoot CauseAction
400INVALID_PROPERTY_NAMEField name not in HubSpot schemaRun dry-run; remap source fields to valid HubSpot property names
400INVALID_ENUMERATION_PROPERTY_VALUEPicklist value not in allowed optionsPull GET /crm/v3/properties and remap; drop unmappable values
400INVALID_DATEDate not in YYYY-MM-DD or epoch msRun convert_date() helper (see implementation-guide.md) before import
400REQUIRED_PROPERTY_MISSINGUpsert idProperty value is emptyNormalize email; route no-email contacts to separate batch/create call
207Partial batch successSome records succeeded, some failedParse both results[] and errors[]; re-queue failed records
409DUPLICATE_PROPERTYCustom property already existsTreat as success — property creation is idempotent
429RATE_LIMITBurst (100/10s) or daily (500K) quotaRespect Retry-After; switch to CSV import API for daily budget relief
500HubSpot internal errorTransient portal errorRetry up to 3 times with 2× backoff, 30s cap
503SERVICE_UNAVAILABLEHubSpot maintenanceBack off 60s and retry; check status.hubspot.com

Examples

Full Salesforce → HubSpot migration
python
# 1. Create ID properties
for obj in ["contacts", "companies", "deals"]:
    create_source_id_property(obj, "salesforce")

# 2. Import companies first
import csv
company_rows = [{"salesforce_id": r["Id"], "name": r["Name"],
                  "domain": r.get("Website","").replace("https://","").rstrip("/")}
                for r in csv.DictReader(open("sf_accounts.csv"))]
company_map, _ = batch_import(company_rows, "companies", "salesforce_id")
save_id_map(company_map, "company_id_map.json")

# 3. Import contacts (upsert by email for dedup)
contact_rows = [{"salesforce_id": r["Id"],
                  "email": r.get("Email","").strip().lower(),
                  "firstname": r.get("FirstName",""), "lastname": r.get("LastName","")}
                for r in csv.DictReader(open("sf_contacts.csv"))]
contact_map, _ = batch_import(contact_rows, "contacts", "salesforce_id")
save_id_map(contact_map, "contact_id_map.json")

# 4. Re-link contact → company
source_assocs = [{"from_source_id": r["Id"], "to_source_id": r["AccountId"]}
                 for r in csv.DictReader(open("sf_contacts.csv")) if r.get("AccountId")]
print(relink_associations(source_assocs, contact_map, company_map,
                           "contacts", "companies", CONTACT_TO_COMPANY))
Verify source IDs landed
bash
curl -s "https://api.hubapi.com/crm/v3/objects/contacts?properties=email,salesforce_id&limit=5" \
  -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" | \
  jq '.results[] | {id, email: .properties.email, sf_id: .properties.salesforce_id}'
Rollback (dry run first, always)
python
print(rollback_migration("contact_id_map.json", "contacts", dry_run=True))
# Confirm output, then:
# rollback_migration("contact_id_map.json", "contacts", dry_run=False)

Output

  • Custom source-CRM ID properties (salesforce_id, pipedrive_id, or copper_id) created on contacts, companies, and deals before first write
  • Pre-migration validation report with 0 errors before any API calls
  • source_id → hubspot_id mapping files written per-batch for rollback coverage
  • Records imported in dependency order: companies → contacts → deals
  • Associations re-linked via v4 API in three post-import passes
  • Contacts deduped by normalized email via upsert
  • Rollback script scoped to migration ID maps

Resources

© jeremylongshore, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 2 other files (references) in skills/.curated/hubspot-bulk-migration of jeremylongshore/tons-of-skills-marketplace.

  • SKILL.md
  • references/API_REFERENCE.md
  • references/implementation-guide.md

Open the folder on GitHubat commit cfae287

Compare with similar skills

Hubspot Bulk Migration next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Hubspot Bulk Migration compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Hubspot Bulk Migration this skilljeremylongshore/tons-of-skills-marketplace2.8k—~3.9kAutomated safety check: PassMIT
Google Maps Exportgmapsscraper/google-maps-agent-skills132—~1.2kAutomated safety check: PassMIT
Pipeline Reviewgooseworks-ai/goose-skills1.2k1 repos~6.9kAutomated safety check: PassMIT
CRM Integrationmanojbajaj95/claude-gtm-plugin105—~3.8kAutomated safety check: PassMIT
CRMmagnus919/agent-skills115—~2.1kAutomated safety check: PassMIT
CRM Data CleanerLeoYeAI/openclaw-master-skills2.2k—~7.3kAutomated safety check: PassMIT

Similar skills

  • Google Maps Export

    gmapsscraper/google-maps-agent-skills

    Export Google Maps business data to CSV, JSON, or CRM format (HubSpot, Pipedrive, Salesforce).

    132 GitHub stars~1.2k tokensUpdated 4 mo ago
    Sales & SupportAuto-check passed
  • Pipeline Review

    gooseworks-ai/goose-skills

    Pipeline analysis composite. An agent skill from gooseworks-ai/goose-skills.

    1.2k GitHub starsUsed in 1 repo~6.9k tokens
    Sales & SupportAuto-check passed
  • CRM Integration

    manojbajaj95/claude-gtm-plugin

    CRM integration patterns for Close CRM, HubSpot, and Salesforce.

    105 GitHub stars~3.8k tokensUpdated 23 days ago
    Sales & SupportAuto-check passed
  • CRM

    magnus919/agent-skills

    Operate HubSpot CRM from a terminal or agent: list and search contact records, view deal pipeline stages, and — with explicit confirmation — move deals between stages, backed by a bundled crm-cli…

    115 GitHub stars~2.1k tokensUpdated yesterday
    Sales & SupportAuto-check passed
  • CRM Data Cleaner

    LeoYeAI/openclaw-master-skills

    Deduplicate, normalize, and enrich CRM contacts and companies.

    2.2k GitHub stars~7.3k tokensUpdated 2 mo ago
    Sales & SupportAuto-check passed
  • CRM Automation

    aAAaqwq/AGI-Super-Team

    CRM workflow automation for HubSpot, Salesforce, Pipedrive - lead management, deal tracking, and multi-CRM synchronization

    105 GitHub starsUsed in 1 repo~2.9k tokens
    Sales & SupportAuto-check passed

More from jeremylongshore/tons-of-skills-marketplace

All 3,342 skills in this repo
  • Performing Security Code Review

    jeremylongshore/tons-of-skills-marketplace

    Execute this skill enables AI assistant to conduct a security-focused code review using the security-agent plugin.

    2.8k GitHub starsUsed in 2 repos~1.3k tokens
    Auto-check: notes
  • Adapting Transfer Learning Models

    jeremylongshore/tons-of-skills-marketplace

    Build this skill automates the adaptation of pre-trained machine learning models using transfer learning techniques.

    2.8k GitHub stars~1.1k tokensUpdated today
    Auto-check passed
  • Agent Context Loader

    jeremylongshore/tons-of-skills-marketplace

    Execute proactive auto-loading: automatically detects and loads agents.md files.

    2.8k GitHub stars~1.1k tokensUpdated today
    Auto-check passed
  • Aggregating Performance Metrics

    jeremylongshore/tons-of-skills-marketplace

    Aggregate and centralize performance metrics from applications, systems, databases, caches, and services.

    2.8k GitHub stars~1.2k tokensUpdated today
    Auto-check passed
  • Analyzing Capacity Planning

    jeremylongshore/tons-of-skills-marketplace

    Execute this skill enables AI assistant to analyze capacity requirements and plan for future growth.

    2.8k GitHub stars~947 tokensUpdated today
    Auto-check passed
  • Analyzing Database Indexes

    jeremylongshore/tons-of-skills-marketplace

    Process use when you need to work with database indexing. An agent skill from jeremylongshore/tons-of-skills-marketplace.

    2.8k GitHub stars~2k tokensUpdated today
    Auto-check passed

Categories

Questions about Hubspot Bulk Migration

What does Hubspot Bulk Migration do?

Bulk-migrate CRM data into HubSpot from Salesforce, Pipedrive, or Copper — or export off HubSpot — with field mapping, ID continuity, association re-linking, dedup safety, rate-limit budgeting, and…. Hubspot Bulk Migration is an agent skill from jeremylongshore/tons-of-skills-marketplace. Bulk-migrate CRM data into HubSpot from Salesforce, Pipedrive, or Copper — or export off HubSpot — with field mapping, ID continuity, association re-linking, dedup safety, rate-limit budgeting, and rollback mitigation across 100K+ record datasets.

When should I use Hubspot Bulk Migration?

Hubspot Bulk Migration fits situations like: migrating any source CRM to HubSpot; recovering from a failed import with duplicate; unlinked records; exporting out of HubSpot before switching platforms.

How do I install Hubspot Bulk Migration in Claude Code?

Run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill hubspot-bulk-migration -a claude-code`. Or copy the skill folder (skills/.curated/hubspot-bulk-migration in jeremylongshore/tons-of-skills-marketplace) into .claude/skills/hubspot-bulk-migration in your project. Claude Code loads it when a task matches its description.

How do I install Hubspot Bulk Migration in Codex?

Run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill hubspot-bulk-migration -a codex`. Or copy the skill folder (skills/.curated/hubspot-bulk-migration in jeremylongshore/tons-of-skills-marketplace) into .agents/skills/hubspot-bulk-migration in your project. Codex loads it when a task matches its description.

Can I use Hubspot Bulk Migration in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill hubspot-bulk-migration -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/hubspot-bulk-migration, .gemini/skills/hubspot-bulk-migration, .github/skills/hubspot-bulk-migration and .opencode/skills/hubspot-bulk-migration in your project.

What does Hubspot Bulk Migration need to run?

Going by SKILL.md and its folder, Hubspot Bulk Migration needs the command-line tools its instructions call (curl, jq and pip) and credentials named HUBSPOT_ACCESS_TOKEN. Our summary lists: Python 3; A credential in HUBSPOT_ACCESS_TOKEN. Its frontmatter pre-approves these tools: Read, Bash(curl:*), Bash(jq:*), Bash(python3:*). Compatibility (from SKILL.md): Designed for Claude Code.

Does Hubspot Bulk Migration access the network?

SKILL.md names 2 domains. In commands or code: api.hubapi.com; the agent is likely to contact it when it follows the instructions. As links in the text: developers.hubspot.com. This is read from the text; nothing was executed.

Is Hubspot Bulk Migration safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Hubspot Bulk Migration use?

Hubspot Bulk Migration is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Hubspot Bulk Migration use?

About 3.9k tokens (SKILL.md is roughly 16k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 9k tokens, read only when the agent opens those files.

What are the alternatives to Hubspot Bulk Migration?

Skills that share tags, products or a category with Hubspot Bulk Migration: Google Maps Export (gmapsscraper/google-maps-agent-skills, 132 stars), Pipeline Review (gooseworks-ai/goose-skills, 1.2k stars), CRM Integration (manojbajaj95/claude-gtm-plugin, 105 stars) and CRM (magnus919/agent-skills, 115 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Hubspot Bulk Migration?

jeremylongshore (a GitHub user) maintains it in jeremylongshore/tons-of-skills-marketplace, which has 2,827 GitHub stars. The repository holds 3,342 skills in this directory. The repository was last updated on October 10, 2026.

Source: jeremylongshore/tons-of-skills-marketplace on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.