Migration Playbook

Intercom HubSpot Service Hub

Intercom to HubSpot Service Hub: The Complete Migration Playbook

A 36-step runbook across six phases — track your progress, and open the right tool at every step.

0 / 36 steps complete 0%
TL;DR

Migrating Intercom to HubSpot Service Hub takes 3–8 weeks via API, not CSV. The biggest risks are broken inline images and multi-object association mapping.

Migrating from Intercom to HubSpot Service Hub has no native migration path and requires significant custom work due to fundamental architectural differences between the two platforms. Intercom uses a messenger-first, conversation-centric model where interactions are stored as threaded Conversation Parts, while HubSpot organizes support around CRM-integrated Tickets with separate Engagement records (notes, emails) linked via the Associations API. Each Intercom Conversation must be decomposed into one HubSpot Ticket plus multiple Engagement records, flat tags must be translated into structured pipeline stages or custom properties, and Intercom's API cap of 500 conversation parts per thread introduces potential data truncation for long histories.

Read this first

Pair-specific gotchas that catch teams out. Each one has cost somebody a weekend.

Do not map one Intercom thread to one giant HubSpot note

HubSpot notes cap hs_note_body at 65,536 characters. The durable pattern is one ticket per conversation and one note per message part — or chunked across multiple notes for long parts. (developers.hubspot.com)

Do not do one HubSpot search per Intercom record

At 5 searches/second, 100,000 lookups take about 5.6 hours before you create a single ticket. Preload contact, company, and owner lookup tables once, then write by ID. Always use batch endpoints (POST /crm/v3/objects/tickets/batch/create) instead of single-record creates — this alone can increase effective throughput by 50–100x.

Order-of-operations failure mode

If you load tickets before contacts, HubSpot will create the tickets but association calls will fail silently or throw 404 errors (response: {"status": "error", "message": "Object not found"}). You'll end up with thousands of orphaned tickets that require manual cleanup or a second migration pass.

Inline image breakage is the #1 post-migration regret

When you cancel your Intercom contract, Intercom deletes the CDN links, resulting in broken images across all historical HubSpot tickets. The only fix at that point is a re-migration — if you still have access to the data.

The runbook

Work top to bottom. Tick steps as you go — your progress is saved in this browser.

01 Discovery Establish why you are moving, what "done" means, and who signs off. 0/5

Objective A written scope with agreed success criteria, a named owner per workstream, and a budget approved by finance.

  1. Pull the real numbers out of Intercom

    Support ops 1 day

    Export counts for tickets (open and closed separately), contacts, organisations, attachments, macros, triggers, automations, views and SLA policies. Note the oldest ticket date — history depth drives the whole timeline. Estimating from memory is the single most common cause of a blown migration window.

    Data Profiler Get real record counts instead of estimating from memory
  2. Decide what history actually moves

    Support lead 2 days

    Agree a cut-off with the support lead: all history, last 24 months, or open tickets plus a read-only archive. Every extra year of closed tickets adds API time and cost without adding much agent value. Get this in writing — it is the decision people relitigate mid-cutover.

    A "move everything" default is what turns a two-week migration into a two-month one.

    COI & ROI Calculator Build the 36-month business case you will need for sign-off
  3. Confirm HubSpot Service Hub can hold your support model

    Solution architect 2-3 days

    Walk your current workflow through HubSpot Service Hub: multi-brand, business hours, SLA targets, CSAT, side conversations, public vs internal notes, and any channel you depend on (voice, chat, WhatsApp, social). List anything with no native equivalent — those are project risks, not configuration details.

  4. Build the business case

    Project sponsor 1-2 days

    Model licence delta, migration effort, agent retraining, and the cost of staying put (Cost of Inaction). Executives approve a number, not a plan, and you will be asked for it again at the go/no-go.

    Helpdesk Migration Planner Turn ticket volume into a dated Intercom → HubSpot Service Hub timeline
  5. Name owners and set the go/no-go date

    Project manager 1 day

    One named owner each for data, configuration, integrations, and agent enablement, plus a decision-maker who can call a rollback. Put the go/no-go meeting in calendars now, 48 hours before the freeze.

