Migrating from HubSpot
HubSpot’s contact/company/deal model maps cleanly onto Primicornis when you treat objects as canonical and pipelines as opportunity graphs.
Source → Primicornis mapping
| HubSpot | Primicornis target |
|---|---|
| Contact | person (or custom) |
| Company | company or startup depending on thesis |
| Deal | opportunity with stage ↔ pipeline mapping |
| Owner | Map to workspace members via email before import |
| Associations | Use relation properties; maintain association labels as text metadata |
Property mapping checklist
- Export HubSpot properties with internal names (
hs_*, custom keys) — not display labels. - Build a dictionary
{ hubspot_internal_name → primicornis_property_key }. - Coerce enumerations (e.g., deal stage) to Primicornis
selectoptions before bulk insert.
Relationship order
person,company/startup- Link people ↔ companies (roles like founder, board)
opportunityrecords with foreign relations to company + champion contact
Deduplication
- Prefer HubSpot
record idstored in a dedicatedtextproperty (hubspot_id). - Upsert strategy:
IF EXISTS hubspot_id THEN PATCH ELSE POST.
CSV vs API migration
| Mode | When |
|---|---|
| CSV | Initial bulk load, historic archives |
| API | Incremental sync, nightly delta pulls from HubSpot (private apps) |
Gotchas
- Multi-currency deals — normalize to workspace currency before import.
- Marketing contacts — decide if they become
personrecords or stay in a marketing object; mixing inflates CRM noise. - Automated sequences — disable HubSpot workflows during cut-over week to avoid ghost updates.
API-flavored sketch
bash
# Pseudocode: create startup with external ref
curl -X POST "$API/ws/$WS/object-definitions/$STARTUP_ID/records" \
-H "Authorization: Bearer $PRIM_TOKEN" -H "Content-Type: application/json" \
-d '{"properties":{"name":"Nova Labs","hubspot_company_id":"123456"}}'
Validate each batch with GET queries filtered by your external ID field before moving stages in pipeline imports.