Skip to content

Help Scout to HubSpot Service Hub Migration: Technical Guide

Migrate Help Scout to HubSpot Service Hub without losing conversation history. API limits, object mapping, step-by-step architecture, and realistic timelines.

Nachi Nachi · · 19 min read
Help Scout to HubSpot Service Hub Migration: Technical Guide
TALK TO AN ENGINEER

Planning a migration?

Get a free 30-min call with our engineers. We'll review your setup and map out a custom migration plan — no obligation.

Schedule a free call
  • 1,500+ migrations completed
  • Zero downtime guaranteed
  • Transparent, fixed pricing
  • Project success responsibility
  • Post-migration support included
Info

TL;DR: A Help Scout to HubSpot Service Hub migration requires API-based extraction — Help Scout's native CSV export strips all conversation thread contents, message bodies, and internal notes. Because Help Scout uses a flat conversation/thread model and HubSpot uses a relational ticket-to-engagement architecture, a 1:1 import is impossible. Workflows, saved replies, and Beacon configurations must be rebuilt manually. Expect 2–4 weeks for most accounts. DIY is viable for teams with under 10K conversations and a dedicated engineer; beyond that, a managed migration service significantly reduces re-work risk.

What Is a Help Scout to HubSpot Service Hub Migration?

A Help Scout to HubSpot Service Hub migration moves conversations, customers, tags, custom fields, attachments, and knowledge base articles from Help Scout's shared-inbox model into HubSpot's CRM-native ticketing system. Teams make this move to unify sales, marketing, and support data into a single contact timeline — when agents can see a customer's deals, marketing touchpoints, and support history in one place, resolution times drop and context gaps disappear.

This is not a simple CSV import. The two platforms use fundamentally different data architectures. The full Help Desk workspace — including SLA management, custom views, and omnichannel routing — requires Service Hub Professional ($100/seat/month as of 2024) or Enterprise ($130/seat/month). Service Hub Starter supports basic ticketing but lacks SLAs, custom reporting on ticket properties, and multiple pipelines. Plan your target tier before designing the migration (developers.hubspot.com).

Important platform distinction: HubSpot ships two ticket experiences. The legacy Tickets interface (Settings → Tickets) stores tickets as standalone CRM objects. The Help Desk workspace (released 2024) adds a unified inbox with threaded conversations, SLA tracking, and routing. Tickets created via the API appear in the legacy Tickets view by default. To appear in the Help Desk workspace, tickets must have at least one properly associated conversation thread (email engagement). During migration testing, verify that your API-created tickets surface in both views. For a deeper look at HubSpot's CRM architecture, see our CTO's guide to Salesforce vs HubSpot architecture.

Help Scout vs. HubSpot Service Hub: The Data Model Mismatch

The core architectural difference: Help Scout treats a Conversation as the primary object with Threads nested inside it. A Conversation is the container; the actual messages, notes, and state changes are Threads with types like message, note, phone, chat, and lineitem. HubSpot uses a flat CRM object model where Tickets are top-level objects and conversation history is represented through associated Engagements — emails, notes, and calls. Each engagement is its own CRM object, linked to the ticket via an association.

A single Help Scout Conversation with 12 threads becomes 1 HubSpot Ticket + 12 separate Engagement objects + the associations connecting them to each other and to the Contact. There is no single API call that handles this mapping.

From HubSpot's public import surfaces, the safe assumption is ticket plus associated timeline history — not a promise to recreate every Help Scout thread as a native Help Desk conversation tab. Design your migration around that constraint from the start.

Authentication: Help Scout OAuth2 Setup

Help Scout Mailbox API v2 requires OAuth2 authentication — the older API key method is deprecated and no longer supported. Before writing any extraction code:

  1. Create an OAuth2 application in Help Scout under Your Profile → My Apps.
  2. Use the Authorization Code flow for interactive apps, or the Client Credentials flow for server-to-server migration scripts (no user context required).
  3. Token endpoint: POST https://api.helpscout.net/v2/oauth2/token with grant_type=client_credentials, client_id, and client_secret.
  4. Access tokens expire after 48 hours. Implement automatic refresh logic in your extraction pipeline.

