# Migrate Pipedrive to HubSpot

> Two flat CRMs, so there is no hierarchy to rebuild — the work is object mapping and rebuilding associations afterwards.

Source: https://migratly.dev/migrate/pipedrive-to-hubspot/

Migratly migrates Pipedrive to HubSpot by reading both APIs live, deriving the mapping between them, and
presenting it for approval before anything is written. This pair covers **8 entity types**
and **18 field mappings**: 7 carry across intact, 11 are flagged as lossy,
partial, dropped or needing another route, and 4 need a decision from you. The Pipedrive side is
read-only for the whole run.

## How the structure changes

- Both systems are flat: there is no project or container, and each object type migrates on its own.
- Organizations become companies, persons become contacts, deals stay deals, notes stay notes, and activities become tasks.
- Owners are reconciled by email in the first wave, so every record that follows lands on the right HubSpot user.
- Pipedrive inlines org_id and person_id on the record; HubSpot needs explicit associations, so contact-to-company, deal-to-company and deal-to-contact links are created in a second pass after both sides exist.
- Deal stages need a pipeline chosen and a value map filled in — this is asked before the run, not guessed.

## Entity map

| Pipedrive | HubSpot | Wave | Fields |
|---|---|---|---|
| User | Owner | 0 | 1 |
| Organization | Company | 1 | 3 |
| Person | Contact | 2 | 4 |
| Deal | Deal | 3 | 4 |
| Activity | Task | 4 | 2 |
| Note | Note | 4 | 1 |
| Deal | Association | 5 | 2 |
| Person | Association | 5 | 1 |

## Field coverage

### User → Owner

| Pipedrive field | HubSpot field | Coverage | Notes |
|---|---|---|---|
| `email` | `email` | Full | Owner reconciliation join key. Builds user_map: pipedrive user id -> hubspot owner id via email. |

### Organization → Company

| Pipedrive field | HubSpot field | Coverage | Notes |
|---|---|---|---|
| `name` | `properties.name` | Full |  |
| `address` | `properties.address` | Full |  |
| `owner_id` | `properties.hubspot_owner_id` | Workaround | Owner id remapped via user_map (email-reconciled at L0). |

### Person → Contact

| Pipedrive field | HubSpot field | Coverage | Notes |
|---|---|---|---|
| `name` | `properties.firstname` | Partial | Pipedrive stores a single `name`; HubSpot splits firstname/lastname. Full name placed in firstname unless first_name/last_name are present on the source. |
| `email` | `properties.email` | Partial | Pipedrive email is an array of {value,label,primary}; take the primary/first value. |
| `phone` | `properties.phone` | Partial | Phone is an array; take the primary/first value. |
| `owner_id` | `properties.hubspot_owner_id` | Workaround | Owner remap via user_map. |

### Deal → Deal

| Pipedrive field | HubSpot field | Coverage | Notes |
|---|---|---|---|
| `title` | `properties.dealname` | Full |  |
| `value` | `properties.amount` | Full | Keep currency paired via deal_currency_code. |
| `stage_id` | `properties.dealstage` | Workaround | Pipedrive numeric stage_id -> HubSpot dealstage (pipeline-scoped). Requires an explicit value_map; remap pipeline together. |
| `owner_id` | `properties.hubspot_owner_id` | Workaround | Owner remap via user_map. |

### Activity → Task

| Pipedrive field | HubSpot field | Coverage | Notes |
|---|---|---|---|
| `subject` | `properties.hs_task_subject` | Full |  |
| `due_date` | `properties.hs_timestamp` | Partial | Pipedrive due_date (date) -> HubSpot hs_timestamp (datetime). |

### Note → Note

| Pipedrive field | HubSpot field | Coverage | Notes |
|---|---|---|---|
| `content` | `properties.hs_note_body` | Full |  |

### Deal → Association

| Pipedrive field | HubSpot field | Coverage | Notes |
|---|---|---|---|
| `org_id` | `association:deal->company` | Workaround | Deal->Company association via id_map. |
| `person_id` | `association:deal->contact` | Workaround | Deal->Contact association via id_map. |

### Person → Association

| Pipedrive field | HubSpot field | Coverage | Notes |
|---|---|---|---|
| `org_id` | `association:contact->company` | Workaround | Convert inline org_id into a v4 association after both objects exist. |

## FAQ

**How do Pipedrive deal stages map to HubSpot?**

HubSpot deal stages are scoped to a pipeline, so a numeric Pipedrive stage_id cannot be translated without knowing which pipeline you want. The mapping is presented for confirmation during planning rather than inferred.

**Does Pipedrive to HubSpot keep the links between contacts, companies and deals?**

Yes. Pipedrive stores those as ids on the record itself; HubSpot needs v4 association objects. They are created in a final pass once both objects exist, so nothing points at a record that has not been written yet.

**What happens to a Pipedrive person's single name field?**

HubSpot splits names into firstname and lastname. Where Pipedrive exposes first and last name separately they are used directly; otherwise the single name field is split, which is flagged as lossy because the split is a guess.

---

Start a migration: https://app.migratly.dev/