Intercom → HubSpot Service Hub specifics

Conversation Parts vs. Engagements
Intercom stores every message, note, and action as a conversation_part inside a single Conversation object. HubSpot stores communication as separate Engagement objects (emails, notes, calls) associated with a Ticket via the Associations API. You must decompose each Intercom Conversation into one Ticket plus N engagement records.
Flat tags vs. structured pipelines
Intercom uses Tags and custom attributes for categorization. HubSpot uses Ticket Pipelines with defined Stages, plus custom properties. There is no automatic mapping — every tag must be translated into either a pipeline stage, a property value, or a HubSpot tag.
History cap
Intercom's API returns only the 500 most recent conversation parts for a conversation, so very long threads need a fallback plan — either a legacy archive, exported text/PDF, or accepted truncation. (developers.intercom.com)

Don't move on until

  • Record counts confirmed for tickets, contacts, organisations and macros
  • Success criteria signed off by the support lead
  • Freeze window provisionally booked with the business
02 Data Audit Find out what is actually in the data before you try to move it. 0/6

Objective A profiled, cleaned export with every quality defect either fixed at source or explicitly accepted.

  1. Take a full Intercom export and profile it

    Data engineer 1-2 days

    Export to CSV or JSON and profile every file: row counts, null rates per column, distinct values, and type consistency. Compare row counts against the API totals from Discovery — a gap here means your export is silently truncated, usually by pagination.

    Data Profiler Profile the Intercom export for nulls, outliers and type drift
  2. Validate file structure before anyone writes a transform

    Data engineer 1 day

    Check delimiters, quoting, encoding (expect UTF-8, watch for BOMs and Latin-1), duplicate headers, and embedded newlines in ticket bodies. Ticket descriptions with raw newlines and commas break naive CSV parsers and silently shift columns.

    A single unescaped quote in one ticket body can shift every subsequent column without any error.

    CSV Validator Catch broken headers and ragged rows in the raw export
  3. Inventory PII and set retention

    Compliance / DPO 2 days

    Scan for emails, phone numbers, payment card fragments, national IDs and anything else regulated in ticket bodies and custom fields — support tickets are where customers paste things they should not. Decide what gets migrated, masked, or dropped, and record the legal basis.

    Ticket bodies and attachments routinely contain card and ID data that never appears in a structured field.

    PII & Compliance Scanner Find regulated fields before they land in a new system
  4. Quantify duplicates, orphans and dead references

    Support ops 1-2 days

    Count duplicate contacts (same email, different casing), tickets whose requester no longer exists, organisations with no members, and attachments whose parent ticket is gone. Fix these in Intercom where you can — migrating them just moves the mess.

    Data Cleaner Strip empty rows, stray whitespace and dead columns
  5. Clean and normalise the export

    Data engineer 2 days

    Trim whitespace, drop empty rows and columns, normalise casing on emails and tags, and standardise every timestamp to UTC ISO 8601. Timezone drift is invisible at load time and shows up weeks later as SLA reports nobody can reconcile.

  6. Produce a masked copy for sandbox work

    Data engineer 0.5 day

    Generate a realistic but fake version of the export for testing and for any vendor who needs sample data. Loading real customer PII into a sandbox is a breach in most jurisdictions, and sandboxes are rarely covered by your DPA.

    PII Masker Generate a safe copy for sandbox and vendor testing

Don't move on until

  • Export parses cleanly with no ragged rows or encoding errors
  • PII inventory complete and retention decisions recorded
  • Duplicate and orphan records quantified and triaged
03 Field Mapping Turn two schemas into one signed-off mapping spec. 0/7

