---
title: How to Migrate from Intercom to Salesforce Service Cloud (2026)
slug: how-to-migrate-from-intercom-to-salesforce-service-cloud-2026
date: 2026-07-14
author: Nachi
categories: [Migration Guide, Intercom, Salesforce Service Cloud]
excerpt: "Step-by-step guide to migrating Intercom conversations, contacts, and attachments to Salesforce Service Cloud. Covers API limits, object mapping, and edge cases."
tldr: "Migrating Intercom to Salesforce Service Cloud takes 2–4 weeks. Watch for the 4,000-char CaseComment limit and the 500-part API retrieval cap that silently truncate transcripts."
canonical: https://clonepartner.com/blog/how-to-migrate-from-intercom-to-salesforce-service-cloud-2026/
---

# How to Migrate from Intercom to Salesforce Service Cloud (2026)


# How to Migrate from Intercom to Salesforce Service Cloud (2026)

> [!NOTE]
> **TL;DR — Intercom to Salesforce Service Cloud Migration**
>
> Migrating from Intercom to Salesforce Service Cloud is a high-complexity project because Intercom's conversation-centric data model does not map cleanly to Salesforce's Account → Contact → Case hierarchy. The realistic timeline is **2–4 weeks** including mapping, testing, and cutover. The biggest risk is losing conversation transcripts — Intercom's CSV and standard dataset exports omit message content entirely, and the `CaseComment.CommentBody` field in Salesforce is capped at **4,000 characters**, silently truncating long conversation parts. The Intercom API also caps `conversation_parts` retrieval at **500 per conversation**, so long-running threads need explicit exception handling. Intercom Fin AI configurations, Product Tours, and custom bot flows cannot be migrated — they must be rebuilt in Salesforce. Current Intercom API rate limits are **10,000 calls per minute per app**, though legacy documentation references 1,000/min; throttle from live `X-RateLimit-*` headers. Teams with small, clean workspaces can build a custom ETL script; for larger volumes, attachment-heavy conversations, or zero-downtime requirements, a managed migration service is the safer path.

## What Is an Intercom to Salesforce Service Cloud Migration?

An Intercom to Salesforce Service Cloud migration is the process of extracting Users, Leads, Companies, Conversations, Conversation Parts, Tags, Custom Attributes, Help Center Articles, and Attachments from Intercom and loading them into Salesforce Service Cloud as Contacts, Leads, Accounts, Cases, CaseComments (or EmailMessages), Topics, Custom Fields, Knowledge Articles, and ContentVersion files.

Intercom's native Salesforce app can create and update Cases, send conversations as Tasks, and match users to Contacts, but it is designed for live sync and agent workflow — not for replaying years of historical support data into a clean Service Cloud archive. ([intercom.com](https://www.intercom.com/help/en/articles/5203865-using-the-salesforce-app-in-intercom))

### Why Teams Move from Intercom to Salesforce Service Cloud

Teams make this switch for three platform-specific reasons:

- **Enterprise case management and SLA enforcement.** Salesforce Service Cloud provides native Entitlements, Milestones, and Omni-Channel routing with skills-based assignment. Intercom's SLA tracking exists but lacks the multi-tier escalation paths and contractual compliance reporting that regulated or enterprise support orgs require.
- **Unified CRM and service platform.** When sales already lives in Salesforce, running support in Intercom creates a data silo. Moving to Service Cloud puts Cases, Opportunities, and Account health on one platform — eliminating the sync overhead of maintaining a bidirectional Intercom↔Salesforce integration.
- **Reporting depth and compliance.** Salesforce analytics, audit trails, field-level security, HIPAA-eligible configurations, and FedRAMP authorization exceed what Intercom offers for enterprise compliance teams.

### How Intercom and Salesforce Data Models Differ

The core architectural mismatch that makes this migration non-trivial:

1. **Flat vs. hierarchical identity model.** Intercom treats Users and Leads as the top-level objects; Companies are loosely attached. Salesforce enforces a strict Account → Contact → Case hierarchy. Every Case requires a Contact, and every Contact should belong to an Account.
2. **Conversations vs. Cases.** An Intercom Conversation is a stream of `conversation_parts` — messages, notes, assignment events, state changes — stored as a flat list. A Salesforce Case is a structured lifecycle record with discrete child objects (CaseComment, EmailMessage, FeedItem) and separate status/priority/escalation fields.
3. **Message threading.** Intercom's `conversation_parts` include bot replies, Fin AI answers, workflow-triggered parts, and internal notes in a single chronological stream. Salesforce separates these into CaseComments (internal/public), EmailMessages (for email channels), and Chatter FeedItems.

### Salesforce Edition Requirements

Not all Service Cloud editions support the features required for a clean migration. Verify your edition before scoping:

