Skip to content

How to Migrate from Intercom to Zendesk (Step-by-Step)

A technical guide to migrating from Intercom to Zendesk — covering API rate limits, field mapping, timestamp preservation, attachment handling, and failure modes.

Raaj Raaj · · 15 min read
How to Migrate from Intercom to Zendesk (Step-by-Step)

Migrating from Intercom to Zendesk is a data modeling problem, not a button-click. Intercom organizes everything around conversations — flat threads of messages between contacts and admins. Zendesk organizes everything around tickets — structured records tied to requesters, organizations, groups, and agents with discrete public/private comments. Every field, timestamp, and relationship has to be translated between these two models, and the gaps between them are where data gets silently dropped.

This guide covers the structural mismatches, API constraints on both sides, field mapping decisions, attachment handling, and a comparison of migration methods — so you can pick the approach that fits your volume, timeline, and risk tolerance.

For a deeper look at Zendesk's architecture, pipelines, and configuration, see The Ultimate Zendesk Guide.

Why Migrating from Intercom to Zendesk Is a Data Modeling Challenge

Intercom's data model is contact-centric. A contact (user or lead) initiates a conversation. That conversation is a single thread with conversation_parts — each part is a message, a note, an assignment action, or a state change. Tags, custom attributes, and SLA data hang directly off the conversation object. Intercom uses companies linked to contacts, but there is no native concept of an "organization" in the Zendesk sense — and companies are not directly tied to conversations. (developers.intercom.com)

Zendesk's data model is ticket-centric. A ticket has a requester (user), belongs to an organization, is assigned to a group and an agent, and contains a flat list of comments — each marked public or private. Ticket metadata like priority, type, status, and custom fields are first-class properties. Side conversations, satisfaction ratings, and audit trails are separate API objects.

This structural gap creates three concrete problems:

  1. Conversations → Tickets: Each Intercom conversation becomes one Zendesk ticket. But Intercom's conversation_parts include assignment changes, state changes, and notes alongside actual messages. You have to decide which parts become public comments, which become private internal notes, and which are metadata you encode as tags or custom field values.

  2. Contacts → Users + Organizations: Intercom contacts can be users or leads. Zendesk requires every ticket to have a requester_id — a user who must already exist in Zendesk before ticket import. Intercom companies need to be mapped to Zendesk organizations, and the contact-company link needs to become a user-organization membership. If a contact belongs to multiple companies in Intercom, you have to pick one primary organization in Zendesk or use organization memberships if your plan supports it.

  3. State mapping: Intercom conversations have three states — open, closed, and snoozed. Zendesk tickets have five-plus states — new, open, pending, on-hold, solved, and closed. You need an explicit mapping table, and snoozed conversations have no direct Zendesk equivalent.

The extraction side is where many DIY migrations fail first. Intercom's list conversations endpoint does not return full conversation_parts — you must retrieve each conversation individually to get the full message thread and attachments. If you have 50,000 conversations, that is 50,000 individual API calls just for content retrieval, on top of the pagination calls to list them. (developers.intercom.com)

Danger

Hard source limit: If an Intercom conversation has more than 500 parts, the retrieve endpoint returns only the 500 most recent parts. Detect these threads before cutover and decide whether to accept truncation, preserve Intercom as a read-only archive for those threads, or build a compensating export path. (developers.intercom.com)

Info

Key distinction: Intercom treats conversations as living threads that can be reopened indefinitely. Zendesk treats closed tickets as archived records. Any conversation you import as "closed" in Zendesk cannot receive new comments — agents must create a follow-up ticket.

The API Rate Limits That Break DIY Migration Scripts

Every Intercom-to-Zendesk migration is bottlenecked by two rate-limiting regimes running simultaneously. Your extraction speed from Intercom and your import speed into Zendesk are independent ceilings, and the lower of the two sets your throughput.

Intercom API Limits

Intercom's official REST documentation describes default limits of 10,000 API calls per minute per app and 25,000 API calls per minute per workspace, distributed into 10-second windows to prevent traffic spikes. Exceeding the limit returns an HTTP 429 response with a Retry-After header. (developers.intercom.com)