All API examples in this guide assume a valid Bearer token in the Authorization header.

Object & Field Mapping

The practical mapping below is what most teams end up shipping. It reflects both platforms' actual data models and the transformations required between them (developer.helpscout.com).

Help Scout Object HubSpot Object Notes & Caveats
Conversation Ticket Core support record. Map status (active/pending/closed) → pipeline stage. Store Help Scout conversation ID in a custom legacy_conversation_id property.
Thread: customer/agent reply Email Engagement Body → hs_email_text. Set hs_email_direction (INCOMING_EMAIL for customer, FORWARDED_EMAIL for agent). Timestamps must be ISO 8601. Associate to both ticket and contact. HubSpot sorts timeline by hs_timestamp — incorrect timestamps silently reorder conversations.
Thread: note Note Engagement Body → hs_note_body. Associate to ticket. Internal notes stay internal.
Thread: phone Call Engagement Preserve call body and timestamp. No clean equivalent for chat threads — flatten to notes.
Thread: lineitem Note (flattened) No clean 1:1 object in HubSpot. Flatten assignment changes, merge events, forward markers, and workflow actions into readable audit text.
Customer Contact Email is the dedup key. Help Scout allows multiple emails per customer; map secondary emails to HubSpot's secondary email property. Carry a legacy_customer_id.
Organization / Company Company Map to domain or name. Associate contacts afterward. Disable HubSpot's automatic company creation before loading or you will create duplicates from contact email domains.
Mailbox Ticket Pipeline or Custom Property Use pipeline only if the mailbox represents a different lifecycle, not just a queue.
Tags Multi-select Custom Property HubSpot tickets don't have a native tags object. Create a multi-select dropdown and pre-populate all option values before loading. Normalize spelling and case first.
Custom Fields Custom Ticket Properties Must create properties in HubSpot first. Match field types (dropdown, text, number, date). Map dropdown options through internal IDs, not display text. Help Scout custom fields are mailbox-scoped — if a conversation moved between mailboxes, custom field data may be missing.
Attachments File Manager + hs_attachment_ids Upload to HubSpot File Manager, then reference file IDs on the engagement. Set access to PRIVATE at upload time — uploads default to PUBLIC_INDEXABLE if not specified.
User Owner Map deactivated Help Scout users to a generic "Legacy Agent" owner in HubSpot so historical tickets aren't orphaned.
Saved Replies Snippets No API migration path. Rebuild manually.
Workflows HubSpot Workflows No migration path. Inventory and rebuild from scratch.
Docs (KB articles) Knowledge Base Articles Separate workstream. See the Knowledge Base Migration section below.
Satisfaction Ratings Custom Property Score can be stored as a custom ticket property. Free-text comments are excluded from Help Scout's native export but available via the API's thread data.

Two field rules that trip teams up:

  1. HubSpot ticket creation requires subject, hs_pipeline_stage, and (when using multiple pipelines) hs_pipeline — and those values must be internal IDs, not display labels. Retrieve internal IDs via GET /crm/v3/pipelines/tickets.
  2. Help Scout dropdown custom fields use mailbox-scoped option IDs. You need a lookup table to transform these into HubSpot enum values before loading.

Why DIY CSV Exports Fail (The Help Scout Export Trap)

Help Scout's built-in reporting export produces CSV or XLSX files with conversation metadata — subject, status, assignee, dates, tags, custom fields — but explicitly excludes conversation thread contents, message bodies, and satisfaction rating comments. This is documented directly by Help Scout:

"Your export will contain all data about each conversation included in your parameters, except the conversation thread contents." (docs.helpscout.com)

Any migration that starts with Help Scout's UI export will lose 100% of conversation history. No replies, no internal notes, no attachments. You get a spreadsheet of ticket metadata with no actual support content.