Objective A reviewed field-level mapping covering every object, with an explicit decision for every field that has no target.

  1. Generate the first-pass Intercom → HubSpot Service Hub field map

    Solution architect 2 days

    Start from an automated match on both schemas, then review every row by hand. Automated matching gets the obvious 70% right and is confidently wrong on the rest — especially anything named "type", "status" or "custom_field_1".

    Schema Mapper Opens pre-loaded with the Intercom → HubSpot Service Hub field pair
  2. Map status, priority and channel values, not just field names

    Support lead 1-2 days

    Enumerate every value in each picklist on both sides and map them explicitly. Value-level mismatches are the defect class that survives all the way to production because the field itself mapped fine — a ticket that should be "Pending" arriving as "Open" reopens SLA clocks.

    Statuses with no target equivalent (on-hold, pending-customer) need a policy decision, not a best guess.

  3. Decide how custom fields land

    Solution architect 2 days

    Create the target custom fields first, matching type exactly (a dropdown mapped to free text can never be mapped back). Where HubSpot Service Hub has no equivalent, decide between a new custom field, a tag, or a note appended to the ticket body — and record which.

  4. Resolve identity and threading

    Data engineer 1 day

    Decide how source IDs are preserved — most platforms will not let you set the primary key, so keep the original ID in a custom field. Without it, reconciliation becomes fuzzy matching and every future support question about an old ticket is unanswerable.

    Losing the original ticket ID makes reconciliation and rollback effectively impossible.

  5. Plan attachments, inline images and threading order

    Data engineer 1-2 days

    Confirm size limits, allowed MIME types, and whether inline images survive as attachments or need rehosting. Decide the comment ordering and author attribution rules: comments loaded out of order, or all attributed to the API user, destroy the conversation history agents rely on.

  6. Freeze and sign off the mapping spec

    Project manager 1 day

    Version the spec, walk the support lead through it row by row, and get explicit sign-off. Any change after this point goes through change control — mid-flight mapping edits are how partial loads happen.

  7. Download all inline images

    from Intercom's CDN (.intercom-attachments.com) and upload to HubSpot's File Manager API. Replace image URLs in conversation HTML. File import from URL is async — build your queue accordingly. Use GET to poll the import status until complete before referencing the file in note bodies.

Don't move on until

  • Every source field is mapped, deliberately dropped, or parked in a custom field
  • Status, priority and channel value maps agreed with the support lead
  • Mapping spec version-controlled and signed off
04 Test Migration Prove the pipeline on a small, representative slice. 0/6

Objective A pilot load into a HubSpot Service Hub sandbox that reconciles cleanly and has been reviewed by real agents.

  1. Stand up a HubSpot Service Hub sandbox that matches production config

    Solution architect 2-3 days

    Create the custom fields, groups, brands, business hours and SLA policies first. A pilot into a default sandbox tests nothing, because the failures you care about are all configuration mismatches.

  2. Pick a deliberately nasty pilot sample

    Data engineer 0.5 day

    Take 500-1000 records chosen for difficulty, not convenience: the longest ticket threads, tickets with the most attachments, non-Latin character sets, merged and split tickets, deleted requesters, and every status value. A clean random sample proves only that easy records are easy.

  3. Run the load with masked data and instrument everything

    Data engineer 1-2 days

    Log every API request and response with its source record ID. When 40 records fail out of 10,000 you need to know exactly which ones and why, without re-running the whole batch.

    PII Masker Never load real customer PII into a sandbox
  4. Measure real throughput against the rate limit

    Data engineer 1 day

    Record achieved records-per-hour under HubSpot Service Hub's actual rate limits, including retries and backoff. Extrapolate to the full volume: if the maths says the full load exceeds your freeze window, you fix that now, not on cutover night.

    Published rate limits are ceilings, not throughput. Assume real-world rates are meaningfully lower once retries and backoff are counted.

  5. Reconcile the pilot and triage every failure

    Data engineer 1-2 days

    Diff source against target on record counts and field-level values. Every discrepancy gets a root cause and a fix — "probably fine" at pilot scale becomes thousands of broken records at full scale.

    Migration Validation Tool Diff the pilot batch against source before scaling up
  6. Put real agents in front of the pilot data

    Support lead 2 days

    Have two or three agents work sample tickets end to end in the sandbox. They find the things reconciliation cannot see: unreadable threading, missing context, macros that no longer make sense. Fix the mapping, then re-run.