Older Intercom community answers (from around January 2022) still cite 1,000 requests per minute and 166 per 10 seconds. Migration plans copied from old blog posts go stale fast. Always check the current vendor documentation before sizing your project.

The real constraint for migrations is not the raw rate limit — it is the number of calls required. Listing conversations returns metadata only. You must make a separate GET /conversations/{id} request for every single conversation to retrieve the full thread and attachments. That per-conversation retrieval is the biggest time sink on the extraction side.

Zendesk API Limits

Zendesk's Support API rate limits vary by plan:

Zendesk Plan Requests per Minute
Team 200
Growth 400
Professional 400
Enterprise 700
Enterprise Plus 2,500
High Volume API add-on 2,500

(Source: Zendesk Developer Docs — Rate Limits)

Some endpoints have their own additional limits. The Update Ticket endpoint is capped at 100 requests per minute on standard plans. The Incremental Export endpoint is limited to 10 requests per minute (30 with the High Volume add-on).

A real migration is not one read and one write per ticket. You page conversations, retrieve each full thread, resolve users and organizations, download binaries, upload those binaries to Zendesk, and then import the ticket. Each ticket with attachments requires at minimum two API calls on the Zendesk side (upload the attachment, then import the ticket) — and tickets with multiple attachments multiply that further.

This means your migration middleware needs separate source and target throttlers, durable checkpoints, idempotent retries, and 429-aware backoff on both sides. Standard ETL tools rarely have the granularity to manage per-endpoint throttling, which leads to complete job failures and silently lost conversations.

Warning

Attachment token expiry: Zendesk upload tokens expire after 60 minutes. If your script uploads a batch of attachments but doesn't import the associated tickets within that window, the uploads are deleted and the tokens return 404 errors. Batch your uploads and imports together.

How to Preserve Ticket History and Attachments in Zendesk

The most common failure in Intercom-to-Zendesk migrations is losing historical timestamps. If you use Zendesk's standard ticket creation endpoint (POST /api/v2/tickets), every ticket gets stamped with the current date. A three-year conversation history will appear as if it all happened today.

Use the Ticket Import API

The correct endpoint is POST /api/v2/imports/tickets. This is Zendesk's dedicated import endpoint that:

  • Preserves historical timestamps — created_at, updated_at, and solved_at
  • Accepts a custom author_id for every comment
  • Accepts value, body, or html_body for comment content
  • Bypasses triggers and automations
  • Does not send notifications to CC'd users

For bulk imports, POST /api/v2/imports/tickets/create_many accepts up to 100 tickets per request and processes them as an async job. (developer.zendesk.com)

curl https://{subdomain}.zendesk.com/api/v2/imports/tickets \
  -d '{
    "ticket": {
      "subject": "Original Intercom Conversation",
      "created_at": "2023-03-15T14:22:00Z",
      "updated_at": "2023-03-16T09:45:00Z",
      "solved_at": "2023-03-16T09:45:00Z",
      "status": "closed",
      "requester_id": 12345,
      "assignee_id": 67890,
      "tags": ["migrated-from-intercom"],
      "comments": [
        {
          "author_id": 12345,
          "created_at": "2023-03-15T14:22:00Z",
          "value": "Hi, I need help with my billing.",
          "public": true
        },
        {
          "author_id": 67890,
          "created_at": "2023-03-15T14:35:00Z",
          "value": "Sure, let me look into that for you.",
          "public": true
        }
      ],
      "custom_fields": [
        { "id": 114094651234, "value": "intercom-conv-98765" }
      ]
    }
  }' \
  -H "Content-Type: application/json" \
  -v -u {email}/token:{api_token} -X POST

Imported tickets are not the same as native Zendesk tickets. Triggers do not run on imported tickets unless the ticket is updated later. Imported tickets do not support native Zendesk metrics or SLA history. CC'd users are not notified during import. For historical tickets, that is fine. For still-active tickets, you need a deliberate post-import workflow — do not assume Zendesk automation will replay the past. (developer.zendesk.com)