A CSV route works for low-stakes metadata migration or reporting, but it cannot reconstruct the back-and-forth your agents need. To extract full thread bodies and attachments, you must use the Help Scout Mailbox API v2. There is no workaround.

HubSpot's import tools are still useful on the load side — HubSpot can import records, activities, and associations — but that does not fix the source-side export gap. HubSpot also notes that existing emails, meetings, notes, and tasks cannot be updated via import (knowledge.hubspot.com).

API Limits & Throughput Math [For Engineering]

Help Scout Extraction Limits

The Help Scout Mailbox API v2 enforces plan-based rate limits that apply across all API consumers on the same account — parallel workers share the same budget (docs.helpscout.com):

Plan Rate Limit Notes
Standard 200 req/min Writes count double against this budget
Plus 400 req/min Writes count double
Pro 800 req/min Writes count double

The List Conversations endpoint (GET /v2/conversations) paginates at 25 records per page. For each conversation, you need a separate call to GET /v2/conversations/{id}/threads to retrieve full thread bodies. That's a minimum of 2 API calls per conversation — more if attachments need to be downloaded individually.

Throughput math (Standard plan): At 200 req/min with 2 calls per conversation, you extract ~100 conversations/minute or ~6,000 conversations/hour. A 50,000-conversation account takes roughly 8–9 hours of continuous extraction. Those numbers are before attachment downloads, customer lookups, merged-record retries, or validation.

Throughput math (Pro plan): At 800 req/min, extraction scales to ~400 conversations/minute or ~24,000/hour. A 200,000-conversation account: ~8.3 hours of extraction, plus attachment download time.

HubSpot Load Limits

HubSpot uses a burst-based rate limit model:

Plan Burst Limit (10 sec) Daily Limit Search API
Free/Starter 100 req/10 sec 250,000/day 4 req/sec
Professional/Enterprise 190 req/10 sec 500,000–1,000,000/day 5 req/sec

HubSpot's batch endpoints (/crm/v3/objects/tickets/batch/create) accept up to 100 records per call and count as a single request against the burst limit. This makes batch endpoints mandatory for any migration above a few thousand records.

Practical throughput (Professional): Using batch endpoints for ticket creation is fast — theoretically 19 batch calls/10 seconds × 100 tickets/call = 1,900 tickets per 10-second window. But the real bottleneck is engagement creation and association calls. Each ticket requires creating 5–15 engagements and 10–30 associations. In practice, expect 2,000–5,000 fully-hydrated tickets per hour (ticket + threads + associations), depending on thread density.

HubSpot also noted that the Associations API remained on earlier burst limits when the 190-per-10-second increase shipped, so association-heavy backfills deserve their own throttle lane (developers.hubspot.com).

Warning

The Search API bottleneck: HubSpot's CRM Search API is limited to 4–5 requests per second — separate from the general burst limit. If your migration script uses search for dedup checks before each insert, this becomes the binding constraint. Newly created records may also take up to 30 seconds to appear in search results due to indexing lag. Build unique legacy_*_id properties, use batch upsert or batch read by ID, and keep search for exception handling only.

Migration Approaches: Scripts vs. Tools vs. Services

Approach How It Works Best For Thread History Scalability Complexity (for you)
HubSpot CSV Import Export CSV from Help Scout → import via HubSpot import tool Never — loses all thread content ❌ Lost Small only Low
Third-Party Tool (Help Desk Migration, Import2) Wizard-based SaaS reads Help Scout API, writes to HubSpot Small accounts with standard mappings ✅ Preserved Up to ~100K conversations Low–Medium
Custom API Scripts (Python/Node) In-house ETL pipeline using both APIs Teams with API experience and spare capacity ✅ Preserved Any volume High
iPaaS / Sync Platform Integration platform for ongoing sync after backfill Coexistence scenarios, not one-time archives Varies Ongoing sync Medium
Managed Migration Service Dedicated engineers handle extraction, transformation, loading, and QA Complex mappings, large volumes, compliance needs ✅ Preserved Enterprise Low

