---
title: "Zendesk to Front Migration: The 2026 Technical Guide"
slug: zendesk-to-front-migration-the-2026-technical-guide
date: 2026-04-20
author: Raaj
categories: [Migration Guide, Front, Zendesk]
excerpt: "A technical guide to migrating from Zendesk to Front. Covers API rate limits, field mapping, migration methods, edge cases, and validation strategies."
tldr: "Zendesk to Front migration requires API-level extraction (CSV won't work), careful field mapping from tickets to conversations, and rate limit orchestration across both platforms to avoid silent data loss."
canonical: https://clonepartner.com/blog/zendesk-to-front-migration-the-2026-technical-guide/
---

# Zendesk to Front Migration: The 2026 Technical Guide


Migrating from Zendesk to Front is a data-model translation problem. Zendesk is ticket-centric: every support interaction is a structured record with statuses, priorities, groups, custom fields, and SLAs. Front is conversation-centric: everything lives as threaded messages in shared inboxes, with collaboration happening via comments on the thread rather than internal notes on a ticket. The mapping between these two models is not one-to-one, and every structural gap is where data silently disappears if you don't plan for it.

This guide covers the exact API constraints on both platforms, a complete field-mapping table, a comparison of every realistic migration method, and the edge cases that cause silent data loss — so engineering teams can move to Front without losing ticket history or operational context.