Danger

SLA and metrics warning: Zendesk explicitly states that metrics and SLAs are not supported for imported tickets. Running reports on imported data will produce incomplete results. Add a migrated-from-intercom tag to all imported tickets so you can exclude them from SLA calculations and Zendesk Explore reports. Make that distinction clear with leadership before anyone expects historical Zendesk dashboards to mirror Intercom performance data.

The Two-Step Attachment Process

Attachments cannot be included inline in the ticket import payload. Zendesk requires a two-step process:

  1. Upload the file to /api/v2/uploads?filename=.... This returns an upload token.
  2. Include the token in the comment's uploads array when importing the ticket.
# Step 1: Upload the file
curl "https://{subdomain}.zendesk.com/api/v2/uploads?filename=screenshot.png" \
  --data-binary @screenshot.png \
  -H "Content-Type: image/png" \
  -v -u {email}/token:{api_token} -X POST
 
# Response includes: { "upload": { "token": "abc123xyz" } }
 
# Step 2: Use the token in the ticket import
# Include "uploads": ["abc123xyz"] in the comment object

The token is single-use — you cannot reuse it across multiple tickets. It expires after 60 minutes. The maximum file size is 50 MB. You cannot attach a file directly to a ticket or retroactively to an existing comment — the token must be included when the comment is created. (developer.zendesk.com)

Your migration script needs to: download the file from Intercom's CDN, upload it to Zendesk's uploads endpoint, capture the token, and embed it in the corresponding comment — all within the expiry window. If any step fails silently, the ticket imports successfully but the attachment is missing. You will not know until an agent opens the ticket.

Plaintext vs. HTML for Message Bodies

Decide early whether you are preserving formatting or prioritizing clean search and rendering. Intercom lets you retrieve conversation content as plaintext. Zendesk's import endpoint accepts plain text (value) or HTML (html_body) for comment content. Plaintext is usually the safer default for historical migrations. If you keep HTML, budget time to rewrite inline image and attachment references after the binaries are re-hosted in Zendesk. (developers.intercom.com)

Mapping Intercom Data to Zendesk: A Complete Field Guide

Good mapping decisions determine whether your agents can actually find and use historical conversations after the move. A bad mapping turns migration into a data graveyard.

For a deep dive on mapping methodology and downloadable CSV templates, see Your Ultimate Guide to Data Mapping for a Flawless Helpdesk Migration.

Core Object Mapping

Intercom Object Zendesk Object Notes
Contact (User) User Match on email address. Create before ticket import.
Contact (Lead) User Leads without email need a placeholder identity.
Company Organization Map company_id to organization. Handle multi-company contacts.
Conversation Ticket One conversation = one ticket.
Conversation Part (message) Comment (public) Map author to author_id. Set public: true.
Conversation Part (note) Comment (private) Set public: false. Failing to do this exposes internal chatter to customers.
Conversation Part (assignment) Tag or internal note No direct equivalent. Encode as internal note or skip.
Tag Tag Direct 1:1 mapping. Zendesk tags cannot contain spaces — sanitize first (e.g., "high priority" → "high_priority").
Custom Attribute Custom Field Create custom fields in Zendesk first. Match data types. If the field does not exist before import, the data is silently dropped.
Admin / Team Assignee Assignee / Group Requires a directory crosswalk between Intercom admins and Zendesk agents.
Statistics / SLA fields Custom field or internal note Do not force them into Zendesk's native metrics system. Preserve as reference only.

Status Mapping

Intercom State Zendesk Status Rationale
open open Active conversations stay active.
snoozed pending Closest equivalent — waiting on external action. Snoozed-until timestamps are lost; Zendesk's pending state has no scheduled reopen time.
closed closed Use archive_immediately parameter on import.

Preserving Historical Searchability

Zendesk assigns new IDs to every imported ticket — it does not preserve Intercom conversation IDs. Any bookmarks, internal wikis, or integrations referencing Intercom conversation IDs will break unless you store the mapping.