Recommendations:

  • Small business (<10K conversations, no custom fields): A third-party tool like Help Desk Migration can work, but verify its HubSpot coverage — some tools have documented gaps around inline images, CC fields, and user conversation associations.
  • Mid-market (10K–100K conversations, custom fields): Custom scripts or a managed service.
  • Enterprise (100K+ conversations, compliance requirements): Managed migration service. The hidden costs of DIY migration scripts at this scale — broken associations, partial loads, re-migration cycles — typically exceed the cost of a managed service.
  • Ongoing coexistence: Use a sync architecture after the historical backfill, not instead of it.

A note on the native HubSpot–Help Scout integration: The existing integration syncs sidebar data (contact properties, deal info) for live use — it does not migrate historical conversations or tickets. There is no native one-click migration path between the two platforms.

Step-by-Step API Migration Architecture

The order of operations matters. Creating tickets before contacts exist in HubSpot will leave orphaned records with no associations. Follow this reference-first, relationship-safe sequence.

1. Set Up HubSpot Sandbox Environment

Before loading any production data, create a HubSpot developer test account or sandbox (available on Professional/Enterprise plans under Settings → Sandboxes). Sandboxes replicate your production schema — pipelines, properties, and workflows — but use a separate data store. Limitations to know: sandboxes have lower API rate limits (matching Starter-tier), do not support all add-ons, and cannot receive inbound email for routing tests. Run your first 500-ticket test load here before touching production.

2. Extract Reference Data

Extract Help Scout mailboxes (GET /v2/mailboxes) and users (GET /v2/users). Map mailboxes to HubSpot pipelines. Map users to HubSpot Owners — assign deactivated Help Scout users to a dedicated "Legacy Support Agent" owner so historical tickets aren't orphaned. Build lookup tables for custom field option IDs, owner mappings, and mailbox-to-pipeline mappings before loading anything.

3. Extract and Load Contacts and Companies

Extract Help Scout Customers (GET /v2/customers). Transform and load into HubSpot using the Batch Contact API (POST /crm/v3/objects/contacts/batch/create) with email as the dedup key. Then load companies and create contact → company associations. Store the helpscout_customer_idhubspot_contact_id mapping in a local database (Redis or PostgreSQL).

Disable HubSpot's automatic company creation and association before loading (Settings → Contacts → Creating and Associating Companies), or you will create duplicate companies from contact email domains.

4. Extract Conversations and Threads

# Pseudocode: Extract conversations with threads (OAuth2 Bearer token)
import time
 
def extract_all(token):
    for page in paginate("GET /v2/conversations?status=all", token):
        for conversation in page["_embedded"]["conversations"]:
            conv_id = conversation["id"]
            threads_resp = GET(f"/v2/conversations/{conv_id}/threads", token)
            
            # Handle merged conversations (301 redirect)
            if threads_resp.status_code == 301:
                new_id = threads_resp.headers["Location"].split("/")[-2]
                threads_resp = GET(f"/v2/conversations/{new_id}/threads", token)
                conv_id = new_id
            
            threads = threads_resp.json()["_embedded"]["threads"]
            for thread in threads:
                if thread.get("attachments"):
                    for att in thread["attachments"]:
                        download(f"/v2/attachments/{att['id']}/data", token)
            store(conv_id, conversation, threads)
            
            # Respect rate limits
            time.sleep(0.3)  # ~200 req/min for Standard plan

At 25 conversations per page, a 100,000-ticket migration requires 4,000 API calls just for conversation headers, plus one call per conversation for threads = ~104,000 total extraction calls minimum.

If a Help Scout conversation was merged, the old ID returns a 301 Moved Permanently. Your script must follow the Location header to resolve the new conversation ID before replaying thread history. The pseudocode above handles this explicitly.

5. Load Tickets and Engagements