Don't move on until

  • Pilot batch reconciles to 100% on record counts
  • Agents have reviewed sample tickets and confirmed they are workable
  • Measured throughput extrapolates to a viable full-load window
05 Cutover Execute the switch inside a controlled, reversible window. 0/6

Objective All in-scope data live in HubSpot Service Hub, agents working in the new system, and a rollback path that stayed available throughout.

  1. Pre-load history before the freeze

    Data engineer 3-10 days

    Load closed tickets and contacts days or weeks ahead while Intercom stays live. Only open tickets and the final delta need to move inside the freeze — this is the single biggest lever on window length.

    Helpdesk Migration Planner Size the freeze window from HubSpot Service Hub's real API limits
  2. Publish the runbook with times, owners and abort criteria

    Project manager 1 day

    A timed sequence: freeze start, final export, delta load, channel switch, smoke test, go/no-go, agent switch. Name who does each step and the explicit condition that triggers a rollback. Decide the abort criteria before the night, when nobody wants to be the one to call it.

  3. Freeze Intercom and take the final delta

    Support ops 2-4 hours

    Stop new ticket creation, let agents finish in-flight replies, then export everything changed since the pre-load. Announce the freeze to the whole business, not just support — someone always tries to raise a ticket during it.

    Tickets created during an unenforced freeze land in the old system and are the most common source of permanently lost data.

  4. Load the delta and open tickets

    Data engineer 2-6 hours

    Run the delta load, then reconcile counts before touching any channel. Do not repoint email until the delta has verified — an inbound ticket arriving mid-load is far harder to untangle than a few extra minutes of freeze.

    Migration Validation Tool Confirm the final delta landed before you reopen
  5. Repoint channels and verify with live traffic

    IT / integrations 2-4 hours

    Switch email forwarding and MX or connector settings, update chat widgets and web forms, and re-authorise integrations. Then send real test tickets through every channel and confirm each lands, routes and triggers the right automation.

    Email forwarding changes can take up to a full DNS TTL to propagate — check the TTL days in advance and lower it if needed.

    Cron Expression Builder Schedule the delta syncs that run through the freeze
  6. Run the go/no-go and switch the agents

    Project sponsor 1-2 hours

    Walk the exit criteria with the decision-maker, call it explicitly, then move agents over with a named person on hand for the first few hours. Keep Intercom read-only rather than cancelled — cancelling the old contract on day one removes your only fallback.

Don't move on until

  • Full historical load complete and counts matched
  • Inbound channels repointed and verified with live test tickets
  • Rollback decision point passed explicitly, not by default
06 Validation Prove the migration is complete, then close it out. 0/6

Objective Documented evidence that data, workflow and reporting all survived, and a signed acceptance.

  1. Run the full reconciliation

    Data engineer 1-2 days

    Compare source and target on every object: total counts, counts by status, counts by group, attachment counts, and field-level spot checks on a random sample. Produce one report you can hand to an auditor.

    Migration Validation Tool Reconcile Intercom and HubSpot Service Hub record-for-record
  2. Verify field completeness, not just record counts

    Data engineer 1 day

    Re-profile the loaded data and compare null rates per field against the source profile. Matching record counts with a field that silently arrived empty is the failure mode counts alone will never catch.

    Data Profiler Prove field completeness held up through the load
  3. Rebuild reporting and compare against baselines

    Support ops 2-3 days

    Recreate your core dashboards — volume, first response time, resolution time, CSAT — and compare to pre-migration figures for the same period. Explain every variance; a changed SLA calculation is a real finding, not a rounding error.

    SLA and first-response metrics are usually recalculated from the loaded timestamps, so they will differ if any timestamp mapping was approximate.

  4. Test the workflow layer end to end

    Support ops 2 days

    Fire every trigger, automation, SLA escalation, macro and notification with a live ticket. Workflow does not migrate — it gets rebuilt — so it is untested until someone has actually watched it run.

  5. Confirm compliance and produce the audit trail

    Compliance / DPO 1 day

    Re-scan the loaded data for regulated fields, confirm retention and deletion policies are configured in HubSpot Service Hub, and file the evidence with your PII decisions from the audit phase.

    PII & Compliance Scanner Produce the compliance evidence your auditor will ask for
  6. Sign off, then decommission on a schedule

    Project sponsor 1 day

    Get written acceptance against the Discovery success criteria. Keep Intercom read-only for an agreed period (30-90 days is typical), take a final archive export, and only then cancel. Diarise the decommission date so it does not quietly renew.