| Feature Required for Migration | Minimum Edition |
|---|---|
| Bulk API 2.0 | Enterprise, Performance, Unlimited, Developer |
| "Set Audit Fields upon Record Creation" | Enterprise+ (requires contacting Salesforce Support to enable) |
| Salesforce Knowledge | Enterprise+ (with Knowledge User license) |
| Email-to-Case (for EmailMessage objects) | All editions, but Email-to-Case must be explicitly enabled |
| Omni-Channel Routing | Enterprise+ |
| Entitlements & Milestones | Professional+ (limited), Enterprise+ (full) |

Professional Edition does not support Bulk API 2.0, which makes it unsuitable for migrations above a few thousand records. If you are on Professional Edition, you must either upgrade or use Data Loader with SOAP API, which is significantly slower (batch sizes of 200 records vs. 10,000). ([help.salesforce.com](https://help.salesforce.com/s/articleView?id=000334139&language=en_US&type=1))

## Intercom to Salesforce Service Cloud Object Mapping

Object mapping dictates the success or failure of your historical data transfer. The official Intercom Salesforce integration maps ongoing conversations to Tasks on the Contact record by default — this breaks standard Service Cloud ITSM reporting because Tasks do not support Case routing, SLA tracking, or standard support metrics. You must map historical data directly to the Case object. ([intercom.com](https://www.intercom.com/help/en/articles/5203865-using-the-salesforce-app-in-intercom))

| Intercom Object | Salesforce Object | Notes / Caveats |
|---|---|---|
| User (role=user) | Contact | Match on `email`. Store Intercom `user_id` in a custom `External_ID__c` field. Salesforce requires a Last Name — Intercom often only has a first name or email. |
| Lead (role=lead) | Lead | Convert to Contact post-migration if needed. |
| Company | Account | Match on `company_id` or domain to prevent duplicates. |
| Conversation | Case | One Conversation = one Case. Map `created_at` → `CreatedDate` (requires "Set Audit Fields upon Record Creation" permission). ([help.salesforce.com](https://help.salesforce.com/s/articleView?id=000334139&language=en_US&type=1)) |
| Conversation Part (comment) | CaseComment or EmailMessage | **CaseComment has a 4,000-character limit** on `CommentBody`. Use EmailMessage for HTML-rich or long messages. |
| Conversation Part (note) | CaseComment (IsPublished=false) | Internal notes map to private CaseComments. |
| Conversation Part (assignment, state_change) | Case field update or FeedItem | Assignment events can be logged as Chatter posts or discarded based on reporting needs. |
| Admin / Teammate | User | Salesforce Users must pre-exist; match by email. Inactive Intercom agents must be mapped to an active placeholder User or their history will fail to insert. |
| Team | Queue | Map Intercom Teams to Salesforce Queues for case assignment. |
| Tag | Topic or Custom Field | Salesforce Topics have limits; mapping tags to a multi-select picklist or custom object is often safer. |
| Custom Attribute (Contact) | Custom Field on Contact | Data type mapping required: Intercom allows flexible strings, booleans, numbers — Salesforce picklists reject values that don't match predefined options. |
| Conversation Attribute | Custom Field on Case | Create matching custom fields on the Case object before import. |
| Help Center Article | Knowledge__kav | Requires Knowledge enabled in the org. Rich text and image re-hosting needed. |
| Saved Reply / Macro | Quick Text or Macro | Intercom saved replies map to Salesforce Quick Text objects. Intercom macros with multi-step actions map to Salesforce Macros (Enterprise+ only). No automated migration path — these must be recreated manually or scripted via Metadata API. |
| Attachment | ContentVersion + ContentDocumentLink | Download from Intercom CDN, upload to Salesforce Files, link to parent Case. |

### What Has No Clean Equivalent in Salesforce Service Cloud?

- **Fin AI configuration and training data** — must be rebuilt in Salesforce Einstein or Agentforce.
- **Intercom Product Tours and Checklists** — no Service Cloud equivalent; requires a separate tool (WalkMe, Pendo, or similar).
- **Intercom Series (automated message sequences)** — rebuild as Salesforce Flows or Marketing Cloud journeys.
- **Conversation ratings (CSAT)** — can be migrated as custom fields on the Case, but Salesforce's native CSAT survey mechanism (post-chat surveys, Customer Lifecycle Analytics) is structurally different.
- **Bot steps, snooze history, and assignment event sequences** — no native Case fields for these. Decide up front whether they become searchable text in CaseComments, read-only custom fields, or a separate transcript object for audit and reporting.
- **Messenger customizations** — custom launcher settings, Messenger home screen configurations, and conditional display rules have no Salesforce equivalent. Document these before canceling Intercom.
- **Webhook configurations and integration events** — Intercom webhook subscriptions and event logs do not migrate. Document all active webhooks and rebuild equivalent Platform Events or Salesforce Event Bus subscriptions.

### Field-Level Transformations

Intercom allows highly flexible custom attributes (strings, numbers, booleans) applied loosely to Users and Companies. Salesforce requires strict schema definitions. Picklists will reject any Intercom data that does not match predefined values. You must audit and clean Intercom custom attributes before attempting a load.

All Intercom timestamps are stored as Unix epoch (UTC); Salesforce `CreatedDate` requires ISO 8601. Ensure timezone conversion is explicit in your transform step. Example: Intercom timestamp `1735689600` → Salesforce `2025-01-01T00:00:00.000Z`.

## The Transcript Trap: How to Export Intercom Conversation Data

Intercom's CSV dataset exports contain reporting metadata — conversation IDs, timestamps, and attributes — but **omit the actual message content**. Intercom's own documentation states that CSV exports do not include full message or conversation content. The S3 data export also does not include transcripts. ([intercom.com](https://www.intercom.com/help/en/articles/2046229-export-your-conversations-data))

For a full deep-dive on every Intercom export method, see our guide on [how to export data from Intercom](https://clonepartner.com/blog/blog/how-to-export-data-from-intercom-methods-api-limits-transcripts/).

### Extraction Pattern via the REST API

To get full transcripts, you must use the Intercom REST API in a two-step process:

1. **List all conversations:** `GET /conversations?per_page=150` returns metadata only — no `conversation_parts`.
2. **Retrieve each conversation:** `GET /conversations/{id}` returns the full conversation object including all `conversation_parts` (messages, notes, events).

This means extracting 100,000 conversations requires a minimum of **100,667 API calls** (667 list pages + 100,000 individual GETs). ([developers.intercom.com](https://developers.intercom.com/docs/references/2.13/rest-api/api.intercom.io/conversations/retrieveconversation))

One additional constraint: the Conversations Search API does not support `company_id` as a filter. If you need company-based migration waves, fetch company contacts first and then search by `contact_ids`. ([intercom.com](https://www.intercom.com/help/en/articles/9071694-intercom-developer-faqs))

### Intercom API Rate Limits

Intercom's current default rate limit is **10,000 API calls per minute per app** and **25,000 calls per minute per workspace**, enforced in 10-second windows (approximately 1,666 operations per 10-second window). Exceeding this returns HTTP 429. Older Intercom community answers and some documentation still reference a legacy 1,000-per-minute figure — the safest approach is to throttle from live `X-RateLimit-Remaining` headers and retry 429 and 5xx responses with exponential backoff. ([intercom.com](https://www.intercom.com/help/en/articles/9071694-intercom-developer-faqs))

**Throughput math:** At 10,000 calls/minute and one GET per conversation, extracting 100,000 conversations takes roughly 10–15 minutes of pure API time. Add serialization, retry handling (plan for 2–5% 429 retries), and disk I/O, and realistic extraction for 100K conversations is **1–3 hours**.

> [!WARNING]
> **Conversation parts are capped at 500 per conversation** when retrieved via the API. If a conversation has more than 500 parts (common with long-running support threads or bot-heavy workflows), the API silently truncates. You must paginate through `conversation_parts` separately for these edge cases. Use `statistics.count_conversation_parts` in the search API to identify oversize threads before cutover. ([developers.intercom.com](https://developers.intercom.com/docs/references/2.13/rest-api/api.intercom.io/conversations/retrieveconversation))

```http
POST /conversations/search
Content-Type: application/json

{
  "query": {
    "operator": "AND",
    "value": [
      { "field": "updated_at", "operator": ">", "value": "1735689600" },
      { "field": "statistics.count_conversation_parts", "operator": ">", "value": 500 }
    ]
  },
  "pagination": { "per_page": 150 }
}
```

## Loading Data into Salesforce Service Cloud: Bulk API 2.0

Salesforce Bulk API 2.0 is the only viable method for loading historical conversation data at scale. Salesforce recommends it for any data operation above 2,000 records. It processes data asynchronously — you upload a CSV payload, and Salesforce handles the chunking and database insertion. Bulk API 2.0 requires Enterprise Edition or higher. ([resources.docs.salesforce.com](https://resources.docs.salesforce.com/latest/latest/en-us/sfdc/pdf/salesforce_app_limits_cheatsheet.pdf))

Key limits from the official Salesforce documentation:

| Limit | Value |
|---|---|
| Batches per 24-hour rolling period | 15,000 (shared with Bulk API 1.0) |
| Max records per 24-hour rolling period | 150,000,000 |
| Records per internal batch | 10,000 (auto-chunked) |
| Max concurrent ingest jobs | 25 |
| Max file size per job | 150 MB (100 MB recommended due to base64 encoding) |
| Max characters per field | 131,072 |
| Job results retention | 7 days |

Job results for successful, failed, and unprocessed rows are available for seven days. Successful rows are **not** rolled back if part of a job fails — review all result files before proceeding to the next load stage.

**Insertion throughput benchmarks:** Bulk API 2.0 typically processes 5,000–15,000 records per minute for standard objects like Case and Contact, depending on the number of active triggers, validation rules, and process automations on the target object. ContentVersion uploads are significantly slower — expect 500–2,000 records per minute due to base64 encoding overhead and file storage I/O. For a migration of 100,000 Cases with 500,000 CaseComments and 200,000 attachments, plan for **4–8 hours** of total Salesforce insertion time across all objects.

### Salesforce Governor Limits and Automation Conflicts

Beyond Bulk API limits, Salesforce enforces per-transaction governor limits that fire on every record insert. These are the most common causes of migration failures that are unrelated to data quality:

| Governor Limit | Threshold | Migration Impact |
|---|---|---|
| SOQL queries per transaction | 100 | Triggers or Process Builders that query related records can exceed this during bulk inserts. |
| DML statements per transaction | 150 | Flows or triggers that create child records on Case insert will hit this. |
| CPU time per transaction | 10,000 ms | Complex Apex triggers or validation rules slow each batch. |
| Email invocations per transaction | 10 | Auto-response rules or workflow email alerts will fail silently after the 10th email in a batch. |
| Future calls per transaction | 50 | Async Apex triggered by inserts can queue-flood. |

**Before running any migration load**, deactivate or bypass the following in your target org:

- Assignment rules (Cases)
- Auto-response rules (Cases)
- Escalation rules (Cases)
- Workflow rules with email alerts
- Process Builder flows triggered on Case or CaseComment creation
- Apex triggers (if possible, add a `Migration_Bypass__c` custom setting check)

Re-enable each one individually after the load completes and validation passes.

### The CaseComment Body Limit Problem

The `CaseComment.CommentBody` field has a **4,000-character limit**. Intercom conversation parts regularly exceed this — especially HTML-rich messages, bot-generated responses, or messages with inline images. If you insert a conversation part longer than 4,000 characters, Salesforce will silently truncate it or throw a `STRING_TOO_LONG` error depending on the API version.

**Workaround:** Use `EmailMessage` objects instead of CaseComments. `EmailMessage.HtmlBody` supports up to **32,000 characters** with full HTML rendering. This preserves rich formatting, inline images, and long messages. Set `EmailMessage.Incoming` = true for customer messages and false for agent replies. The trade-off is that EmailMessage requires Email-to-Case to be enabled, and it adds complexity to your data model — but it prevents silent data loss.

If you use CaseComment, it stores **plain text only** — you must strip HTML. If you use EmailMessage, HTML is preserved, but Salesforce enforces a strict HTML tag whitelist on rich text fields. Unsupported tags (complex nested tables, custom div classes, `<script>`, `<iframe>`) will cause the API to reject the entire record. Sanitize during the transformation phase using a library like Bleach (Python) or DOMPurify (Node.js).

### Order of Operations

Salesforce enforces strict relational integrity. You cannot insert a Case if the Contact does not exist, and you cannot insert a CaseComment if the Case does not exist. Load order matters — broken relationships are the #1 cause of failed migrations and the source of the `INVALID_CROSS_REFERENCE_KEY` error.

1. **Accounts** — Insert Intercom Companies. Use an `External_ID__c` populated with the Intercom `company_id` to enable upsert operations and avoid duplicates on re-runs. Capture the new Salesforce `AccountId`.
2. **Contacts** — Insert Intercom Users, linking to the correct `AccountId`. Capture the `ContactId`. Assign "Unknown" as the Last Name where Intercom only has an email or first name.
3. **Cases** — Insert Intercom Conversations, mapping `ContactId`, `AccountId`, and `OwnerId`. **Disable assignment rules, auto-response rules, escalation rules, and email alerts before this step.** If you fail to disable these triggers, Salesforce will send thousands of automated "Your case has been created" emails to customers for tickets that were closed years ago. Enable "Set Audit Fields upon Record Creation" to preserve original Intercom timestamps. Capture the `CaseId`.
4. **CaseComments or EmailMessages** — Insert Intercom Conversation Parts, mapping them to the parent `CaseId`. Preserve chronological order by setting `CreatedDate` from the Intercom part's `created_at` timestamp.
5. **ContentVersion + ContentDocumentLink** — Upload attachments and link them to the corresponding Case.
6. **Knowledge Articles** — Insert Help Center Articles if migrating the knowledge base.

### Common Bulk API Error Messages and Resolutions

| Error | Cause | Resolution |
|---|---|---|
| `INVALID_CROSS_REFERENCE_KEY` | Parent record (Contact, Account, or Case) does not exist or External_ID__c lookup failed. | Verify load order. Check that all parent External_ID__c values exist before loading child records. |
| `STRING_TOO_LONG` | Field value exceeds max length (e.g., CaseComment > 4,000 chars). | Truncate with ellipsis marker, or switch to EmailMessage. |
| `REQUIRED_FIELD_MISSING` | Mandatory Salesforce field (e.g., Contact.LastName, Case.Status) is null. | Add default values in your transform step for all required fields. |
| `DUPLICATE_VALUE` | External_ID__c or unique field constraint violated. | Use upsert operation instead of insert. De-duplicate source data. |
| `UNABLE_TO_LOCK_ROW` | Concurrent Bulk API jobs updating the same parent record. | Reduce parallelism. Sort CSV by parent ID to minimize lock contention. |
| `FIELD_CUSTOM_VALIDATION_EXCEPTION` | A validation rule on the target object rejected the record. | Deactivate validation rules during migration or ensure source data conforms. |
| `STORAGE_LIMIT_EXCEEDED` | Org data or file storage quota exceeded. | Check storage before migration. Purchase additional storage or archive old data. |

```http
POST /services/data/v67.0/jobs/ingest
Content-Type: application/json

{
  "object": "Case",
  "operation": "upsert",
  "externalIdFieldName": "Intercom_Conversation_Id__c",
  "contentType": "CSV"
}

PUT /services/data/v67.0/jobs/ingest/<jobId>/batches
<csv payload>

PATCH /services/data/v67.0/jobs/ingest/<jobId>
Content-Type: application/json

{ "state": "UploadComplete" }
```

## Handling Attachments and Inline Images

Attachments represent the highest risk of silent data loss during a migration. Intercom stores attachments as CDN-hosted URLs inside `conversation_parts [].attachments []`. These URLs are ephemeral — they may expire or become inaccessible after workspace changes. You cannot map a URL into a Salesforce text field and call it done; you will end up with permanently broken links.

**Migration process:**

1. Download each attachment from the Intercom CDN URL during extraction. Intercom allows individual attachments up to 100 MB.
2. Upload to Salesforce as a `ContentVersion` record (base64-encoded body, max 2 GB per file). ([developer.salesforce.com](https://developer.salesforce.com/blogs/2020/09/codelive-creating-finding-and-publishing-files))
3. Create a `ContentDocumentLink` to associate the file with the parent Case record.
4. For **inline images** embedded within Intercom rich-text messages: parse them out of the HTML, download, upload to Salesforce Files, and rewrite the `<img>` tags in the CaseComment or EmailMessage body to point to the new Salesforce `ContentVersion` download URL.

**Storage consideration:** Salesforce file storage is licensed per org. Enterprise Edition includes 10 GB base + 2 GB per user license. Verify your storage allocation before migrating large attachment volumes. A 50,000-conversation workspace with an average of 2 attachments per conversation at 500 KB each consumes roughly **50 GB**. File-heavy projects often hit storage constraints long before they hit case-row limits. Check your current usage at Setup → Storage Usage before starting extraction.

### Large-Volume Considerations: 500K+ Conversations

For workspaces with more than 500,000 conversations, standard Case objects may not be the right target for all historical data. Consider a tiered approach:

- **Active/recent conversations (last 12–24 months):** Migrate to standard Case objects for full agent access and reporting.
- **Archived conversations (older than 24 months):** Migrate to Salesforce Big Objects or an external archive (e.g., Amazon S3 with a Salesforce External Object connection) for compliance and audit access without consuming Case storage and impacting query performance.
- **Threshold indicator:** When your total Case count exceeds 5–10 million records, standard SOQL queries and list views begin to degrade noticeably. Big Objects support up to 1 billion records with indexed query access.

## Migration Approaches Compared

| Approach | How It Works | Best For | Complexity | Risk Level |
|---|---|---|---|---|
| **Intercom Native Salesforce App** | Real-time sync of new conversations to Cases or Tasks. | Ongoing sync, not historical migration. Does not back-fill history. | Low | High for migration. |
| **iPaaS (Zapier / Make)** | Trigger-action workflows per conversation. Per-task pricing. | Small-volume real-time event routing. | Low | High (cost per task, no batch capability). |
| **Custom ETL Script** | Python/Node.js scripts using Intercom REST API + Salesforce Bulk API 2.0. | Teams with Salesforce API experience and available engineering bandwidth. | High | Medium (if well-tested). |
| **Managed Migration Service** | Expert team handles extraction, transformation, loading, and validation. | Enterprise volumes, zero-downtime requirements, complex field mappings. | Low (for your team) | Low |

> [!WARNING]
> Intercom's native Salesforce integration is designed for ongoing sync, not bulk historical migration. By default, it maps conversation transcripts to **Tasks on the Contact record**, not to Cases. While auto case creation exists, it requires explicit configuration, does not back-fill historical conversations, and forces chat transcript into `Case.Description` — which can fail on field validation and does not support formula fields. ([intercom.com](https://www.intercom.com/help/en/articles/5203865-using-the-salesforce-app-in-intercom))

**Decision matrix:**
- **< 5,000 conversations, simple fields:** Custom script is feasible if you have an engineer with Salesforce API experience. Estimated effort: 40–80 engineer-hours.
- **5,000–50,000 conversations:** Custom ETL with dedicated engineering time (2–3 weeks, 120–200 engineer-hours).
- **50,000+ conversations or zero-downtime requirement:** Managed migration service.

## How Long Does an Intercom to Salesforce Service Cloud Migration Take?

A standard Intercom to Salesforce migration takes **2 to 4 weeks** from kickoff to final cutover. The process should follow a phased approach rather than a risky big-bang deployment.

| Phase | Duration | Activities |
|---|---|---|
| Discovery & mapping | 2–3 days | Audit Intercom data volumes, map fields, define transformation rules, identify missing required fields in Salesforce. Document Intercom Messenger customizations, saved replies, and webhook configurations. |
| Environment setup | 1–2 days | Create custom fields, External_ID__c fields, enable audit fields, configure Case Record Types and Queues. Deactivate assignment rules, auto-response rules, escalation rules, and email-triggering automations. |
| Extraction & transformation | 3–5 days | Extract all historical data via the Intercom REST API. Cleanse data, transform to Salesforce-ready formats. Download all attachments from Intercom CDN. |
| Sandbox test load | 2–3 days | Push a subset of data (e.g., 10% of Cases) into a Salesforce Full Copy Sandbox. Fix issues. Verify governor limit behavior with active triggers. |
| UAT & validation | 2–3 days | Support managers validate the sandbox data. Verify thread chronology, attachments, SLA timers. Run programmatic reconciliation (see Validation section). |
| Production load & delta sync | 1–2 days | Load historical data into production. Run final delta sync for records created during migration. |
| Post-migration configuration | 1–2 days | Re-enable assignment rules, escalation rules, and automations. Configure Omni-Channel routing, SLA Entitlements, and Milestones. Rebuild saved replies as Quick Text. |
| **Total** | **14–22 business days** | |

For a ready-to-use project checklist, see our [Salesforce Service Cloud migration checklist](https://clonepartner.com/blog/blog/salesforce-service-cloud-migration-checklist/).

### Delta Sync Strategy for Zero Downtime

Agents keep working in Intercom throughout the migration. During the final cutover window:

1. Run the full historical migration on a Friday evening.
2. Saturday morning: run a delta sync that pulls only conversations with `updated_at` after the migration start timestamp.
3. Validate record counts and spot-check 50 random conversations.
4. Monday morning: switch agents to Salesforce Service Cloud.

This ensures no tickets are lost during the transition and no agent downtime occurs.

## What Do Customers and Agents Notice During Migration?

With a properly executed migration, customers notice **nothing**. Active conversations continue in Intercom until cutover. Post-cutover, customers may notice:

- **New reply-from addresses** if Service Cloud uses a different support email.
- **Different self-service portal** if you're replacing Intercom's Help Center with Salesforce Knowledge.
- **Conversation history gaps** only if transcripts were truncated by the 4,000-char CaseComment limit or the 500-part retrieval cap.

Agents will notice more: new Case numbers, different queues and owners, different search behavior, and the shift from Intercom's thread view to Cases, comments, and Files. The operational detail that matters most is **history trust**. If agents cannot see who said what and when, adoption drops fast.

Preserving full conversation history directly impacts First Contact Resolution (FCR) rates and Customer Satisfaction (CSAT) scores. A poorly executed migration forces agents to ask customers to repeat themselves because historical context is missing.

**Change management checklist:**
- Notify customers of any support email address changes 2 weeks before cutover.
- Train agents on the Salesforce Service Cloud console 1 week before go-live.
- Run parallel support for 48 hours post-cutover (monitor both systems).
- Tell agents explicitly what appears as Cases, what appears as comments, and what stays in an archive or exception set.
- Keep Intercom read-only for a short fallback window after go-live.

## Edge Cases and Known Limitations

- **Deleted/inactive users in Intercom.** Intercom allows conversations to remain assigned to deleted teammates. Salesforce rejects any record assigned to an invalid or inactive `OwnerId`. Map all deleted Intercom users to an active "System Migration" user in Salesforce, or reactivate them temporarily during the load.
- **Duplicate contacts.** Intercom allows multiple records with the same email (one as User, one as Lead). Salesforce enforces unique email on Contact. De-duplicate before import.
- **Multi-company contacts.** Intercom Users can belong to multiple Companies. Salesforce Contact has a single `AccountId`. Choose a primary Account and store others in a junction object or multi-select field.
- **Archived contacts.** Intercom archives inactive contacts. You must unarchive them via the API (`POST /contacts/{id}/unarchive`) before you can retrieve their full data — there is no UI option for bulk unarchiving.
- **Conversations with > 500 parts.** The API caps `conversation_parts` at 500 per retrieval. Long-running threads may have more, requiring paginated extraction and an explicit exception plan. ([developers.intercom.com](https://developers.intercom.com/docs/references/2.13/rest-api/api.intercom.io/conversations/retrieveconversation))
- **HTML sanitization.** Intercom conversation parts contain HTML (`<p>`, `<a>`, `<img>` tags). CaseComment stores plain text only — you must strip HTML. If you use EmailMessage, HTML is preserved, but Salesforce rich text fields enforce a strict tag whitelist. Unsupported tags (complex nested tables, custom div classes, `<script>`, `<style>`) will cause the API to reject the entire record with `INVALID_MARKUP`. Sanitize during the transformation phase.
- **Timezone handling.** All Intercom timestamps are Unix epoch (UTC). Salesforce `CreatedDate` requires ISO 8601. Example conversion: `1735689600` → `2025-01-01T00:00:00.000Z`.
- **CreatedDate override.** By default, creating a Case in Salesforce stamps `CreatedDate` as the moment the API call runs. To preserve original Intercom timestamps, enable "Set Audit Fields upon Record Creation" **before** your first pilot load. This requires contacting Salesforce Support or using the Metadata API to enable the `CreateAuditFields` permission. Without this, a ticket from 2022 will appear as if it was created today. ([help.salesforce.com](https://help.salesforce.com/s/articleView?id=000334139&language=en_US&type=1))
- **Conversation ratings.** Intercom CSAT ratings can be migrated as custom fields on the Case (e.g., `Intercom_Rating__c` picklist with values 1–5 and `Intercom_Rating_Remark__c` long text) but do not map to Salesforce's native CSAT survey mechanism.
- **Record locking during parallel loads.** If multiple Bulk API jobs update records sharing the same parent Account, you will encounter `UNABLE_TO_LOCK_ROW` errors. Sort your CSV payloads by `AccountId` and reduce job parallelism to avoid this.

## Validation and Testing

Do not rely on visual spot-checks. Execute a programmatic reconciliation strategy.

**Record-count reconciliation:** After migration, compare total counts at each level:

| Object | Intercom Count | Salesforce Count | Expected Delta |
|---|---|---|---|
| Companies → Accounts | X | X | 0 |
| Users → Contacts | X | X | May differ if duplicates merged |
| Conversations → Cases | X | X | 0 (minus intentional exclusions) |
| Conversation Parts → CaseComments/EmailMessages | X | X | 0 |
| Attachments → ContentVersions | X | X | 0 |

**Field-level sampling:** Pull 50 random Cases and compare every field against the source Intercom conversation. Check: timestamps, assignee, tags, status, and full transcript content. Verify that `CreatedDate` matches the Intercom `created_at` (not the migration run timestamp).

**Thread integrity checks:** For a random sample of 100 Cases, verify that the number of CaseComments or EmailMessages matches the number of Conversation Parts in Intercom. Verify chronological ordering — parts should appear in the same sequence as the original Intercom thread.

**Attachment validation:** Run a SOQL query to identify any Cases that had attachments in the source data but lack a corresponding `ContentDocumentLink` in Salesforce:

```sql
SELECT Id, Intercom_Conversation_Id__c
FROM Case
WHERE Intercom_Has_Attachments__c = true
AND Id NOT IN (SELECT LinkedEntityId FROM ContentDocumentLink)
```

**Bulk API result review:** Check all success, failed, and unprocessed result files from every Bulk API job. Nothing unexplained should remain. Common failure patterns: `INVALID_CROSS_REFERENCE_KEY` (broken parent reference), `STRING_TOO_LONG` (CaseComment overflow), `REQUIRED_FIELD_MISSING` (null LastName or Status). ([resources.docs.salesforce.com](https://resources.docs.salesforce.com/latest/latest/en-us/sfdc/pdf/api_asynch.pdf))

**>500-part exception review:** Verify every conversation flagged with `count_conversation_parts > 500` before sign-off. Cross-check the Salesforce CaseComment/EmailMessage count against the Intercom source count for each.

**Rollback plan:** Keep the Intercom workspace active for 30 days post-cutover. If critical issues emerge within the first week:

1. Switch agents back to Intercom immediately.
2. In Salesforce, identify all migrated records using `External_ID__c IS NOT NULL` and the migration user's `CreatedById`.
3. Delete child records first (ContentDocumentLink → ContentVersion → CaseComment/EmailMessage → Case → Contact → Account) to respect referential integrity.
4. For records created natively in Salesforce during the migration window (new Cases from live channels), export these before deletion and re-import into Intercom or preserve them separately.

Do not cancel your Intercom subscription until validation is complete and the 30-day fallback window has passed.

For a detailed QA process, see our [post-migration QA checklist](https://clonepartner.com/blog/blog/help-desk-data-migration-qa-checklist/).

## Post-Migration: Configuring Service Cloud

Migrating data is only half the project. The reason teams move to Service Cloud is for its enterprise case management capabilities. After data loading and validation, configure:

- **Omni-Channel Routing:** Set up routing configurations, service channels, and agent presence statuses. Map Intercom team assignments to Salesforce skill-based routing rules.
- **Entitlements & Milestones:** Define SLA policies that replace Intercom's SLA tracking. Create Entitlement Processes with Milestone Types (First Response, Resolution) and corresponding Milestone Actions.
- **Escalation Rules:** Rebuild any Intercom escalation workflows as Salesforce Escalation Rules with time-based criteria.
- **Quick Text:** Recreate Intercom saved replies as Salesforce Quick Text records for agent efficiency.
- **Case Assignment Rules:** Configure rules based on criteria (product, priority, language) to replace Intercom's round-robin or workload-based assignment.
- **Knowledge Base:** If you migrated Help Center Articles, configure Knowledge article types, data categories, and publishing workflows.

These configurations should be tested in the sandbox alongside the migrated data before production cutover.

## Build In-House or Use a Managed Service?

**Build in-house when:**
- You have fewer than 10,000 conversations with simple, flat custom fields.
- Your team has available engineering capacity (120–200 hours) and Salesforce API experience.
- You can tolerate a 1–2 day cutover window with some manual cleanup.

**Use a managed service when:**
- You have 50,000+ conversations or strict zero-downtime requirements.
- Conversations contain heavy attachments, inline images, or HTML that needs re-hosting.
- You need to preserve exact timestamps, threading, and author attribution.
- A failed migration requiring a re-run would cost more than doing the first one correctly.

The hidden cost of DIY is not the initial script — it's the edge cases that surface at 80% completion: the 429 rate limit cascade that corrupts your batch state, the CaseComment truncation you didn't catch until UAT, the orphaned attachments from expired CDN URLs, the `UNABLE_TO_LOCK_ROW` errors from parallel Bulk API jobs, the hours spent writing custom parsers for inline HTML images. Each of these adds 1–2 weeks to the project. For a deeper analysis of why custom migration scripts fail, see [why AI migration scripts fail](https://clonepartner.com/blog/blog/why-ai-migration-scripts-fail/).

ClonePartner removes this engineering burden entirely. We handle the Intercom extraction, Salesforce Bulk API loading, attachment re-hosting, and edge case resolution so your engineers stay on product work. By running continuous delta syncs during the final cutover window, we guarantee zero downtime — your agents never miss a message.

> Need to migrate from Intercom to Salesforce Service Cloud without losing transcripts or downtime? Our engineers can scope your project in a 30-minute call.
>
> [Talk to us](https://cal.com/clonepartner/meet?duration=30)

## Frequently asked questions

### Can Intercom conversation history be preserved in Salesforce Service Cloud?

Yes. Every Intercom conversation part — customer messages, agent replies, internal notes, and bot interactions — can be migrated to Salesforce as CaseComments or EmailMessages on the corresponding Case. The key constraint is the 4,000-character limit on CaseComment.CommentBody; use EmailMessage objects to preserve full HTML content and avoid truncation. Also plan explicit exceptions for threads longer than 500 conversation parts, since the Intercom API caps retrieval at 500.

### How much does an Intercom to Salesforce Service Cloud migration cost?

Cost depends on volume and complexity. A managed migration for 10,000–50,000 conversations typically costs $5,000–$15,000. Enterprise migrations (100,000+ conversations with attachments and zero-downtime requirements) range from $15,000–$40,000. DIY costs 120–200 engineer-hours plus the opportunity cost of pulling developers off product work.

### What data cannot be migrated from Intercom to Salesforce Service Cloud?

Intercom Fin AI training and configuration, Product Tours, Checklists, Series (automated sequences), custom bot flows, and Messenger styling cannot be migrated. These must be rebuilt natively in Salesforce using Einstein, Agentforce, or Flows. Conversation ratings can be migrated as custom fields but don't map to Salesforce's native CSAT mechanism.

### Does the native Intercom Salesforce integration handle historical migration?

No. Intercom's native Salesforce app is designed for ongoing sync of new conversations, not bulk historical migration. It creates Cases or Tasks from active conversations going forward and does not back-fill historical conversation data into Salesforce.

### Can I migrate Intercom to Salesforce Service Cloud without downtime?

Yes, with a delta sync strategy. Run the full historical migration while agents continue working in Intercom. Before cutover, run a final delta sync to capture conversations created or updated during the migration window. This ensures zero missed tickets and no agent downtime.