Create Tickets in HubSpot (POST /crm/v3/objects/tickets/batch/create). Map Help Scout statuses to HubSpot pipeline stage internal IDs (retrieve via GET /crm/v3/pipelines/tickets). Associate each ticket with the corresponding contact.

Then iterate through threads. For each thread, create the matching engagement type:

  • Customer/agent replies → POST /crm/v3/objects/emails with hs_email_direction, hs_email_text, hs_timestamp
  • Internal notes → POST /crm/v3/objects/notes with hs_note_body, hs_timestamp
  • Phone threads → POST /crm/v3/objects/calls
  • Lineitem/system events → flatten into notes with readable audit text, or omit

Associate each engagement with both the ticket and the contact in the same create call. If you skip the contact association, the Contact timeline will be empty even though the Ticket timeline looks correct.

In the JSON example below, associationTypeId: 15 represents the HubSpot-defined association type for email-to-contact. Use associationTypeId: 27 for email-to-ticket. Retrieve the full list of association type IDs via GET /crm/v4/associations/{fromObjectType}/{toObjectType}/labels.

{
  "inputs": [
    {
      "properties": {
        "hs_timestamp": "2023-10-01T12:00:00Z",
        "hubspot_owner_id": "123456",
        "hs_email_direction": "INCOMING_EMAIL",
        "hs_email_text": "I need help resetting my password."
      },
      "associations": [
        {
          "to": { "id": "987654321" },
          "types": [
            {
              "associationCategory": "HUBSPOT_DEFINED",
              "associationTypeId": 15
            }
          ]
        },
        {
          "to": { "id": "ticket_id_here" },
          "types": [
            {
              "associationCategory": "HUBSPOT_DEFINED",
              "associationTypeId": 27
            }
          ]
        }
      ]
    }
  ]
}

Critical for Help Desk workspace visibility: Tickets created via API will appear in the legacy Tickets view automatically. To appear in the Help Desk workspace, the ticket must have at least one associated email engagement that creates a conversation thread. Verify this in your sandbox before production loading.

6. Upload Attachments

Upload files to HubSpot File Manager via the Files API (POST /files/v3/files), then reference the file IDs in the hs_attachment_ids property of the engagement. Set the access parameter to PRIVATE at upload time — HubSpot defaults to PUBLIC_INDEXABLE, which means uploaded files are accessible to anyone with the URL and indexable by search engines. Verify download behavior after upload.

7. Validate and Delta Sync

Run record-count reconciliation before cutting over. Then execute a delta sync to capture conversations created or updated since the initial extraction, using modifiedSince parameters or query syntax like query=(modifiedAt: [2026-06-01T00:00:00Z TO *]).

Tip

Retry strategy: Implement exponential backoff with jitter on 429 responses. Cap at 5 retries per request. Log every failed record to a dead-letter queue for manual review. If a batch partially fails (HubSpot returns per-record status in batch responses), replay only the source IDs that didn't acknowledge. Never silently drop a record.

Knowledge Base Migration

The Help Scout Docs API and HubSpot Knowledge Base API are separate from the conversation/ticket APIs and should be treated as an independent workstream.

Help Scout Docs structure: Collections → Categories → Articles. Extract via GET /v2/collections, GET /v2/collections/{id}/articles.

HubSpot KB structure: Categories → Subcategories → Articles. Import via POST /cms/v3/blogs/posts or the Knowledge Base import UI.

Key constraints:

  • HubSpot limits KB imports to 400 articles per batch. For larger knowledge bases, split into multiple import runs.
  • HubSpot KB does not support HTML tables in imported articles. Convert tables to styled lists or images before import.
  • Images in Help Scout Docs articles are hosted on Help Scout's CDN. Download them, upload to HubSpot File Manager, and rewrite src URLs — same as inline images in conversation threads.
  • HubSpot Knowledge Base requires a Service Hub Professional or Enterprise seat assigned to the user managing the KB.
  • Category and subcategory structure must be created in HubSpot before importing articles.