Don't move on until

  • Full reconciliation report attached to the project record
  • Reporting baselines match pre-migration figures within agreed tolerance
  • Formal acceptance signed and archive retention scheduled

Field mapping reference

The field-by-field mapping for each object. Use this as the starting point for your mapping spec.

How Does Intercom Data Map HubSpot Service Hub 13 fields
Intercom fieldHubSpot Service Hub fieldNotes
Contact (User/Lead) Contact Map on email as the dedup key. Intercom distinguishes Users vs. Leads by role; HubSpot uses Lifecycle Stage. Contacts without emails create orphaned records — decide in advance whether to skip, assign a placeholder, or merge them.
Company Company Use company_id or domain for matching. Intercom allows multiple companies per contact; HubSpot supports this via Associations. Intercom's CSV user export only includes the most recent company name and ID — use API data when relationships matter. (intercom.com)
Conversation Ticket + Engagements One Conversation becomes one Ticket. Individual messages (Conversation Parts) become Engagements (Notes or Emails) tied to the Ticket. Pipeline and Stage must be explicitly set. Intercom returns only the 500 most recent parts per conversation. (developers.intercom.com)
Conversation Parts Engagements (Notes / Emails) Each Part becomes a Note or Email engagement associated with the Ticket. Preserve created_at timestamps as hs_timestamp. Internal notes must map to HubSpot Note engagements — not external emails — to prevent accidental customer exposure.
Admins / Teammates Users / Owners Map by email. Intercom Admin IDs do not transfer. HubSpot Users must be created and active before migration so historical tickets can be assigned to them. If no matching HubSpot owner exists, store the Intercom assignee in a custom text field.
Teams Teams Manual setup in HubSpot first; then assign Ticket ownership by team.
Tags Custom Properties No native tag object on HubSpot tickets. Map to a multi-select custom property or single-select category depending on your reporting needs.
Articles (Help Center) Knowledge Base Articles HTML formatting requires deep cleaning. Intercom's proprietary blocks (buttons, dividers) often break in HubSpot's editor. No bulk API import for HubSpot KB articles — must be recreated via custom script against the CMS API.
Custom Attributes Custom Properties Create matching properties in HubSpot before import. Data type mapping: Intercom string → HubSpot single-line text, integer/float → number, boolean → checkbox, date → date, list → dropdown/multi-select.
Intercom Tickets Tickets (separate pipeline) Intercom's newer Tickets feature maps more directly to HubSpot Tickets, but Ticket Types become pipeline definitions and carry their own attributes.
Custom Objects Custom Objects (Enterprise only) Requires HubSpot Enterprise. Schema must be defined before migration.
Attachments Files + Note attachments Upload to HubSpot's File Manager, then attach to a note using hs_attachment_ids. File import from URL is async, and HubSpot does not support uploading multiple files in one request. (developers.hubspot.com)
CSAT Scores Custom Property Intercom's native CSAT ratings do not map to HubSpot's standard CSAT object. Create a custom property on the Ticket (e.g., "Legacy Intercom CSAT") to store historical data.

Risk matrix

Per-object risk for this pair. Plan extra validation around anything marked high.

