Migratly migrates Pipedrive to HubSpot by reading both APIs, deriving the mapping between them, and showing you what it found before anything is written. For this pair that is 8 entity types and 18 field mappings, of which 7 carry across intact and 11 are flagged as lossy, partial, dropped, or needing a route other than the obvious one. 4 of them need a decision from you. The Pipedrive side is read-only throughout — Migratly never writes to or deletes from your source.
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_idandperson_idon 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.
What maps to what
Entities are written in dependency waves. Everything at wave 0 exists before anything at wave 1 is created, which is what makes cross-references resolvable and the whole run resumable from a cursor.
| Pipedrive | HubSpot | Wave | How it is handled | Fields |
|---|---|---|---|---|
| User | Owner | 0 | accounts matched before anything is written | 1 |
| Organization | Company | 1 | the records themselves | 3 |
| Person | Contact | 2 | the records themselves | 4 |
| Deal | Deal | 3 | the records themselves | 4 |
| Activity | Task | 4 | the records themselves | 2 |
| Note | Note | 4 | the records themselves | 1 |
| Deal | Association | 5 | links between records, resolved last | 2 |
| Person | Association | 5 | links between records, resolved last | 1 |
Field-by-field coverage
Every mapping carries one of five labels. Full means it carries across intact. Partial means the value survives with a narrowed range. Lossy means something is lost. Workaround means there is no native slot and it is carried another way. Dropped means the target will not accept it. Anything short of full is shown to you before the run, not discovered afterwards.
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. Asks you first |
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). Asks you first |
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. Asks you first |
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. Asks you first |
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. |
What does not carry across cleanly
These are the 11 mappings where HubSpot cannot hold what Pipedrive holds. Each one appears in your coverage report with the same reason, and with the alternative routes available.
owner_idWorkaround
Owner id remapped via user_map (email-reconciled at L0).namePartial
Pipedrive stores a single `name`; HubSpot splits firstname/lastname. Full name placed in firstname unless first_name/last_name are present on the source.emailPartial
Pipedrive email is an array of {value,label,primary}; take the primary/first value.phonePartial
Phone is an array; take the primary/first value.owner_idWorkaround
Owner remap via user_map.stage_idWorkaround
Pipedrive numeric stage_id -> HubSpot dealstage (pipeline-scoped). Requires an explicit value_map; remap pipeline together.owner_idWorkaround
Owner remap via user_map.due_datePartial
Pipedrive due_date (date) -> HubSpot hs_timestamp (datetime).org_idWorkaround
Convert inline org_id into a v4 association after both objects exist.org_idWorkaround
Deal->Company association via id_map.person_idWorkaround
Deal->Contact association via id_map.
Decisions you will be asked to confirm
Migratly stops and asks rather than guessing when the right answer depends on your instance.
email→email
Owner reconciliation join key. Builds user_map: pipedrive user id -> hubspot owner id via email.owner_id→properties.hubspot_owner_id
Owner id remapped via user_map (email-reconciled at L0).name→properties.firstname
Pipedrive stores a single `name`; HubSpot splits firstname/lastname. Full name placed in firstname unless first_name/last_name are present on the source.stage_id→properties.dealstage
Pipedrive numeric stage_id -> HubSpot dealstage (pipeline-scoped). Requires an explicit value_map; remap pipeline together.
How a Pipedrive to HubSpot migration runs
- Connect both systems. Pipedrive is connected read-only. Migratly never writes to, archives or deletes anything on the source side.
- Schema discovery. Both APIs are read live, including your custom fields, so the mapping reflects your instance rather than a generic Pipedrive instance.
- Coverage report. All 18 mappings are presented with their coverage. You confirm, reroute or exclude before anything is written.
- Execution in 6 waves. Writes are idempotent and cursor-tracked, so an interrupted run resumes instead of restarting or duplicating.
- Verification. The result is checked back against the source, and every action is in an append-only audit log.
Questions
Can Migratly migrate Pipedrive to HubSpot?
Yes. Pipedrive to HubSpot is a supported pair with a mapping covering 8 entity types and 18 fields. You connect both systems, Migratly reads the live schemas on each side, and it produces a coverage report you approve before any data moves.
What is lost when migrating from Pipedrive to HubSpot?
11 of the 18 field mappings for this pair are flagged rather than clean. For example, `owner_id` is marked workaround: Owner id remapped via user_map (email-reconciled at L0). Every flagged mapping appears in the coverage report before the run, with its reason and the routes still open to it. Nothing is dropped silently.
How long does a Pipedrive to HubSpot migration take?
It is bounded by the two APIs' rate limits rather than by Migratly. This pair runs in 6 dependency waves, starting with account matching and ending with cross-references, and every wave is resumable — a run interrupted halfway continues from its cursor rather than starting over or duplicating what it already wrote.
Is my Pipedrive data modified during the migration?
No. The source is read-only for the entire run. Migratly never writes to, archives, or deletes anything in Pipedrive, and every action taken against HubSpot is written to an append-only audit log.
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.