(knowledge.hubspot.com)

How Long Does a Help Scout to HubSpot Migration Take? [For PMs]

Phase Duration Dependencies
Audit & field mapping 2–3 days Access to both platforms, custom field inventory
Script development / tool configuration 3–5 days API credentials (OAuth2), sandbox environments
Test migration (subset) 1–2 days 5% sample data, QA checklist
Full historical migration 1–5 days Conversation volume and rate limits
Validation & UAT 2–3 days Support team availability
Delta sync + go-live cutover 1 day Coordinated team switchover

Realistic total: 2–4 weeks for most accounts. Large accounts with 200K+ conversations may extend to 6 weeks. Add time for knowledge base import, mailbox redesign, or heavy attachment volumes.

For a zero-downtime cutover strategy, run the full historical migration first, then execute a delta sync of records created or updated since the initial extraction. This lets your support team keep working in Help Scout until the final cutover weekend.

Risk Register

Risk Likelihood Mitigation
Thread history loss (CSV path) High if CSV used Use API extraction from day one
Rate limit throttling extends timeline Medium–High Pre-compute throughput; batch aggressively; run off-peak
Broken ticket-contact associations Medium Load contacts first; validate associations post-load
Duplicate companies Medium Disable HubSpot auto-association; use unique legacy IDs
Custom field type mismatch Low–Medium Pre-create all properties; test with subset
Attachment exposure (public URLs) Low–Medium Set access=PRIVATE at upload; verify file access post-upload
Thread ordering errors Medium Map hs_timestamp from Help Scout's createdAt field on each thread; verify chronological sort post-load
Help Desk workspace gaps Medium Verify API-created tickets render in Help Desk workspace in sandbox before production load

GDPR, Data Residency & Compliance Considerations

Migrations that move customer data between platforms raise compliance questions that should be addressed before extraction begins:

  • GDPR right to deletion: If a customer has exercised their right to deletion in Help Scout, verify that the deleted data is not present in API responses. Help Scout's API honors deletion requests — deleted conversations return 404. However, if you extract data before a deletion request is processed, you may inadvertently re-create deleted data in HubSpot. Implement a deletion reconciliation check before final load.
  • Data residency: Help Scout stores data in the US. HubSpot offers EU data hosting for accounts created with the EU data center option. If your HubSpot instance is EU-hosted, confirm that migration scripts route API calls to api.hubapi.com (US) or api.hubapi.eu (EU) as appropriate.
  • HIPAA: If your Help Scout account handles protected health information (PHI), ensure your HubSpot account is on an Enterprise plan with a signed BAA before loading any data. HubSpot's BAA does not cover all features — verify which objects are in scope.
  • Data retention: Establish a retention policy for the Help Scout account post-migration. Keep it in read-only mode for audit purposes, but set a deletion date to avoid indefinite dual-storage of customer PII.

What Do Customers and Agents Notice? [For Customer Success]

Done correctly, customers notice nothing. Their ticket history, conversation threads, and attachments all appear on the HubSpot ticket record. Agents log into HubSpot and see complete, chronological ticket histories.

The key risks to customer experience:

  • Broken history: If thread migration fails, agents lose context on open issues. Customers repeat themselves.
  • SLA gaps: During cutover, routing rules and SLA clocks reset. Pre-configure HubSpot SLAs before go-live. Note: SLAs require Service Hub Professional or higher.
  • Reply-to address changes: If you change support email routing, confirm SPF/DKIM records and test inbound delivery before cutover.
  • Missing attachments: Agents and customers lose trust when linked files return 404s.

Brief your support team on where to find historical conversations in HubSpot's ticket timeline. Run a 30-minute walkthrough before go-live. Tell agents which fields are legacy versus live, and spot-check high-touch accounts before switching routing.

Edge Cases & Known Limitations