ObjectRiskNotes
Contacts low Contacts map well between platforms using email as the dedup key, though contacts without email addresses will create orphaned records requiring a skip-or-placeholder decision.
Companies low Companies can be matched on domain or company ID, and HubSpot supports Intercom's multi-company-per-contact model via Associations, though CSV exports only include the most recent company.
Conversations (Tickets) high Decomposing each conversation into a ticket plus individual engagement records is complex, rate-limit-sensitive, and subject to the 500-part API cap that may truncate long threads.
Conversation Parts (Engagements) high Each message part must be created as a separate Note or Email engagement with correct timestamp conversion and association, and internal notes must be carefully mapped to prevent accidental customer exposure.
Tags medium Tags have no native equivalent on HubSpot tickets and must be mapped to custom multi-select or single-select properties, requiring upfront property creation and value alignment.
Custom Attributes medium Custom attributes require pre-creation of matching HubSpot properties with explicit type definitions, and any picklist value not in the predefined option list will be silently rejected.
Knowledge Base Articles high No bulk import API exists for HubSpot Knowledge Base articles, Intercom's proprietary HTML blocks break in HubSpot's editor, and each article must be recreated via custom CMS API scripts.
Attachments medium Files must be uploaded to HubSpot's File Manager individually (no multi-file requests), then linked to notes via attachment IDs, with async processing adding complexity.
CSAT Scores medium Intercom's native CSAT ratings do not map to any standard HubSpot object and must be stored in a custom ticket property, losing native reporting integration.
Admins / Teammates low Admins map to HubSpot Users by email, but all target users must be created and active before migration so historical tickets can be properly assigned.

The hard parts

What makes this specific migration difficult, beyond the mechanics.

Conversation Parts Decomposition

Every Intercom Conversation must be split into one HubSpot Ticket plus N individual Engagement records (notes or emails), as HubSpot has no single threaded-conversation object equivalent.

Tags to Pipeline Mapping

Intercom's flat tag-based categorization has no automatic mapping to HubSpot's structured Ticket Pipelines, Stages, and custom properties, requiring manual translation of every tag.

Timestamp Format Mismatch

Intercom timestamps use Unix epoch in seconds while HubSpot expects milliseconds, and failing to convert causes silent date corruption that places records in January 1970.

Conversation History Truncation

Intercom's API returns only the 500 most recent conversation parts per conversation, requiring a fallback archival strategy for long-running threads.

Knowledge Base Rebuilding

HubSpot lacks a bulk API import for Knowledge Base articles, so Intercom Help Center content must be recreated via custom scripts with deep HTML cleaning to handle proprietary block elements.

Note Body Character Limits

HubSpot's note body field caps at 65,536 characters, so long Intercom conversation parts must be chunked across multiple note engagements to avoid silent data loss.

Tools used in this playbook

All free, all run entirely in your browser — nothing is uploaded.

FAQ

How long does an Intercom to HubSpot Service Hub migration take?

A typical migration takes 3–8 weeks end-to-end, including scoping, field mapping, script development, test migration, and production run. The actual data transfer for 100K conversations takes 1–2 days of API processing time. Calendar time is driven by mapping decisions and validation, not data volume.

Can I migrate Intercom conversations to HubSpot without losing data?

Yes, but only via the API — not CSV imports. Native CSV imports cannot carry conversation content or multi-object associations. API-based migration preserves conversation parts as engagement records with timestamps and author attribution. Inline images require explicit download and re-hosting to avoid permanent breakage when Intercom is deactivated.

What data cannot be migrated from Intercom to HubSpot Service Hub?

Intercom Workflows, Fin AI configuration, Product Tours, Series, Messenger Apps, and behavioral events cannot be migrated programmatically. These must be manually rebuilt using HubSpot Workflows, Chatflows, and Breeze Customer Agent. Conversation ratings also have no direct equivalent and should be stored as custom properties.

Will my HubSpot Workflows fire during migration?

Yes. Any active Workflow with enrollment triggers like 'Ticket is created' or 'Contact property is updated' will fire on every migrated record, potentially sending thousands of unwanted emails. Always disable enrollment-based Workflows before starting the migration and re-enable them after validation.

Do I need HubSpot Enterprise to migrate from Intercom?

No. HubSpot Service Hub Professional is sufficient for most migrations. Enterprise is only required if you need Custom Objects (to map Intercom Custom Objects) or Custom Behavioral Events (to map Intercom Events). The ticket, contact, company, and engagement APIs are available on Professional and above.

Or skip all of this and let us handle it

Book a 30-minute call and we'll scope your migration in a single session.