> [!WARNING]
> **Front's native Zendesk importer is not actively maintained.** Front's own documentation states: "we recommend using one of our migration partners" and notes the built-in importer is available "at no additional cost, but it is not actively maintained." Plan accordingly. ([help.front.com](https://help.front.com/en/articles/2203))

> [!NOTE]
> **Scope check:** This guide covers **Zendesk Support** migrations, not Zendesk Sell. If your workflow depends on CRM objects like leads or opportunities, those don't belong in Front's core data model. Front can surface CRM records through integrations (Salesforce, HubSpot), but those remain CRM data, not native Front objects. ([help.front.com](https://help.front.com/en/articles/2305))

For a deeper look at Front's architecture and omni-channel capabilities, see [Mastering Front: A Technical Deep Dive](https://clonepartner.com/blog/blog/ultimate-guide-front-2026/). If you're still evaluating the move, [Why Forward-Thinking Teams Are Choosing Front](https://clonepartner.com/blog/blog/why-migrate-to-front/) covers the strategic case. For a complete walkthrough on getting data out of Zendesk, [How to Export Tickets from Zendesk](https://clonepartner.com/blog/blog/how-to-export-tickets-from-zendesk/) covers every native option and its limits.

## Why Teams Migrate from Zendesk to Front

The typical driver is a shift from **queue-based ticketing** to **collaborative inbox**. Common triggers:

- **Cross-functional collaboration.** Teams that involve sales, ops, logistics, or finance in customer conversations find Zendesk's ticket model too rigid. Front's shared inboxes let multiple people work a thread natively.
- **Cost consolidation.** Mid-market teams paying for Zendesk Suite Professional look at Front's Growth plan and see immediate savings — especially when they don't need Zendesk's ITSM or marketplace depth.
- **Simplicity.** Front's UX resembles a modern email client. Teams that over-invested in Zendesk customization often want to reset to something lighter.
- **Industry-specific workflows.** Logistics, financial services, and agency teams that rely on email-heavy, relationship-driven communication find Front's threading model more natural than Zendesk's ticket abstraction.

## Zendesk vs. Front: Core Architecture

Before writing a single line of migration code, internalize the structural differences. These are not just different products — they use fundamentally different data models.

| Concept | Zendesk | Front |
|---|---|---|
| Core unit | **Ticket** (structured record) | **Conversation** (message thread) |
| Messages | Comments on a ticket | Messages in a conversation |
| Internal notes | Private comments | Comments on a conversation |
| Routing | Groups → Agents | Inboxes → Teammates |
| Customer identity | Users (end-users) + Organizations | Contacts + Accounts |
| Custom data | Custom ticket fields, custom objects | Custom fields on conversations, contacts, accounts (up to 50 per category) |
| Knowledge base | Zendesk Guide (native) | No native KB |
| Automation | Triggers, automations, macros | Rules (linear and branching) |
| Status model | New → Open → Pending → Hold → Solved → Closed | Open → Archived → Deleted (plus Snoozed, Waiting) |

The critical distinction: **Zendesk separates the "ticket" from its "comments." Front treats the conversation as the primary object, with messages as its children.** Every Zendesk ticket becomes a Front conversation. Every Zendesk comment — public or private — becomes a Front message or internal comment within that conversation. If the threading logic fails, you end up with orphan messages and a fragmented customer history.

## Zendesk Export: API Limits and Bottlenecks

Getting data out of Zendesk is the first bottleneck. Three native export options exist, and only one is viable for a real migration.

### CSV Export: Not a Migration Format

Zendesk's CSV export from Admin Center is useful for reporting. It is **not** a migration format. The CSV export excludes:

- **Ticket comments and descriptions** — you get metadata only (ID, subject, status, requester, timestamps)
- **Multi-line text fields, multi-select fields, and custom date fields**
- **Deleted tickets**
- **Attachments**
- **Records updated within the last six minutes** of the export request
- View exports cap at **1,000 tickets** with no warning when truncated

As Zendesk's documentation confirms, "multi-line text and multi-select fields, as well as custom date fields, are excluded from CSV reports." ([support.zendesk.com](https://support.zendesk.com/hc/en-us/articles/4408886165402-Exporting-ticket-user-or-organization-data-from-your-account))

For a full breakdown of extraction limits, see [How to Export Tickets from Zendesk](https://clonepartner.com/blog/blog/how-to-export-tickets-from-zendesk/).

### JSON/XML Full Export: Slow and Constrained

The full data export from Admin Center produces JSON or XML files that include comments. But it carries its own problems:

- **Rate-limited to roughly one export request per week**
- **1 MB per-ticket limit** — tickets exceeding this have their comments stripped with a `MaximumCommentsSizeExceeded` error
- **XML capped at ~500 MB** (roughly 200K tickets)
- **Processing can take 24+ hours** for large accounts
- **No incremental updates** — it's a point-in-time snapshot
- **Six-minute exclusion window** — items updated within six minutes of the export are skipped

Zendesk recommends JSON for accounts with more than 200,000 tickets. The full export is a useful validation artifact or pre-migration backup, but it's not a reliable extraction method for production migrations. ([support.zendesk.com](https://support.zendesk.com/hc/en-us/articles/4408886165402-Exporting-ticket-user-or-organization-data-from-your-account))

### Incremental Export API: The Only Real Option

The **Incremental Export API** is the only viable extraction method for migration. It returns tickets (and users, organizations) that have changed since a given timestamp, using cursor-based pagination.

**Key constraints:**

| Parameter | Limit |
|---|---|
| Rate limit (tickets, cursor-based) | 10 requests per minute |
| Rate limit (users, cursor-based) | 20 requests per minute |
| Rate limit (with High Volume add-on) | Up to 30 requests per minute |
| Results per page | Up to 1,000 items |
| Time-based exports | May contain duplicates |
| Data freshness | Excludes changes from the last ~60 seconds |

([developer.zendesk.com](https://developer.zendesk.com/api-reference/introduction/rate-limits/))

At 10 requests per minute returning 1,000 tickets per page, you can extract roughly **10,000 ticket stubs per minute** in metadata. But ticket comments are not included in the incremental ticket export — you need to fetch them separately via the Ticket Comments API for each ticket. That multiplies your API calls by the number of tickets, quickly burning through your general rate limit (200–700 rpm depending on plan).

A single Zendesk ticket can contain up to **5,000 comments**. ([developer.zendesk.com](https://developer.zendesk.com/api-reference/ticketing/tickets/ticket_comments/))

> [!NOTE]
> **Practical throughput.** For a 100K-ticket account with an average of 8 comments per ticket, expect the full extraction (tickets + all comments + attachments) to take **6–12 hours** when properly throttled against Zendesk's rate limits. Rushing it triggers 429 errors and can get your API token temporarily blocked.

For an in-depth walkthrough of every export method, see [3 Advanced Ways to Export Tickets from Zendesk](https://clonepartner.com/blog/blog/advanced-ways-export-tickets-from-zendesk/).

## Front API: Import Limits and Constraints

Front's API is well-documented but tightly rate-limited, especially for migration workloads.

### Rate Limits by Plan

| Front Plan | Global Rate Limit |
|---|---|
| Starter | 50 requests/min |
| Growth | 100 requests/min |
| Scale | 200 requests/min |
| Premier | 500 requests/min |

These limits are **enforced per-company, not per-token**. If your team runs live integrations (Salesforce sync, Slack notifications, Zapier automations) while your migration script runs, they all share the same quota. A migration that saturates the API will degrade your team's live workflows. ([dev.frontapp.com](https://dev.frontapp.com/docs/rate-limiting))

Front also enforces **burst limits** — generally 5 requests per second per resource type. Even if your global limit says 200/min, you can't fire 200 calls in the first 3 seconds.

### The `imported_messages` Endpoint

This is the endpoint for historical migration:

```
POST /inboxes/{inbox_id}/imported_messages
```

Key behaviors:

- **One message per request.** There is no bulk import endpoint. Every Zendesk comment becomes one API call to Front.
- **Historical only.** Front's docs explicitly state this endpoint is for historical, non-active conversations. Do not use it to create messages for new conversations.
- **Attachment limit: 25 MB per message** via multipart form data.
- **Threading via `conversation_id`.** The first imported message creates a new conversation. Subsequent messages thread onto it by referencing the conversation ID returned by the first call.
- **Idempotent via `external_id`.** Front will not import two messages with the same `external_id`. This is what makes safe retries possible.
- **Metadata support.** You can set `created_at` (Unix timestamp), `sender` handle, `to` recipients, `subject`, and `body` (HTML supported).

([dev.frontapp.com](https://dev.frontapp.com/reference/import-inbox-message))

### Import Throughput Math

On a Growth plan (100 rpm), importing a ticket with 8 comments takes 8+ API calls (one per comment, plus calls for tags, custom fields, and contact linking). That means roughly **10–12 complete tickets per minute**. A 50K-ticket account would take **~60–80 hours** of continuous import at this rate.

> [!TIP]
> **Negotiate a temporary rate limit increase.** Front offers API rate limit add-ons on Scale plans and above. If you're migrating more than 20K tickets, request a temporary increase before starting. It can cut migration time by 50–75%.

## Data Mapping: Zendesk Tickets to Front Conversations

This is where migrations succeed or fail.

### Object-Level Mapping

| Zendesk Object | Front Equivalent | Notes |
|---|---|---|
| Ticket | Conversation | One ticket = one conversation |
| Ticket Comment (public) | Message (imported) | Direction inferred from comment author; mapped chronologically via `imported_messages` |
| Ticket Comment (private/internal note) | Comment | Internal-only, not visible to contacts |
| User (end-user) | Contact | Matched by email address |
| Organization | Account | Map company-level data; domain-based auto-association available in Front |
| Agent | Teammate | Matched by email |
| Group | Inbox | One group maps to one shared inbox |
| Tag | Tag | Direct mapping; tags must be pre-created in Front |
| Custom ticket field | Custom conversation field | Types must match; picklists need recreation; 50-field-per-category cap; text fields limited to 2,000 characters |
| Attachment | Attachment | 25 MB per message limit |
| Macro | — | Must be rebuilt as Front message templates |
| Trigger/Automation | — | Must be rebuilt as Front Rules |
| SLA Policy | — | Must be rebuilt in Front's SLA settings |
| Zendesk Guide article | — | Front has no native KB; use third-party |

### Field-Level Mapping Table

| Zendesk Field | Front Field | Transformation |
|---|---|---|
| `ticket.id` | Conversation custom field + `external_id` pattern | Store as reference; use `zd-{ticket_id}-c-{comment_id}` for message external IDs |
| `ticket.subject` | `conversation.subject` | Direct map |
| `ticket.status` | `conversation.status` + custom field | `New/Open` → `open`; `Pending/Hold` → `open` + tag/snooze; `Solved/Closed` → `archived`. Store original in custom field |
| `ticket.priority` | Custom conversation field or tag | Front has no native priority field |
| `ticket.type` | Custom conversation field or tag | Front has no ticket type |
| `ticket.tags` | `conversation.tags` | Must be pre-created in Front; native importer skips tags |
| `ticket.group_id` | `inbox_id` | Map each Zendesk group to a Front inbox |
| `ticket.assignee_id` | `conversation.assignee_id` | Match agent email → teammate ID |
| `ticket.requester_id` | Contact (sender of first message) | Lookup by email |
| `ticket.created_at` | First message `created_at` | Unix timestamp |
| `comment.body` | `message.body` | HTML body; strip Zendesk-specific markup (survey widgets, notification footers) |
| `comment.public` | Message (if true) / Comment (if false) | Determines import endpoint |
| `comment.author_id` | `message.sender` or comment author | Resolve to email handle |
| `comment.attachments` | `message.attachments` | Multipart upload; 25 MB cap |
| `ticket.custom_fields []` | Custom conversation fields | Must pre-create fields in Front via API; mind the 50-field cap and 2,000-char text limit |
| `organization.name` | `account.name` | Create accounts before contacts |
| `organization.domain_names` | `account.domains` | Normalize to lowercase; enables auto-association by domain |

([help.front.com](https://help.front.com/en/articles/2285), [dev.frontapp.com](https://dev.frontapp.com/reference/import-inbox-message))

### Handling Priority and Type

Front has no native priority or type field on conversations. Two options:

1. **Custom conversation fields** — Create a "Priority" dropdown in Front with values matching Zendesk's (Low, Normal, High, Urgent). Set via the API during import. This approach supports rule-based automation in Front.
2. **Tags** — Simpler but less structured. Tag conversations with `priority_high`, `priority_urgent`, etc.

Custom fields work better for priority (enables automation). Tags work better for type (typically used for filtering, not routing).

### Handling Statuses

Zendesk's multi-state status model doesn't map cleanly to Front's simpler model:

- **New / Open** → Import as `open` in Front
- **Pending / Hold** → Import as `open`, optionally snoozed with a tag (`status_pending` or `status_hold`)
- **Solved / Closed** → Import as `archived`

Front's native importer maps `Pending`, `Hold`, `Solved`, and `Closed` to Archived, and `New`/`Open` to Open. ([help.front.com](https://help.front.com/t/k9cd67/how-to-import-your-zendesk-history-into-front))

If you need to distinguish between original statuses post-migration for reporting or compliance, store the Zendesk status in a conversation custom field rather than trying to infer it later.

## Migration Methods Compared

There are six realistic approaches. Here's what each actually involves.

### 1. Front's Native Zendesk Importer

**How it works:** Built into Front's settings. Provide Zendesk API credentials, map groups to inboxes, match agents to teammates, and Front pulls tickets.

**What it does:**
- Maps Zendesk groups to Front inboxes
- Matches agents to teammates (with a default fallback)
- Imports assignee, status, and attachments
- Free — no additional cost
- As of Front's help article edited **December 2, 2025**, Front states the importer has **no hard limit** on Zendesk history import

**What it doesn't do:**
- **Not actively maintained** — Front explicitly says this and recommends migration partners instead
- No custom field migration
- No tag migration
- No rules/automation migration
- Limited error reporting and edge case handling
- No delta sync capability

**When to use it:** Small accounts with simple schemas where losing custom fields and tags is acceptable.

**Complexity:** Low | **Risk:** Medium-High

([help.front.com](https://help.front.com/t/k9cd67/how-to-import-your-zendesk-history-into-front))

> [!NOTE]
> **2026 clarification:** Older migration guides sometimes mention ticket caps for Front's native importer. Front's current Zendesk importer article says there is no hard limit, but also says the importer is not actively maintained. That combination means you should test for fidelity on a real subset, not assume either limitlessness or maturity. ([help.front.com](https://help.front.com/t/k9cd67/how-to-import-your-zendesk-history-into-front))

### 2. Self-Serve SaaS Tools (e.g., Help Desk Migration)

**How it works:** Connect both Zendesk and Front via API credentials. The tool maps fields and runs the migration.

**What it does well:**
- Visual mapping interface
- Support for tickets, agents, contacts, notes, tags
- Delta migration options
- Pre-migration demo with sample tickets

**What it doesn't do:**
- Custom field data may be moved into an **internal comment** rather than actual Front custom fields — verify with the vendor before committing
- Inline images may only transfer as attachments, not inline media
- Organizations/accounts may not be supported natively
- Limited control over error handling and retry logic

**When to use it:** Mid-size accounts (5K–50K tickets) with standard data. Good when you need faster turnaround than DIY without complex custom field requirements.

**Complexity:** Low-Medium | **Risk:** Medium

([help-desk-migration.com](https://help-desk-migration.com/help/front-data-migration-checklist/), [front.com](https://front.com/integrations/deskmigration))

### 3. CSV Export / Import

**How it works:** Export Zendesk data to CSV, reshape in spreadsheets, import into Front.

**When to use it:** Seeding Front contacts and accounts before a broader API migration. **Never** for full ticket history.

**Why:** Zendesk CSV excludes comments, descriptions, deleted tickets, and several field types. Front's CSV imports are for contacts and accounts only, not conversation history. Front's account CSV uploads are capped at 3,000 rows per file. ([support.zendesk.com](https://support.zendesk.com/hc/en-us/articles/4408886165402-Exporting-ticket-user-or-organization-data-from-your-account), [help.front.com](https://help.front.com/en/articles/2322))

**Complexity:** Low | **Risk:** High (for anything beyond contacts/accounts)

> [!WARNING]
> **Do not rely on CSVs for historical migrations.** Zendesk CSV exports strip out the actual conversation thread. You get metadata only, leaving agents blind to the actual customer interaction.

### 4. Direct API Migration (DIY)

**How it works:** Your engineering team writes scripts that extract from Zendesk's API, transform the data, and load into Front via the `imported_messages` endpoint.

**What it does well:**
- Full control over every field, transformation, and edge case
- Can handle custom objects, complex field mappings, and attachment re-hosting
- Can implement incremental sync and delta catches

**What it costs:**
- **Engineering time:** 80–200+ hours for a production-quality pipeline, depending on volume and complexity
- **Rate limit orchestration:** Must build retry logic, exponential backoff, and quota tracking for both APIs

**What goes wrong:**
- Unhandled 429 errors cause silent data loss mid-run
- Threading logic breaks when Zendesk comments have missing or malformed author data
- Attachment downloads from Zendesk URLs expire — you must buffer them during extraction
- The Incremental Export API returns duplicates in time-based mode that must be deduplicated

**When to use it:** Dedicated engineering team, >50K tickets, extensive custom fields, or need a repeatable pipeline during a phased rollout.

**Complexity:** High | **Risk:** Medium (if well-resourced) to High (if under-resourced)

For a reality check on why DIY scripts fail under migration pressure, see [Common Helpdesk Migration Mistakes](https://clonepartner.com/blog/blog/helpdesk-migration-mistakes-and-how-to-avoid-them/) and [Why AI Migration Scripts Fail](https://clonepartner.com/blog/blog/why-ai-migration-scripts-fail/).

### 5. Middleware / iPaaS (Zapier, Make)

**How it works:** Configure event-driven triggers and actions between Zendesk and Front. Zapier's Front app centers on triggers like New Inbound Message and actions like Add Comment, Assign Conversation, and Create Contact. ([zapier.com](https://zapier.com/apps/front-app/integrations))

**When to use it:** Post-cutover sync, alerts, routing, or light delta logic after the main historical import.

**Why not for migration:** Trigger-and-action tools are built for workflows, not for replaying years of ticket history with exact authorship, timestamps, attachments, and conversation threading. They're fragile at scale — missed events, replay difficulty, loops, and weak auditability.

**Complexity:** Low to start, High if you try to harden it into a migration engine.

### 6. Managed Migration Service

**How it works:** A specialist team handles the entire pipeline — extraction, transformation, loading, validation, and delta sync — using pre-built, battle-tested tooling.

**What it does well:**
- Preserves custom fields, tags, inline images, and attachments that other methods drop
- Handles rate limit orchestration across both APIs without crashing live workflows
- Provides validation reports (record counts, field-level spot checks, sample comparisons)
- Runs delta syncs for zero-downtime cutovers
- Completed in days, not weeks

**When to use it:** Complete data fidelity required, >10K tickets, no engineering cycles to spare, or tight go-live deadline.

**Complexity:** Low (for you) | **Risk:** Low

### Migration Methods Comparison

| Method | Complexity | Custom Fields | Tags | Attachments | Delta Sync | Best For |
|---|---|---|---|---|---|---|
| Front Native Importer | Low | ❌ | ❌ | ✅ | ❌ | Simple schemas, low stakes |
| SaaS Tool (HDM, etc.) | Low-Med | ⚠️ Varies | ✅ | ✅ | ✅ | 5K–50K, standard data |
| CSV Export/Import | Low | ❌ | ❌ | ❌ | ❌ | Contact/account seeding only |
| Custom DIY Scripts | High | ✅ | ✅ | ✅ | ✅ | Engineering-heavy orgs |
| iPaaS (Zapier/Make) | Low-High | ❌ | ❌ | ❌ | ⚠️ | Post-cutover sync only |
| Managed Service | Low (for you) | ✅ | ✅ | ✅ | ✅ | >10K, tight timelines |

## Step-by-Step Migration Process

Regardless of method, the process follows the same logical stages.

### Step 1: Audit and Scope Your Zendesk Data

- Count tickets by status (open, pending, solved, closed)
- Inventory custom ticket fields, user fields, and organization fields
- Identify unused tags, defunct groups, and deactivated agents
- Check attachment size distribution — flag anything over 25 MB
- Document macros, triggers, automations, and SLA policies (these must be rebuilt manually in Front)
- Identify side conversations and call recordings that sit outside the standard ticket comments export
- Decide what to migrate vs. what to leave behind. See [Helpdesk Migration Playbook](https://clonepartner.com/blog/blog/helpdesk-migration-playbook/) for scoping guidance.

### Step 2: Prepare the Front Environment

- Create all shared inboxes (one per Zendesk group you're migrating)
- Invite all teammates and match email addresses to Zendesk agents
- Pre-create all custom conversation fields via the API or UI
- Pre-create all tags
- **Disable any rules or automations** that could fire on imported conversations — imported messages can trigger auto-replies, assignments, and tagging rules if left active

### Step 3: Extract Data from Zendesk

Use the Incremental Export API (cursor-based) for tickets and users:

```python
import requests
import time

ZD_SUBDOMAIN = "yourcompany"
ZD_EMAIL = "admin@yourcompany.com/token"
ZD_TOKEN = "your_zendesk_api_token"
BASE_URL = f"https://{ZD_SUBDOMAIN}.zendesk.com/api/v2"

def extract_tickets(start_time=0):
    url = f"{BASE_URL}/incremental/tickets/cursor.json?start_time={start_time}"
    all_tickets = []
    
    while url:
        response = requests.get(url, auth=(ZD_EMAIL, ZD_TOKEN))
        
        if response.status_code == 429:
            retry_after = int(response.headers.get("Retry-After", 60))
            print(f"Rate limited. Waiting {retry_after}s...")
            time.sleep(retry_after)
            continue
        
        data = response.json()
        all_tickets.extend(data["tickets"])
        
        if data.get("end_of_stream"):
            break
        
        url = data.get("after_url")
        time.sleep(6)  # Respect 10 req/min limit
    
    return all_tickets
```

For each ticket, fetch comments separately:

```python
def get_ticket_comments(ticket_id):
    url = f"{BASE_URL}/tickets/{ticket_id}/comments.json"
    comments = []
    
    while url:
        response = requests.get(url, auth=(ZD_EMAIL, ZD_TOKEN))
        
        if response.status_code == 429:
            retry_after = int(response.headers.get("Retry-After", 60))
            time.sleep(retry_after)
            continue
        
        data = response.json()
        comments.extend(data["comments"])
        url = data.get("next_page")
    
    return comments
```

If you're handling very large datasets, stage raw JSON or NDJSON so you can replay transforms without re-pulling from Zendesk on every iteration. ([developer.zendesk.com](https://developer.zendesk.com/api-reference/ticketing/ticket-management/incremental_exports/))

### Step 4: Transform Data

Build a transformation layer that:

- Maps Zendesk statuses to Front statuses (with the original status preserved in a custom field)
- Resolves `requester_id` and `assignee_id` to email addresses
- Converts comment direction (public → imported message, private → internal comment)
- Strips Zendesk-specific HTML (satisfaction survey widgets, notification footers)
- Downloads attachments and buffers them for re-upload (Zendesk `content_url` values are authenticated and expire)
- Maps custom field IDs to Front custom field IDs
- Deduplicates any records from time-based Incremental Export pagination
- Normalizes email domains and collapses duplicate users before contact creation

### Step 5: Load Accounts and Contacts First

Create Front accounts before contacts if you want domain-based association to work cleanly. Front can automatically associate contacts to accounts based on email domain, which is cleaner than hard-coding account linkage on every contact row. ([help.front.com](https://help.front.com/en/articles/2285))

Deduplicate contacts before loading. Front identifies contacts by unique email or phone — duplicate Zendesk requesters with shared emails will collide. Users with neither email nor phone need a merge policy before load. ([help.front.com](https://help.front.com/en/articles/2211))

### Step 6: Import Conversations

Use the `imported_messages` endpoint with stable external IDs for idempotent retries:

```python
def migrate_ticket(ticket, comments, inbox_map):
    conversation_id = None

    for comment in comments:
        if comment['public']:
            payload = {
                'subject': ticket.get('subject') or f"Zendesk ticket {ticket['id']}",
                'body': render_html(comment),
                'body_format': 'html',
                'external_id': f"zd-{ticket['id']}-c-{comment['id']}",
                'created_at': to_unix(comment['created_at']),
                'metadata': {
                    'is_inbound': is_inbound(comment, ticket)
                }
            }

            if conversation_id:
                payload['conversation_id'] = conversation_id

            response = front_import_message(
                inbox_id=inbox_map[ticket['group_id']],
                payload=payload,
                files=download_attachments(comment)
            )

            conversation_id = conversation_id or response.get('conversation_id')
        else:
            if conversation_id:
                create_front_internal_comment(
                    conversation_id=conversation_id,
                    body=render_internal_note(comment)
                )

    # Apply metadata after all messages are imported
    if conversation_id:
        apply_conversation_tags(conversation_id, ticket.get('tags', []))
        apply_conversation_assignment(conversation_id, ticket.get('assignee_id'))
        apply_conversation_custom_fields(conversation_id, ticket)
```

The important parts aren't the syntax. They're the controls around it: stable `external_id` values (Front won't import duplicates, which is what makes safe replays possible), resumable checkpoints, a dead-letter queue for failed records, attachment pre-flight size checks, and strict `Retry-After` handling when Front returns 429s. ([dev.frontapp.com](https://dev.frontapp.com/reference/import-inbox-message))

### Step 7: Run a Delta Sync

During the migration window (which can take hours to days), your team keeps working in Zendesk. After the initial load completes:

1. Record the timestamp of your last extraction
2. Run the incremental export again from that timestamp
3. Import only new/updated tickets
4. Repeat until the gap is small enough for a clean cutover

The six-minute exclusion window on Zendesk exports makes a delta pass mandatory near cutover, even if you also have a bulk snapshot. ([support.zendesk.com](https://support.zendesk.com/hc/en-us/articles/4408886165402-Exporting-ticket-user-or-organization-data-from-your-account))

For the complete zero-downtime playbook, see [Zero-Downtime Helpdesk Migration](https://clonepartner.com/blog/blog/zero-downtime-helpdesk-migration/).

### Step 8: Validate

Never skip validation. At minimum:

| Check | Method | Pass Criteria |
|---|---|---|
| Total conversation count | Compare Zendesk ticket count vs. Front conversation count | 100% match (minus intentionally excluded) |
| Comment/message count (sample) | Pull 50–100 random tickets, compare comment counts | 100% match |
| Attachment presence (sample) | Download 50 random attachments from Front | Files open correctly |
| Custom field values (sample) | Compare 50 tickets across all custom fields | Values match |
| Tag counts | Compare total tagged tickets per tag | Within 1% |
| Contact-to-account linking | Spot-check 20 contacts | Correct account association |
| Assignment accuracy | Compare 50 assigned conversations | Correct teammate |

## Edge Cases That Break Migrations

These are the issues that repeatedly derail timelines across Zendesk-to-Front migrations.

### Inline Images

Zendesk stores inline images as attachments referenced by `content_url` in the comment HTML. These URLs are authenticated and **expire**. If you push this HTML directly to Front, the images appear broken. Your script must download the images during extraction, re-host them (or embed as base64), and rewrite the `src` tags in the HTML body before importing.

Many SaaS migration tools can only preserve inline images as attachments, not inline media. Decide whether that's acceptable before picking a tool. ([help-desk-migration.com](https://help-desk-migration.com/help/front-data-migration-checklist/))

### Deactivated or Deleted Agents

Zendesk retains tickets assigned to deactivated agents. When you map that agent to a Front teammate, the email may not exist in Front. **Solution:** Define a default teammate fallback. Log all tickets that fell back to default so you can manually reassign if needed.

### Merged Tickets

Zendesk allows ticket merging, which creates a comment on the target ticket referencing the merged ticket. The merged ticket becomes a closed stub. **Solution:** Import only the surviving ticket. Check for `via.source.rel: "merge"` in comments and handle accordingly.

### Side Conversations

Zendesk's side conversations (child tickets, Slack threads, email threads from the ticket sidebar) are separate API objects. They won't appear in the standard ticket comments export. **Solution:** Use the Side Conversations API endpoint separately and import them as additional messages or comments in Front.

### Attachments Over 25 MB

If a single Zendesk comment has attachments totaling more than 25 MB, the Front API rejects the import. **Solution:** Split the import — upload the text body first, then attach files individually in follow-up API calls, or host oversized files externally and link them. Decide this policy before go-live, not during the load phase. ([dev.frontapp.com](https://dev.frontapp.com/reference/import-inbox-message))

### Very Large Tickets

Zendesk allows up to 5,000 comments per ticket, and JSON exports can omit comments on tickets over 1 MB. These heavy tickets need special QA — verify comment counts explicitly. ([developer.zendesk.com](https://developer.zendesk.com/api-reference/ticketing/tickets/ticket_comments/))

### Custom Objects in Zendesk

Zendesk supports custom objects (since 2023) that can be linked to tickets via lookup relationship fields. Front has no equivalent concept. **Solution:** Flatten the custom object data into custom conversation fields or contact fields. The relational structure will be lost.

### Duplicate Contacts

Front identifies contacts by unique email or phone. If Zendesk has duplicate users sharing an email, or users with neither email nor phone, you need a merge policy before loading. Otherwise Front will create or reject records in ways that break downstream threading. ([help.front.com](https://help.front.com/en/articles/2211))

### HTML Sanitization

Zendesk comments can contain complex HTML (tables, embedded styles, satisfaction survey widgets). Front's message renderer handles standard HTML but may strip or mangle non-standard elements. Run a sanitization pass that strips Zendesk-specific elements and normalizes the rest before import.

> [!NOTE]
> **Idempotency is non-negotiable.** Use the `external_id` field on every imported message. A good pattern is `zd-{ticket_id}-c-{comment_id}`. Front rejects duplicate external IDs, preventing duplicate messages during retries. Store the Zendesk ticket ID in a conversation custom field for post-migration reconciliation.

## Limitations You Must Accept

Some things cannot be preserved in a Zendesk → Front migration:

- **Zendesk Guide articles** — Front has no native knowledge base. Migrate articles to a third-party KB (Notion, Document360, Intercom Articles) or build a custom solution.
- **Ticket metrics and SLA data** — First-reply-time, resolution-time, and SLA breach data lives in Zendesk Explore. This does not transfer. Export it separately for historical reporting.
- **Trigger and automation logic** — Zendesk triggers, automations, macros, and SLA policies must be rebuilt as Front Rules and message templates. There is no automated conversion tool. See [Your Helpdesk Migration's Secret Saboteur: Automations, Macros, and Workflows](https://clonepartner.com/blog/blog/how-to-migrate-automations-macros-workflows/).
- **Satisfaction ratings** — Zendesk CSAT survey responses are not exportable in a format Front can ingest. Archive these in your data warehouse.
- **Custom objects and lookup relationships** — Front has no equivalent. Data must be flattened or moved to an external system.
- **Front custom field limits** — 50 custom fields per category, and text fields are limited to 2,000 characters. Do not dump large JSON payloads into custom fields. ([help.front.com](https://help.front.com/en/articles/2172))
- **Archived tickets in Zendesk** — Zendesk does not include archived tickets in incremental exports. If you need these, use the Ticket Archive API or request a special export from Zendesk support.

## Validation and Testing Strategy

Migration without validation is data loss waiting to happen.

### Pre-Migration Test Run

Always run a test migration on a subset (1,000–5,000 tickets) before the full run. This catches:

- Field mapping errors
- Character encoding issues
- Rate limit math problems
- Attachment failures
- Threading logic bugs

Do not test with a toy sample. Use representative data that includes your worst-case tickets: large threads, big attachments, tickets with private notes, and tickets from deactivated agents.

### UAT Process

Before cutover, have 3–5 agents work in Front for 24–48 hours using real migrated data:

1. Search for specific historical tickets by subject or requester
2. Verify the full comment thread is intact and in chronological order
3. Confirm attachments are accessible and open correctly
4. Check that custom field values display correctly
5. Test that new Front Rules fire correctly on new conversations

### Rollback Plan

Front does not have a "delete all imported data" button. Your rollback options:

- **Keep Zendesk active** until you've validated Front. Don't cancel your Zendesk contract until you're confident.
- **Tag all imported conversations** with a migration-specific tag (e.g., `migrated_from_zendesk`) so you can identify and bulk-archive if needed.
- **Document the point of no return** — typically when agents start replying from Front, as those replies won't exist in Zendesk.

For a structured post-migration QA process, see [Post-Migration QA: 20 Tests to Run](https://clonepartner.com/blog/blog/helpdesk-migration-qa-checklist/).

## Post-Migration Tasks

Once data lands in Front, you're halfway done. The other half is operational readiness.

### Rebuild Automations

- **Triggers → Front Rules:** Recreate routing logic. Front's branching rules are powerful but structurally different from Zendesk's trigger/automation split.
- **Macros → Message Templates:** Recreate canned responses. Front's template syntax differs from Zendesk's placeholder syntax (`{{ticket.requester.name}}` becomes dynamic variables via Front's template engine).
- **SLAs:** Recreate SLA policies in Front's SLA settings. Front's SLA engine is simpler — it supports response and resolution targets but not Zendesk's multi-policy, priority-based SLA stacking.

### Agent Training

Front's UX differs enough from Zendesk that agents need hands-on time:

- How shared inboxes differ from Zendesk groups
- How to use comments (internal notes) vs. replies
- How Front's assignment model works (no "take it" queue — conversations are assigned or unassigned)
- How to use tags and custom fields for workflows that previously relied on Zendesk custom statuses or ticket forms

### Post-Cutover Monitoring

For the first 2 weeks:

- Monitor Front's API usage dashboard for rate limit issues from integrations
- Watch for conversations with missing data (search for conversations without expected tags or custom fields)
- Track agent-reported issues in a dedicated Slack channel or Front inbox
- Compare daily conversation volume between Front and Zendesk (if still active)
- Watch for duplicate contacts created by live traffic racing against import jobs
- Review account and contact auto-association by domain for correctness

## Best Practices

1. **Back up everything first.** Run a full JSON export from Zendesk before starting. Store it somewhere immutable.
2. **Run test migrations early.** Don't wait until the week before cutover to discover field mapping is wrong.
3. **Disable Front rules during import.** Imported messages can trigger auto-replies, assignments, and tagging rules.
4. **Pre-create all Front entities.** Inboxes, teammates, tags, custom fields — all must exist before the first message is imported.
5. **Log everything.** Every API call, every error, every skipped record. You'll need this for validation.
6. **Plan for the delta.** Your team will keep working in Zendesk during migration. Plan at least one (ideally two) delta sync passes.
7. **Don't cancel Zendesk immediately.** Keep it active for at least 2 weeks post-migration as a safety net.
8. **Store original Zendesk IDs.** Preserve ticket IDs in conversation custom fields and comment IDs in message external IDs. This makes reconciliation and debugging possible.
9. **Decide attachment policy early.** If Zendesk tickets have attachments above Front's 25 MB limit, decide whether to skip, host externally, or archive separately — before the load phase starts.
10. **Use Zapier and Make for post-cutover automation, not for replaying history.** iPaaS tools are built for workflows, not bulk backfill.

## When a Managed Migration Service Makes Sense

Build in-house when you have:
- A dedicated engineer who can commit 2–4 weeks
- Fewer than 20K tickets with simple custom fields
- An existing ETL framework you can extend
- No hard deadline

Use a managed service when:
- You have >20K tickets or complex custom field mappings
- Your team can't spare engineering cycles
- You need the migration completed in days, not weeks
- You can't afford silent data loss on custom fields, inline images, or attachments
- You need a delta sync for zero-downtime cutover
- Support can't stop during the transition

The case against building in-house usually isn't lack of talent. It's that migrations are bursty, edge-case heavy, and unforgiving. Your team has to solve extraction throttling, write-path throttling, comment-level replay, attachment handling, deduplication, cutover timing, UAT, and rollback — then throw most of that code away. The hidden costs are usually human: after-hours cutover supervision, agent confusion during re-runs, QA time from support leads, and cleanup work when mismapped records land in Front.

Front's own Zendesk importer documentation names **ClonePartner** as a recommended migration partner before it describes the built-in importer. ([help.front.com](https://help.front.com/t/k9cd67/how-to-import-your-zendesk-history-into-front))

ClonePartner has completed this exact migration path — [700K tickets spanning 12 years of history, migrated to Front without downtime or data loss](https://clonepartner.com/blog/blog/zendesk-to-front-iin/). Our tooling handles Zendesk's 10 req/min export throttle and Front's per-company rate limits in parallel, preserving every custom field, tag, inline image, and attachment that native importers and SaaS tools explicitly drop. The migration runs in the background while your support team continues working in Zendesk, with a final delta sync right before cutover.

That said: if you have a few thousand tickets with no custom fields and a flexible timeline, you probably don't need us. Front's built-in importer or a SaaS tool will get the job done. We're here for the migrations where data fidelity and speed actually matter.

> Planning a Zendesk to Front migration? Our engineers have moved 700K+ tickets to Front without downtime or data loss. Book a 30-minute call to scope your migration and get a timeline.
>
> [Talk to us](https://cal.com/clonepartner/meet?duration=30&utm_source=blog&utm_medium=button&utm_campaign=demo_bookings&utm_content=cta_click&utm_term=demo_button_click)

## Frequently asked questions

### Can I migrate Zendesk tickets to Front using CSV files?

No, not for full history. Zendesk CSV exports exclude ticket comments, descriptions, multi-line text fields, deleted tickets, and attachments. Front's CSV imports are for contacts and accounts only, not conversation history. You need the Incremental Export API for the actual ticket data.

### Does Front have a native Zendesk importer?

Yes. As of Front's help article edited December 2, 2025, the importer has no hard ticket limit, but Front states it is 'not actively maintained' and recommends migration partners instead. It does not import custom fields, tags, or rules, and edge case handling is limited.

### How long does a Zendesk to Front migration take?

It depends on volume and Front plan. On a Growth plan (100 API requests/min), expect roughly 10–12 complete tickets per minute import throughput. A 50K-ticket account can take 60–80 hours of continuous import. Temporary rate limit increases from Front or a managed service can cut this significantly.

### What data cannot be migrated from Zendesk to Front?

Zendesk Guide articles (Front has no native KB), SLA metrics, trigger/automation logic, CSAT survey responses, and custom object relationships cannot be directly migrated. These must be rebuilt, archived separately, or moved to third-party tools.

### What is the biggest API bottleneck in a Zendesk to Front migration?

Both sides are constrained. Zendesk's Incremental Export API is capped at 10 requests per minute. Front's write limits are 50–500 requests per minute depending on plan, enforced per-company across all integrations and scripts. Your migration script competes with live workflows for Front's quota.