These constraints need explicit handling during execution:

  • Inline images: Help Scout threads often contain inline images hosted on Help Scout's servers (secure.helpscout.net URLs). If you migrate HTML bodies directly, those images break when Help Scout closes your account or your subscription lapses. Download inline images, upload them to HubSpot File Manager (POST /files/v3/files with access=PRIVATE), and rewrite the <img> src tags before loading the thread HTML into HubSpot.

  • Merged conversations: Merged conversations in Help Scout return a 301 Moved Permanently for the old conversation ID. Migration scripts must follow redirects or pre-resolve merged IDs before replaying thread history. Track old→new ID mappings to avoid duplicate ticket creation.

  • Multiple email addresses: Help Scout allows multiple emails per customer profile. HubSpot designates one primary email. Map secondary emails to HubSpot's hs_additional_emails property (semicolon-delimited), or deduplication logic will create duplicate contacts.

  • Mailbox-scoped custom fields: If a conversation moved between Help Scout mailboxes, custom field data may be missing for the original mailbox's fields. Audit this before migration by comparing custom field population rates across mailboxes.

  • HubSpot Help Desk workspace visibility: Tickets created via the API appear in the legacy Tickets view but may not appear in HubSpot's Help Desk workspace unless at least one email engagement is properly associated, creating a conversation thread. Verify this behavior in a sandbox first.

  • Note body length: HubSpot note bodies have a character limit of 65,536 characters. Split long note bodies exceeding this limit into multiple sequential notes, preserving timestamp ordering.

  • Lineitem and system events: Help Scout lineitem threads (assignment changes, merge events, workflow actions) have no 1:1 HubSpot equivalent. Flatten these into readable audit notes or omit them based on your requirements.

  • Thread timestamp ordering: HubSpot sorts ticket timeline entries by hs_timestamp. If you map this field incorrectly — for example, using conversation creation time instead of individual thread creation time — the conversation will appear out of order. Always map hs_timestamp from the createdAt field on each individual Help Scout thread.

  • CC and BCC fields: Help Scout stores CC recipients on threads. HubSpot's email engagement supports hs_email_cc and hs_email_bcc properties, but these must be explicitly mapped or CC context is lost.

Validation & Testing

Do not trust a "success" HTTP status code as proof of data fidelity. Run post-migration queries to reconcile record counts and verify data integrity.

  1. Record count reconciliation: Total tickets in HubSpot should equal total conversations in Help Scout — broken down by mailbox, status, and date range.
  2. Thread count sampling: Randomly select 50–100 tickets. Verify thread count matches the source. Verify threads appear in correct chronological order (sorted by hs_timestamp).
  3. Field-level checks: Confirm custom fields, tags, statuses, and assignees transferred correctly. Spot-check 20 tickets for dropdown field value accuracy.
  4. Association integrity: Confirm every ticket has an associated contact. Orphaned tickets are effectively lost data. Confirm contacts have company associations where applicable. Run: GET /crm/v3/objects/tickets/{id}/associations/contacts on a sample set.
  5. Attachment verification: Open 20 attachments to confirm they download and render properly. Verify file access is private, not public.
  6. Timeline ordering: Verify threads appear in chronological order on the HubSpot ticket record. Check both the legacy Tickets view and the Help Desk workspace.
  7. Help Desk workspace check: Verify that migrated tickets appear in the Help Desk workspace, not just the legacy Tickets view.
  8. Live inbound test: Send a new test message after cutover to confirm routing works end-to-end.

For a complete testing framework, use our Post-Migration QA Checklist.

Rollback plan: Maintain the Help Scout account in read-only mode for at least 30 days post-migration. If critical issues surface, revert email routing back to Help Scout while resolving data issues in HubSpot. For data created in HubSpot during a failed migration, you have three options: (1) archive all migrated tickets using PATCH /crm/v3/objects/tickets/{id} with hs_pipeline_stage set to a "closed" stage, (2) bulk delete via the batch delete endpoint if you need a clean slate for re-migration, or (3) leave them and re-migrate into a separate pipeline. Do not cancel your Help Scout subscription until the migration is fully validated.