Create a custom text field in Zendesk (e.g., "Intercom Conversation ID") and populate it during import with the original Intercom conversation.id. Agents can then search using Zendesk's custom field search syntax:

GET /api/v2/search?query=type:ticket custom_field_123456:intercom-conv-98765

If the legacy ID is buried in a note instead of a searchable field, agents will stop using it within a week. (support.zendesk.com)

Also store the mapping externally — a simple CSV or database table linking intercom_conversation_idzendesk_ticket_id. You will need this for post-migration QA, redirect rules, and integration updates.

Company-to-Organization Relationships

Intercom contacts can belong to multiple companies. Zendesk can model many-to-many user/organization relationships through organization memberships, but only if your plan supports multiple organizations per user. If your operating model requires a single default organization, preserve extra Intercom company references in a custom user field or internal note instead of silently dropping them. (developers.intercom.com)

Map Intercom companies to Zendesk organizations first, capture the generated Zendesk Organization IDs, and then associate the imported users to those IDs. The import order matters.

Public Replies vs. Internal Notes

Intercom threads mix customer-visible messages and teammate-only notes in the same conversation parts array. Preserve the split carefully. Public replies become public Zendesk comments. Internal teammate notes become private comments with public: false. If you flatten everything into public comments, you have a privacy problem. If you drop internal notes, you erase the context that makes historical tickets useful in the first place.

What Gets Lost (and What to Do About It)

Some Intercom data has no Zendesk equivalent. Know these gaps before you start:

  • Conversation ratings — Intercom's rating system does not map to Zendesk CSAT. You can preserve the score as a custom field, but it will not appear in Zendesk's native satisfaction reports.
  • Contact-level notes — These are separate from conversation parts. Migrate them as user-level notes or append to a synthetic ticket.
  • Fin AI Agent data — Intercom's AI participation metadata (ai_agent_participated, resolution data) has no Zendesk equivalent. Preserve as tags or custom fields if needed for reporting.
  • Snoozed-until timestamps — Zendesk's pending state does not support a scheduled reopen time. The trigger is lost.
  • Group conversations — Intercom allows multiple contacts on a single conversation. Zendesk tickets have one requester. Additional participants can be added as CCs, but the model is fundamentally different.
  • SLA and statistics fields — Intercom's native SLA data and conversation statistics do not translate to Zendesk metrics. Preserve as custom fields or internal notes for reference, but do not expect them to appear in Zendesk Explore reporting.

What to Do Before You Start

Regardless of which migration method you choose, complete this preparation work first:

  • Audit your Intercom data. Count conversations, contacts, companies, tags, and custom attributes. Identify conversations with 50+ parts — these are your edge cases. Flag any conversations that might exceed the 500-part retrieval limit.
  • Clean up before migrating. Delete spam conversations, merge duplicate contacts, and archive stale leads. Every record you migrate costs time and API calls.
  • Set up your Zendesk instance. Create custom fields (including an "Intercom Conversation ID" field), groups, agent accounts, and organizations before import. The Ticket Import API requires valid requester_id, assignee_id, and group_id values — if any are missing, the import fails.
  • Plan your cutover window. Decide when agents stop using Intercom and start using Zendesk. Run the bulk migration before cutover, then run a delta sync to catch late-arriving conversations. A one-shot weekend dump is the risky option.
  • Tag everything. Add a migrated-from-intercom tag to all imported tickets. This lets you filter them out of SLA reports and identify them during QA.

For a complete pre-migration checklist, see The Go-Live Day Checklist: 15 Things to Do for a Smooth HelpDesk Migration.

Migration Methods: Automated Tools vs. DIY vs. Custom Engineering

There are three common approaches. Each has real trade-offs.

Self-Serve Automated Tools

Platforms like Help Desk Migration offer a UI-based migration wizard. For a direct comparison, see ClonePartner vs Help Desk Migration.

Works well for: Small volumes (under 5,000 tickets) with standard fields and minimal customization. Fast setup. Predictable per-ticket pricing.

