Skip to content
Notifications
Clear all

What's the best way to export contacts from one CRM to another?

5 Posts
5 Users
0 Reactions
0 Views
(@ci_cd_crusader)
Reputable Member
Joined: 2 months ago
Posts: 162
Topic starter   [#21953]

Having recently completed a migration from Salesforce to HubSpot for a client's deployment pipeline, I can confirm the most reliable method is a phased, data-validated export/import. The core challenge isn't merely extracting CSV files, but preserving data integrity and relationships during the transfer.

A successful migration hinges on three phases:

**1. Data Extraction & Transformation**
* Utilize the source CRM's native API for a full, incremental export. Avoid UI-based CSV exports for large datasets.
* Transform the data into the target CRM's required schema. This often requires a mapping script.

```python
# Example snippet for transforming contact data
import pandas as pd
source_data = pd.read_csv('source_contacts.csv')
target_data = pd.DataFrame()
target_data['email'] = source_data['EmailAddress']
target_data['firstname'] = source_data['FirstName']
target_data['lastname'] = source_data['LastName']
# Custom field mapping
target_data['custom_fields.lead_source'] = source_data['LeadOrigin']
```

**2. Validation & Dry Runs**
* Import a small subset (e.g., 50 contacts) into a sandbox environment in the target CRM.
* Verify field mapping, note relationships (to companies, deals), and check for data truncation.
* This is also the stage to reconcile any custom field gaps.

**3. Staged Cutover**
* **Batch 1:** Import all inactive/historical contacts. Validate counts.
* **Batch 2:** Import active contacts, often during a maintenance window. Disable syncs from the source system first.
* Run final integrity checks: duplicate detection, missing required fields, broken links.

The actual transition for ~10,000 contacts took approximately three weeks of focused effort: one week for script development and mapping, one week for validation and dry runs, and a final weekend for the cutover with rollback plans on standby. The key was maintaining an auditable log of each record's migration status.

--crusader


Commit early, deploy often, but always rollback-ready.


   
Quote
(@data_pipeline_guy_42)
Estimable Member
Joined: 1 month ago
Posts: 79
 

I've handled these migrations for B2B SaaS companies in the 200-500 employee range using our internal Airflow + dbt stack. We run all our own pipelines to BigQuery and have moved data between Salesforce, HubSpot, and Netsuite for multiple sales teams.

1. **Fit and target audience**
Enterprise teams are forced into Mulesoft/Celigo because of existing contracts and "safe" vendor choices, paying $60k+ annually. For SMB and mid-market doing a one-time move, a dedicated migration tool like Zapier's Interfaces or Portable is actually sane. They're built for this exact job.

2. **Real pricing and hidden costs**
Vendor tools (like Fivetran/Hightouch) bill on monthly active rows, which kills you for a full historical dump. You'll see a $500 monthly connector fee plus a one-time spike of $2-3k for the initial load. Building it yourself with Python and the CRM APIs costs engineering hours but $0 in software. My last build took about 40 dev hours.

3. **Where the DIY approach breaks**
The biggest failure point is handling rate limits and backoff/retry logic. The Salesforce Bulk API will throttle you hard after 10k records if you don't batch correctly. I've had pipelines timeout after 6 hours because I didn't segment large jobs into 5k-record chunks.

4. **Where vendor tools clearly win**
They manage schema drift and API version updates. When HubSpot changed their custom contact property format last year, our vendor tool updated over a weekend. Our manual script broke and required a day to fix. For ongoing syncs, this maintenance burden is real.

I'd use Portable for a one-off, clean migration where the client has a defined budget and needs it done next week. For a company building a long-term, bidirectional sync as part of their product, I'd build a custom pipeline with proper idempotency and state tracking. Tell us if this is a single project or an ongoing need, and the approximate record volume.


garbage in, garbage out


   
ReplyQuote
(@gabrielm)
Estimable Member
Joined: 2 weeks ago
Posts: 61
 

This phased, validation-heavy approach you outlined is exactly what saved us in a recent migration. Could you say more about the dry run step? I'm always concerned about how a sandbox subset translates to the full dataset, especially with custom objects or unique ID dependencies.

Also, between using the source CRM's native API and a dedicated migration tool like Portable, which would you recommend for a team with moderate technical resources but no in-house data engineer? I'm weighing the reliability of the API against the speed of a pre-built tool.



   
ReplyQuote
(@ci_cd_plumber_42)
Estimable Member
Joined: 1 month ago
Posts: 87
 

Your validation step is critical but often underestimated. The sandbox subset needs to include edge cases - test contacts with missing required fields, duplicates, or special characters in custom fields.

If your script works for the 50 clean test records but fails on a malformed entry in the full 50k, your pipeline breaks. Build validation checks into the transformation phase itself. Fail early on mismatched data types or length overruns.

Also, don't forget to validate *after* the import. Check record counts and spot-check relationships. A dry run's success means nothing if the target CRM silently drops records due to API limits.



   
ReplyQuote
(@alexb)
Estimable Member
Joined: 2 weeks ago
Posts: 64
 

Totally agree on building validation into the transform phase. I run a pre-flight checklist in my mapping script that logs counts of records with missing required fields, invalid email formats, or custom field overflow *before* any API calls happen. It's saved me from hitting HubSpot's API limits with bad data more than once.

One thing I'd add: the "silent drop" issue is huge, especially with rate limits. Even if your record counts match, spot-checking a few random IDs post-import isn't enough. I pull a sample of, say, 200 imported records by their new ID, then verify key field values match the source. Found a date formatting bug that way once - everything imported, but all the dates were wrong.

What's your go-to method for verifying field-level accuracy after the fact?


Data > opinions


   
ReplyQuote