Build In-House vs. Use a Managed Service

Build in-house when: You have a dedicated engineer with API integration experience, fewer than 10,000 conversations, no complex custom field mappings, and no compliance requirements (HIPAA, SOC 2, GDPR data residency). The engineer needs to own OAuth2 authentication, pagination, retry logic for 429 Too Many Requests errors, the HubSpot association API, Help Desk workspace verification, and QA validation.

Use a managed service when: You have 50K+ conversations, complex threading (merged conversations, multi-mailbox setups), compliance requirements, or your engineering team can't afford 2–4 weeks of migration work on top of product development.

The hidden cost of DIY is re-migration. Teams that underestimate Help Scout's thread model or HubSpot's engagement association requirements frequently end up with tickets that have no visible history — and must re-run the migration from scratch. As detailed in our analysis of why DIY migration scripts fail, the hard work is thread reconstruction, attachment replay, custom-field normalization, and delta-sync orchestration — not ticket creation.

The Practical Next Step

Start by deciding whether you're migrating metadata or support history. If the answer is support history, design the project around Help Scout API thread extraction (via OAuth2) and HubSpot ticket-plus-engagement loading from day one. Verify your target HubSpot tier supports the features you need (SLAs, Help Desk workspace, custom reporting). That single decision eliminates most rework.

Frequently Asked Questions

Can I migrate Help Scout to HubSpot Service Hub without losing data?
Yes, but only if you use the Help Scout Inbox API for extraction. The native CSV export excludes all conversation thread contents, message bodies, and internal notes. An API-based migration preserves full thread history, attachments, and custom fields.
How long does a Help Scout to HubSpot Service Hub migration take?
A typical migration takes 2–4 weeks including planning, execution, and validation. The API extraction alone can take 8–48 hours depending on conversation volume and your Help Scout plan's rate limits (200–800 requests/minute). Large accounts with 200K+ conversations may extend to 6 weeks.
What data can't be migrated from Help Scout to HubSpot Service Hub?
Workflows, saved replies, Beacon widget configuration, and user permissions cannot be migrated via API and must be rebuilt manually in HubSpot. Inline images embedded in message bodies require download and re-upload. Knowledge base migration is a separate workstream with a 400-article-per-import cap.
How much does a Help Scout to HubSpot Service Hub migration cost?
Third-party SaaS tools charge based on record count, typically starting at a few hundred dollars for small accounts. Managed migration services range from $2,000–$15,000+ depending on conversation volume, custom fields, and compliance requirements. DIY costs are engineering time: 2–4 weeks of a dedicated engineer.
Is there a native Help Scout to HubSpot integration for migration?
No. The existing Help Scout–HubSpot integration syncs sidebar data (contact properties, deal info) for live use — it does not migrate historical conversations or tickets. There is no native one-click migration path between the two platforms.

More from our Blog

Post-Migration QA: 20 Tests to Run After Your Help Desk Data Migration
Help Desk

Post-Migration QA: 20 Tests to Run After Your Help Desk Data Migration

Ensure your help desk migration is a success with this comprehensive 20-point post-migration QA checklist. This expert guide details the 20 essential tests needed to validate your data integrity, system functionality, user-friendliness, and performance . Learn exactly how to check everything from ticket data, attachments, and knowledge base articles to critical workflows, automations, and integrations before you go live. This process is your final line of defense against lost tickets, broken workflows, and unhappy customers.

Raaj Raaj · · 8 min read
Zero-Downtime Help Desk Data Migration: How to Keep Support Running During the Move
Help Desk

Zero-Downtime Help Desk Data Migration: How to Keep Support Running During the Move

This guide details the 3-stage technical process for a zero-downtime help desk migration. Learn how to use an initial bulk data transfer, a continuous delta migration (Change Data Capture), and a seamless final cutover to move platforms without any service interruption. Discover how an engineer-led approach can guarantee a 100% accurate, 50x faster migration.

Raaj Raaj · · 6 min read