Breaks on: Limited control over how conversation parts map to comments. Attachment handling is opaque and hard to verify for completeness. Custom attribute mapping is often rigid or incomplete. Rate limit handling is a black box — you cannot tune retry logic. Edge cases like multi-company contacts, conversations with 100+ parts, or the 500-part retrieval ceiling may fail silently.

DIY In-House Scripts

Building your own migration scripts using both APIs gives maximum control.

Works well for: Teams with a strong integration engineer and a flexible timeline. Full control over mapping logic. No per-ticket cost.

Breaks on: A production-grade script with proper rate limiting, retry logic, attachment handling, idempotency, and error logging typically takes 2–4 weeks for a senior engineer. Rate limit mishandling causes silent data loss (partial ticket imports where the text arrives but attachments do not). The per-conversation Intercom retrieval is the biggest time sink. Testing requires a Zendesk sandbox, careful QA, and a rollback plan.

Custom Engineering (Migration Service)

A dedicated migration team builds, tests, and executes custom scripts tailored to your dataset. This is the approach ClonePartner takes.

Works well for: Complex mappings, strict cutover windows, attachment-heavy history, and compliance-sensitive data. Battle-tested rate limit handling tuned to your specific Zendesk plan. Per-record verification. Zero downtime — the migration runs in parallel while your team continues using Intercom.

Breaks on: Higher upfront cost than self-serve tools for small, simple datasets. Requires a scoping phase (typically 1–2 days) before execution begins.

Method Good Fit Where It Typically Breaks
Automated SaaS tool Standard fields, modest volume, low customization Long threads, custom transforms, attachment edge cases, audit-heavy QA
DIY scripts Strong internal team, flexible timeline Retry logic, idempotency, attachment re-hosting, operator QA burden
Custom engineering partner Complex mappings, strict cutover, attachment-heavy history Higher scoping effort up front, but lower execution risk

The common failure modes across automated tools and DIY scripts are the same: truncated long threads, lost timestamps from using the wrong Zendesk endpoint, broken attachments because binaries were never re-hosted, company-to-organization mismatches, and the assumption that imported tickets will behave like native Zendesk tickets for triggers and SLA reporting. These are platform constraints, not bad luck. (developers.intercom.com)

How ClonePartner Handles Intercom-to-Zendesk Migrations

We have executed this exact migration many times. Here is what the process looks like:

  1. Scoping and mapping review — We audit your Intercom workspace to identify custom attributes, tag structures, conversation volumes, and attachment density. We produce a mapping document for your sign-off before writing a single line of code.

  2. User and organization pre-migration — Contacts and companies are migrated first. Every user is created or matched in Zendesk before ticket import begins, so requester_id references never fail.

  3. Conversation extraction with intelligent throttling — Our scripts dynamically adjust request pacing based on Intercom's rate limit response headers, maximizing throughput without hitting 429 errors.

  4. Ticket import with attachment validation — Each conversation is imported via the Ticket Import API with historical timestamps. Attachments go through the two-step upload/token process with per-file verification. If an upload fails, the script retries before moving to the next ticket.

  5. Post-migration QA — We run a full record-count reconciliation and spot-check tickets across volume tiers. Every custom field, tag, and attachment is validated against the source.

  6. Delta sync — If conversations are created or updated in Intercom during migration, we run a delta pass to catch them before cutover. Your team does not have to stop working in Intercom until QA is complete.

For a behind-the-scenes look at our process, see How We Run Migrations at ClonePartner.

We are not the right answer for every migration. If your Intercom workspace is small, lightly customized, and not attachment-heavy, a self-serve tool may be enough. If you have long threads, messy custom fields, multiple organization relationships, compliance-sensitive notes, or a hard zero-downtime cutover window, you want custom engineering instead of a generic adapter.

Making the Right Call

An Intercom-to-Zendesk migration is straightforward in principle — conversations become tickets, contacts become users, companies become organizations. The complexity lives in the details: rate limit choreography across two APIs, the two-step attachment upload process, timestamp preservation via a dedicated import endpoint, the 500-part thread ceiling, and the dozen structural mismatches that automated tools paper over instead of solving.

If your dataset is small and simple, a self-serve tool can get the job done. If you have years of conversation history, attachments, custom fields, and a support team that cannot afford to lose context on a single ticket, the engineering needs to be precise.

That is what we do. We treat migration as a data engineering discipline — custom extraction, field-level mapping, per-record verification, and a cutover plan that keeps support running throughout.

Frequently Asked Questions

Does Zendesk preserve original timestamps when importing from Intercom?
Only if you use the dedicated Ticket Import API endpoint (POST /api/v2/imports/tickets). This endpoint preserves created_at, updated_at, and solved_at timestamps. The standard ticket creation API overwrites all dates with the current time.
How do attachments work in an Intercom to Zendesk migration?
Zendesk requires a two-step process: upload each file to /api/v2/uploads to get a single-use token (expires in 60 minutes), then embed that token in the ticket comment's uploads array during import. Your script must download each file from Intercom, upload it to Zendesk, and use the token before expiry. The max file size is 50 MB.
What data gets lost when migrating from Intercom to Zendesk?
Intercom conversation ratings, snoozed-until timestamps, Fin AI agent metadata, contact-level notes, and group conversation multi-contact structures have no direct Zendesk equivalent. These can be partially preserved using custom fields and tags, but native reporting for them is lost. Imported tickets also do not support native Zendesk SLA or metric history.
How long does an Intercom to Zendesk migration take?
It depends on volume and complexity. A dataset under 10,000 conversations with minimal attachments can be migrated in 1–3 days. Larger datasets (50,000+ conversations) with attachments and custom fields typically take 3–7 days including QA, mainly due to API rate limits on both platforms.
Can I keep Intercom conversation IDs in Zendesk after migration?
Zendesk assigns new ticket IDs and cannot preserve Intercom IDs. The best practice is to create a custom text field in Zendesk (e.g., 'Intercom Conversation ID') and populate it during import so agents can search for migrated tickets by their original ID.

More from our Blog

ClonePartner vs Help Desk Migration: 2026 Price & Feature Comparison
Why Choose ClonePartner

ClonePartner vs Help Desk Migration: 2026 Price & Feature Comparison

Choosing between ClonePartner and Help Desk Migration for your data migration in 2026? This essential guide provides a head-to-head comparison of features, true costs, and security compliance. We break down the critical differences between a DIY automated tool and a managed, engineer-led service , analyzing key factors like custom data handling, "Delta Migration," and the "hidden costs" of an in-house project so you can choose the right approach for your team.

Raaj Raaj · · 10 min read
Your Ultimate Guide to Data Mapping for a Flawless Helpdesk Migration (with CSV Templates)
Help Desk

Your Ultimate Guide to Data Mapping for a Flawless Helpdesk Migration (with CSV Templates)

This guide provides a complete playbook for data mapping, the most critical step for a flawless helpdesk migration. It explains how to match data fields from your old help desk to your new one, ensuring no customer data is lost and your reports remain accurate. You'll get practical templates for mapping tickets, users, and organizations , along with CSV examples showing how to transform data like ticket statuses. Learn to avoid common, costly mistakes like mishandling custom fields, ignoring attachments, or forgetting data dependencies.

Raaj Raaj · · 7 min read
The Go-Live Day Checklist: 15 Things to Do for a Smooth HelpDesk Migration
Help Desk

The Go-Live Day Checklist: 15 Things to Do for a Smooth HelpDesk Migration

Master your helpdesk migration with this definitive 15-point go-live day checklist. This guide provides a strategic framework to navigate the critical help desk cutover, from the final 24-48 hour countdown to the post-launch hypercare phase. Follow these expert steps, born from engineer-led experience, for a smooth, zero-downtime transition, preventing data loss and ensuring a flawless launch.

Raaj Raaj · · 10 min read
Zendesk to Intercom Migration: The 2026 Technical Guide
Migration Guide/Intercom/Zendesk

Zendesk to Intercom Migration: The 2026 Technical Guide

A technical guide to migrating from Zendesk to Intercom — covering data model mismatches, API rate limits, attachment handling, notification traps, and how to choose the right migration method.

Raaj Raaj · · 18 min read