---
title: "Zendesk to Gladly Migration: The Complete Technical Guide"
slug: zendesk-to-gladly-migration-the-complete-technical-guide
date: 2026-07-14
author: Roopi
categories: [Migration Guide, Gladly, Zendesk]
excerpt: "How to migrate from Zendesk to Gladly: object mapping, API rate limits, step-by-step process, edge cases, and realistic timelines. By engineers who've done it."
tldr: "Zendesk to Gladly is a high-complexity schema translation — tickets become conversation items on person-centric timelines. 2–4 week timeline. Biggest risk: attachments and CSAT cannot be imported."
canonical: https://clonepartner.com/blog/zendesk-to-gladly-migration-the-complete-technical-guide/
---

# Zendesk to Gladly Migration: The Complete Technical Guide


# Zendesk to Gladly Migration: The Complete Technical Guide

> [!NOTE]
> **TL;DR — Zendesk to Gladly Migration**
>
> Migrating from Zendesk to Gladly is a **high-complexity data-model translation**, not a simple field-mapping exercise. Zendesk's ticket-centric architecture must be restructured into Gladly's person-centric timeline, where discrete tickets become conversation items on a lifelong customer record. Realistic timeline: **2–4 weeks** end to end for a mid-size instance (20,000–100,000 tickets). The single biggest risk is **silent data loss** — Gladly's historical import is text-based only and does not support attachments, images, recordings, metrics, or routing assignments. ([help.gladly.com](https://help.gladly.com/implementation/docs/historical-conversation-item-data-import/)) Zendesk Macros, Triggers, Automations, and SLAs cannot be migrated programmatically and must be rebuilt manually in Gladly. Teams with fewer than 10,000 tickets and no attachment-heavy threads can work through Gladly's native JSON import with their implementation team. Anything above that — or with complex custom fields, duplicate requesters, and zero-downtime requirements — should use a managed migration service.

## What Is a Zendesk to Gladly Migration?

A Zendesk to Gladly migration is the process of extracting tickets, users, organizations, comments, tags, custom fields, and knowledge base articles from Zendesk Support and loading them into Gladly as conversations, conversation items, customers, teams, topics, inboxes, and answers — while translating Zendesk's ticket-centric data model into Gladly's person-centric timeline.

This is not a like-for-like transfer. It is a **schema translation** that fundamentally changes how customer history is organized. Gladly does not use ticket numbers, allows only one open Conversation per customer at a time, and treats the timeline as a customer view rather than a reportable unit. ([help.gladly.com](https://help.gladly.com/docs/what-is-a-conversation?utm_source=openai))

### Why Teams Move from Zendesk to Gladly

Teams make this switch for three platform-specific architectural reasons:

- **Person-centric architecture.** Gladly organizes all interactions around a single customer profile — every email, chat, SMS, and phone call lives on one continuous timeline. Zendesk treats each interaction as a separate ticket. For brands with high repeat-contact rates (e-commerce, DTC, hospitality), this eliminates repeated context-gathering across tickets. For a deeper overview of Gladly's architecture, see our [Gladly platform guide](https://clonepartner.com/blog/blog/ultimate-guide-gladly-2026/).
- **Channel-native design.** Gladly treats every channel (voice, email, chat, SMS, social) as a first-class citizen within a single conversation thread. Zendesk requires separate channel configurations and creates distinct tickets per channel, which fragments context across ticket records.
- **Simplified pricing model.** Gladly charges per agent (Hero) with unlimited conversations. Zendesk's usage-based add-ons for AI, advanced analytics, and the High Volume API can inflate costs at scale — particularly for high-volume support teams exceeding 100,000 tickets/month.

### The 2 Architectural Differences That Make This Migration Non-Trivial

1. **Tickets vs. Lifelong Conversations.** A Zendesk Ticket is a discrete, numbered record with a lifecycle (New → Open → Pending → Solved → Closed). A Gladly Conversation is a period of related interactions on a customer's timeline — it has no ticket number. Multiple Zendesk tickets from the same requester must be collapsed into conversation items on a single Gladly customer profile. The mapping is many-to-one, not one-to-one.

2. **Organization-centric vs. Person-centric.** Zendesk groups end-users under Organizations, and tickets belong to requesters. Gladly has no Organization object — everything hangs off the Customer profile. If you rely on Zendesk Organizations for routing, reporting, or access control, you need to rethink that logic using Gladly's custom attributes or external Lookup Adapters to pull org data from your CRM.

## How Does Zendesk Data Map to Gladly?

The object mapping table below covers every core Zendesk object and its Gladly equivalent. Lead with this when scoping your migration.

| Zendesk Object | Gladly Object | Notes / Caveats |
|---|---|---|
| Ticket | Conversation + Conversation Items | Each ticket becomes a conversation; each comment becomes a conversation item on the customer's timeline. Ticket numbers are not preserved. |
| Ticket Comment (public) | Conversation Item (email/chat/SMS) | Mapped as timeline events. Original timestamps preserved via historical import using `occurredAt` field. |
| Ticket Comment (internal note) | Conversation Item (note) | Internal notes import as note-type items on the timeline. |
| User (end-user / requester) | Customer | Email is the unique identifier. Duplicate emails across Zendesk users will cause `409 Conflict` responses in Gladly. |
| User (agent) | Agent | Agent profiles must be created in Gladly before import. Gladly uses email-based matching. |
| Organization | No direct equivalent | Gladly has no Organization object. Map to custom attributes on the Customer profile or use Gladly's Lookup Adapters to pull org data from your CRM at query time. |
| Group | Team | Zendesk Groups map to Gladly Teams. Team membership must be configured manually or via API. |
| Tags | Topics + Freeform Topics | Zendesk tags map to Gladly Topics (predefined) or freeform topics. Topics must be created before import; the API rejects payloads referencing nonexistent Topics. |
| Custom Fields (ticket) | Conversation Custom Attributes | Must be configured by Gladly Professional Services before they display in the UI. |
| Custom Fields (user) | Customer Custom Attributes | Same constraint — must be pre-configured in Gladly. |
| Macros | Answers (partial) | No programmatic migration path. Must be rebuilt manually in Gladly as Answers or Rules. |
| Triggers / Automations | Rules | No migration path. Gladly Rules use a different logic model and do not act on closed conversations. Rebuild from scratch. |
| SLAs | No direct equivalent | Gladly does not have a native SLA engine comparable to Zendesk's. Monitor via reporting and Rules-based escalation. |
| Views | Inboxes (partial) | Zendesk Views are filter-based lists. Gladly Inboxes are routing containers. Different paradigm — requires redesign. |
| Help Center Articles | Answers | Can be migrated via Gladly's Answers API. Formatting differences (Zendesk uses Markdown/HTML; Gladly Answers have their own structure) require manual review. |
| Attachments | **Not imported via historical path** | Gladly's historical import is text-based only. Attachments, images, and recordings are not supported. ([help.gladly.com](https://help.gladly.com/implementation/docs/historical-conversation-item-data-import/)) |
| Satisfaction Ratings (CSAT) | **Not imported** | No historical CSAT import into Gladly. Export and archive separately from Zendesk Explore. |

> [!WARNING]
> **What has no clean equivalent in Gladly:** Zendesk Organizations, SLA Policies, Side Conversations, Ticket Forms, Ticket Statuses (beyond Open/Closed), Light Agents, CSAT history, merged ticket cross-links, and Zendesk Talk call recordings have no direct Gladly counterpart. Plan for these gaps before migration, not during.

### Field-Level Mapping Constraints

- **Picklists / Dropdowns:** Zendesk dropdown custom fields must be recreated as Gladly custom attributes with matching option values. Gladly does not enforce enum validation on custom attributes — values are stored as strings. This means typos or mismatched option values will not throw errors but will produce inconsistent data.
- **Multi-select fields:** Gladly does not natively support multi-select custom attributes. Flatten to comma-separated strings or split into multiple boolean attributes.
- **Dates:** Zendesk stores timestamps in UTC ISO 8601. Gladly's historical import expects `createdAt` / `occurredAt` in ISO 8601 format. No timezone conversion needed, but you must explicitly pass original creation timestamps to prevent the system from stamping all imported history with the current date.
- **Rich text / HTML:** Gladly conversation item bodies accept plain text through the historical import path. HTML from Zendesk ticket comments will need to be stripped or converted. Use a library like `html2text` (Python) or `turndown` (JavaScript) for consistent conversion.
- **Character limits:** In Gladly's CSV-based historical import, `title` is capped at **100 characters** and `body` is capped at **25,000 characters**. Zendesk ticket descriptions with long HTML content will be truncated silently. ([help.gladly.com](https://help.gladly.com/implementation/docs/historical-conversation-item-data-import/))
- **Customer-level fields:** In the CSV import, starred customer-level fields such as `customAttribute`, `note`, and `address` only apply on the first occurrence of each email. Sort your rows by `customer_email` and time so the first row for each customer carries any one-time profile attributes. ([help.gladly.com](https://help.gladly.com/implementation/docs/historical-conversation-item-data-import/))
- **Phone numbers:** Gladly requires E.164 format for phone numbers (e.g., `+14155551234`). Zendesk stores phone numbers in freeform text. Your transformation layer must normalize all phone numbers or omit malformed values.

For reusable field mapping worksheets, see our [data mapping guide](https://clonepartner.com/blog/blog/your-ultimate-guide-to-data-mapping-for-a-flawless-help-desk-data-migration-with-csv-templates/).

## What Are the API Rate Limits for This Migration?

**[For engineering]** Rate limits are the primary throughput bottleneck. Both platforms impose hard caps that directly determine how long your migration takes.

### Zendesk Extraction Limits

| API Endpoint | Rate Limit | Notes |
|---|---|---|
| Incremental Export (cursor-based, tickets) | 10 requests/minute | 30 req/min with High Volume API add-on. Each request returns up to 1,000 tickets. |
| Incremental Export (cursor-based, users) | 20 requests/minute | 60 req/min with High Volume add-on. |
| Incremental Export (time-based) | 10 requests/minute | Used for ticket events and organizations. |
| Support API (general) | 200–2,500 req/minute | Depends on plan tier (Team: 200, Growth: 400, Professional: 700, Enterprise: 2,500). |
| Ticket Comments API | Account-wide limit | Returns up to 100 comments per request per ticket. Paginated via `next_page`. |

Use the cursor-based Incremental Export API (`GET /api/v2/incremental/tickets/cursor`) for extraction. At 10 requests per minute with 1,000 tickets per response, you can extract roughly **10,000 tickets per minute** under ideal conditions — but each ticket then requires separate calls for comments and attachments, which consumes your account-wide API budget. ([developer.zendesk.com](https://developer.zendesk.com/api-reference/ticketing/ticket-management/incremental_exports/?utm_source=openai))

For messaging tickets where you need reliable comment-author attribution, Zendesk recommends using the ticket audits endpoint (`GET /api/v2/tickets/{id}/audits`) after you identify the relevant ticket IDs. If you need a fallback full dump, Zendesk's full JSON export uses NDJSON, is not available on Team plans, and accounts with more than 1 million tickets are broken into 31-day increments.

For a detailed guide on Zendesk data extraction, see [How to Export Tickets from Zendesk](https://clonepartner.com/blog/blog/how-to-export-tickets-from-zendesk/).

### Gladly Ingestion Limits

| API Method | Rate Limit | Notes |
|---|---|---|
| GET / POST / PUT / PATCH / DELETE | 10 requests/second | Hard cap across all methods. Returns `429 Too Many Requests` when exceeded. |
| Reporting API | 10 requests/minute | Max 2 concurrent requests across the org |
| Customer search | Max 50 profiles per response | Not paginated beyond 50 results |
| List conversations (per customer) | Max 100 conversations returned | Not paginated. `Gladly-Limited-Data` header indicates truncation. |
| List conversation items | Max 1,000 items per conversation | Not paginated. Same truncation header applies. |

Gladly's API enforces a hard cap of **10 requests per second** across all methods. Exceed it and Gladly returns a `429 Too Many Requests` error. Your ingestion script must include exponential backoff with jitter and retry logic. Gladly exposes rate-limit headers (`Ratelimit-Limit-Second`, `Ratelimit-Remaining-Second`) that your script should monitor and use to throttle proactively rather than reactively. ([developer.gladly.com](https://developer.gladly.com/rest/))

In practice, creating a customer profile and adding multiple conversation items requires 2–5+ API calls per customer:
1. `POST /api/v1/customer-profiles` — create the customer
2. `POST /api/v1/customer-profiles/{id}/emails` — add email addresses
3. `POST /api/v1/customer-profiles/{id}/phones` — add phone numbers (if applicable)
4. `POST /api/v1/conversations` — create the conversation
5. `POST /api/v1/conversations/{id}/items` — add each conversation item

At 10 requests per second, effective throughput drops to approximately **150–300 customer records per minute**.

> [!TIP]
> **Throughput math:** For 50,000 Zendesk tickets mapping to 20,000 unique customers with an average of 2.5 tickets each, expect the Gladly ingestion phase alone to take **2–5 hours** when accounting for rate-limit backoff and retry logic. Plan overnight migration windows. Gladly's production reporting data also has about a one-hour latency, so do not rely on reports as a same-hour go-live validation source. ([help.gladly.com](https://help.gladly.com/docs/why-is-my-reporting-data-not-current/?utm_source=openai))

## How Should You Approach This Migration? DIY vs. Native Import vs. Managed Service

For most teams, the safest plan is **split-path**: import legacy history through Gladly's historical import process and move live work through a separate cutover path. A pure REST API rewrite is rarely the best primary method because Gladly's public create-item API writes non-routable customer activities that sit outside conversations. ([help.gladly.com](https://help.gladly.com/implementation/docs/historical-conversation-item-data-import/))

### Approach 1: Gladly's Native Historical Import

**How it works:** Export your Zendesk data as JSON via Zendesk's full data export. Transform it into Gladly's required CSV or JSON format with columns for `customer_email`, `customer_name`, `title`, `body`, `occurredAt`, `activityType`, and `sourceName`. Upload the file to a Gladly-provided Dropbox link. Gladly's implementation team processes the import.

**When to use it:** You're a new Gladly customer going through onboarding, and your dataset is relatively clean and under 500K conversation items.

| Pros | Cons |
|---|---|
| Handled by Gladly's Professional Services team | Text-based only — no attachments, images, or recordings |
| Zendesk is a natively supported source format | Imported items are not searchable or reportable in Gladly |
| Recommended batch sizes: 500K rows | Requires a Professional Services fee (included in some contracts, separate in others) |
| Timestamps preserved via `occurredAt` field | No control over mapping logic or error handling |
| | Subject truncated at 100 chars; body at 25K chars |
| | Imported items do not feed Gladly Sidekick or AI suggestion features |

**Complexity:** Low (for you) · **Scalability:** Medium · **Risk:** Medium — limited visibility into failures

### Approach 2: Custom API-Based Migration (DIY)

**How it works:** Write scripts to extract via Zendesk's REST/Incremental APIs, transform the data model, and load via Gladly's REST API.

**When to use it:** You have dedicated engineering capacity, need full control over field mapping and transformation logic, and can tolerate a 2–4 week build + test cycle.

| Pros | Cons |
|---|---|
| Full control over mapping and transformation | Must handle rate limiting on both sides (10 req/min Zendesk export, 10 req/sec Gladly) |
| Can run delta syncs for cutover | Significant engineering time: 120–200 hours including testing |
| Iterative testing possible against Gladly sandbox | 429 error handling, retry logic, and idempotency are your problem |
| Can handle conditional logic (e.g., skip spam, merge aliases) | Must manage customer deduplication manually |
| | Gladly sandbox environments must be provisioned by Gladly during onboarding |

**Complexity:** High · **Scalability:** High · **Risk:** High without prior migration experience. The hidden cost is not the build — it's the re-migration when a deduplication bug at 2 AM creates hundreds of duplicate customer profiles that must be individually merged via the Gladly UI or support ticket.

### Approach 3: Managed Migration Service

**How it works:** A migration team builds custom extraction, transformation, and load scripts tailored to your specific Zendesk configuration and Gladly setup. The service handles rate-limit orchestration, deduplication, validation, and cutover.

**When to use it:** You have 50,000+ tickets, complex custom fields, attachment archival requirements, or cannot afford downtime.

| Pros | Cons |
|---|---|
| Zero engineering time from your team | Service cost (typically $5,000–$25,000 depending on volume and complexity) |
| Rate-limit orchestration handled for you | Less direct control over timing |
| Validation and reconciliation included | Vendor dependency during migration window |
| Zero-downtime cutover with delta sync | |
| Attachment archival and linking handled | |

**Complexity:** Low (for you) · **Scalability:** Enterprise · **Risk:** Low

For a deeper comparison of migration tools and services, see our [help desk migration solutions guide](https://clonepartner.com/blog/blog/top-5-help-desk-data-migration-solutions/).

### Cost Comparison

| Approach | Cost Range | Primary Cost Driver |
|---|---|---|
| Gladly Native Import | Included or $2,000–$10,000 PS fee | Negotiate during contract; varies by account size |
| DIY API Migration | $15,000–$40,000 (120–200 engineering hours) | Developer time + opportunity cost of pulling engineers off product work |
| Managed Migration Service | $5,000–$25,000 | Volume, complexity, and attachment archival requirements |

## What Is the Step-by-Step Migration Process?

The order of operations matters. Loading conversation items before their parent customer profiles exist will orphan records. Here is the correct sequence:

### Step 1: Extract Data from Zendesk

Use the Incremental Export API with cursor-based pagination for tickets, users, and organizations. Use the Ticket Comments API to pull full thread history per ticket. For bulk comment history, the Incremental Ticket Event Export with `comment_events` is more efficient than per-ticket comment pulls.

```python
import requests
import time

ZD_SUBDOMAIN = "yourcompany"
ZD_AUTH = ("[email protected]/token", "your_api_token")

def extract_tickets(start_time=0):
    url = f"https://{ZD_SUBDOMAIN}.zendesk.com/api/v2/incremental/tickets/cursor"
    params = {"start_time": start_time}
    all_tickets = []
    
    while True:
        resp = requests.get(url, params=params, auth=ZD_AUTH)
        if resp.status_code == 429:
            wait = int(resp.headers.get("Retry-After", 60))
            time.sleep(wait)
            continue
        resp.raise_for_status()
        data = resp.json()
        all_tickets.extend(data["tickets"])
        if data.get("end_of_stream"):
            break
        params = {"cursor": data["after_cursor"]}
        url = f"https://{ZD_SUBDOMAIN}.zendesk.com/api/v2/incremental/tickets/cursor"
        time.sleep(6)  # Respect 10 req/min limit
    
    return all_tickets

def extract_comments(ticket_id):
    url = f"https://{ZD_SUBDOMAIN}.zendesk.com/api/v2/tickets/{ticket_id}/comments"
    comments = []
    while url:
        resp = requests.get(url, auth=ZD_AUTH)
        if resp.status_code == 429:
            wait = int(resp.headers.get("Retry-After", 60))
            time.sleep(wait)
            continue
        resp.raise_for_status()
        data = resp.json()
        comments.extend(data["comments"])
        url = data.get("next_page")
    return comments
```

### Step 2: Clean and Deduplicate

- Merge duplicate Zendesk requesters by email address. Gladly uses email as a unique identifier — attempting to create two customers with the same email will return a `409 Conflict`.
- Strip HTML from comment bodies if targeting Gladly's CSV import path. Preserve HTML if loading via API and your Gladly contract supports rich content.
- Remove or archive tickets with no valid requester email. Gladly will reject any import row without a well-formatted email address.
- Audit your Zendesk user base before extraction — run `GET /api/v2/search?query=type:user role:end-user email:""` to identify email-less users (common in voice, messaging, and older data).
- Normalize phone numbers to E.164 format (`+{country_code}{number}`). Malformed phone numbers will cause Gladly API errors.
- Filter out suspended tickets (spam). Do not migrate them — they consume API quota and clutter customer timelines.

> [!WARNING]
> **If you skip canonical email design, you will split the same human into multiple Gladly profiles.** Gladly's historical import groups all activity by email, and records without a valid email are silently rejected. Multi-brand or multi-channel Zendesk instances are especially vulnerable — the same customer may exist as `[email protected]` in one brand and `[email protected]` in another. Build an email canonicalization map before import. ([help.gladly.com](https://help.gladly.com/implementation/docs/historical-conversation-item-data-import/))

### Step 3: Transform the Data Model

This is the critical step. You must reshape Zendesk's flat ticket structure into Gladly's nested customer → conversation → conversation item hierarchy.

```
Zendesk:                          Gladly:
┌─────────────┐                   ┌─────────────────────┐
│  Ticket #1  │──┐                │     Customer        │
│  Ticket #2  │──┼──▶ Transform ──▶│  ├─ Conversation A  │
│  Ticket #3  │──┘                │  │  ├─ Item 1       │
└─────────────┘                   │  │  ├─ Item 2       │
  (3 separate records             │  ├─ Conversation B  │
   for same requester)            │  │  ├─ Item 1       │
                                  └─────────────────────┘
                                    (1 customer profile,
                                     tickets become
                                     conversation items)
```

Group all tickets by requester email. Each ticket becomes a conversation; each comment becomes a conversation item within that conversation. For the documented Zendesk import path, map each ticket comment to one historical item using comment `created_at`, ticket `subject`, tags plus `html_body`, and requester identity.

```python
import html2text
import re

h = html2text.HTML2Text()
h.ignore_links = False

def truncate(text, max_len):
    if text and len(text) > max_len:
        return text[:max_len - 3] + "..."
    return text or ""

def canonical_email(user):
    email = (user.get("email") or "").strip().lower()
    # Handle common alias patterns
    email = re.sub(r'\+.*@', '@', email)
    return email

def e164_or_blank(phone):
    if not phone:
        return ""
    digits = re.sub(r'[^\d+]', '', phone)
    if digits.startswith('+') and len(digits) >= 10:
        return digits
    return ""

def transform_to_gladly_row(ticket, comment, requester):
    email = canonical_email(requester)
    if not email:
        return None  # Log and skip
    
    tags_text = ", ".join(ticket.get("tags", []))
    body_text = h.handle(comment.get("html_body", comment.get("body", "")))
    
    return {
        'customer_email': email,
        'customer_name': requester.get('name', ''),
        'customer_phone': e164_or_blank(requester.get('phone')),
        'title': truncate(
            ticket.get('subject') or f"Zendesk ticket {ticket['id']}", 100
        ),
        'body': truncate(
            f"Tags: {tags_text}\n\n{body_text}" if tags_text else body_text,
            25000
        ),
        'activityType': 'CUSTOMER_ACTIVITY',
        'occurredAt': comment['created_at'],
        'sourceName': 'Zendesk',
    }
```

This transform pattern mirrors Gladly's documented Zendesk field mapping and its CSV constraints. Log every rejected row — especially missing-email rows, long-body truncations, and alias merges. ([help.gladly.com](https://help.gladly.com/implementation/docs/historical-conversation-item-data-import/))

### Step 4: Load in the Correct Order

1. **Agents first** — Create agent profiles in Gladly (or confirm they exist). Agent IDs are referenced in conversation items.
2. **Teams and Inboxes** — Configure Gladly Teams (mapped from Zendesk Groups) and Inboxes. Gladly Inboxes are routing containers, not filter-based views — redesign your Zendesk Views as Inboxes based on routing logic, not display logic.
3. **Topics** — Create all Topics in Gladly that correspond to your Zendesk Tags. If a Zendesk tag does not exist as a Gladly Topic, the Gladly API will reject the payload with a validation error.
4. **Answers and Rules** — Rebuild Zendesk Macros as Gladly Answers and Triggers as Gladly Rules before cutover so active work has a destination. Do not auto-port Zendesk automations blindly — Gladly Rules do not act on closed conversations and use a different condition/action model.
5. **Customers** — Create customer profiles via `POST /api/v1/customer-profiles`. Email, name, and phone are mapped from Zendesk user records. Then add contact points via `POST /api/v1/customer-profiles/{id}/emails` and `/phones`.
6. **Conversations and Items** — Add conversation items to customer timelines. Use the historical import (CSV/JSON via Gladly PS) for legacy data, or the conversation/item creation endpoints for API-based loading: `POST /api/v1/conversations` followed by `POST /api/v1/conversations/{id}/items`.

> [!CAUTION]
> **Order-of-operations failure mode:** If you load conversation items before the customer profile exists, items created via the timeline API will generate a new customer profile automatically — but without the full profile data (name, phone, custom attributes). This creates duplicate, incomplete customer records that must be manually merged via the Gladly UI or by contacting Gladly support. There is no bulk merge API.

### Step 5: Migrate Integrations

Zendesk integrations do not carry over to Gladly. Common integrations that must be re-wired:

| Integration | Zendesk Implementation | Gladly Equivalent |
|---|---|---|
| Shopify | Zendesk Shopify app (sidebar) | Gladly native Shopify integration (built-in) |
| Salesforce | Zendesk Salesforce sync | Gladly Lookup Adapter + Salesforce connector |
| Jira | Zendesk Jira app | Gladly API webhook or third-party connector (Workato, Tray.io) |
| Slack | Zendesk Slack integration | Gladly Slack integration or webhook-based notifications |
| Custom apps (Zendesk Apps Framework) | ZAF sidebar apps | Gladly Sidekick SDK or Lookup Adapters |

Budget 1–3 days per integration for re-wiring and testing. For Shopify-heavy e-commerce teams, Gladly's native Shopify integration is typically simpler than Zendesk's app-based approach, but the data mapping (order lookup, refund actions) must be validated in the sandbox.

### Step 6: Validate

See the Validation section below.

### Step 7: Go-Live with Delta Sync

Run the production migration while Zendesk is still live. Perform a delta sync to capture tickets created or updated during the migration window. Switch live traffic to Gladly and keep Zendesk in read-only mode for 1–2 weeks as a rollback option and attachment lookup archive.

Gladly's own import guidance recommends running history imports in batches of 500K rows about two weeks before launch, with a final delta pass two days before go-live. ([help.gladly.com](https://help.gladly.com/implementation/docs/historical-conversation-item-data-import/))

If your inbound email address is visibly tied to Zendesk, set customer-facing auto-replies in the old system before cutover so customers know where to send new messages. Update DNS MX records and any forwarding rules to route to Gladly's email endpoints. ([help.gladly.com](https://help.gladly.com/implementation/docs/prepare-for-launch?utm_source=openai))

### Rollback Procedure

If critical issues are discovered post-cutover:

1. **Re-route inbound email** back to Zendesk by reverting DNS/forwarding changes (MX record TTL should be set low — 300 seconds — before cutover to enable fast rollback).
2. **Re-enable Zendesk chat/messaging** widgets on your site by swapping the JavaScript snippet.
3. **Zendesk phone routing** can be restored by updating your IVR/telephony provider to point back to Zendesk Talk.
4. **Records created in Gladly during the interim** remain in Gladly but are not automatically synced back to Zendesk. Export any Gladly-created tickets via the Gladly API and import them into Zendesk if needed for continuity.
5. Keep Zendesk licenses active for at least 30 days post-cutover to preserve rollback capability.

## How Long Does a Zendesk to Gladly Migration Take?

**[For PMs]** A typical Zendesk to Gladly migration takes **2–4 weeks** from kickoff to go-live. The calendar is driven less by export speed than by identity cleanup, sample QA, workflow rebuild, and integration re-wiring.

| Phase | Duration | Key Activities |
|---|---|---|
| Discovery & Scoping | 2–3 days | Audit Zendesk instance: ticket volume, custom fields, automations, integrations. Define what to migrate vs. archive. |
| Data Mapping & Transformation Design | 3–5 days | Build object/field mapping. Design transformation rules. Handle edge cases (orgs, multi-select fields, attachments). |
| Gladly Configuration | 2–3 days | Set up Teams, Inboxes, Topics, custom attributes, Answers, Rules. Provision sandbox environment with Gladly PS. |
| Integration Re-wiring | 2–5 days | Reconnect Shopify, Salesforce, Jira, Slack, and custom apps to Gladly equivalents. Test in sandbox. |
| Script Development & Testing | 3–5 days | Build extraction, transformation, and load scripts. Test against Gladly sandbox. |
| Test Migration (dry run) | 1–2 days | Run full migration against staging. Validate record counts, spot-check 50–100 records. |
| UAT & Fixes | 2–3 days | Support team validates in Gladly. Fix mapping errors, adjust transformations. |
| Production Migration & Delta Sync | 1–2 days | Run production load. Delta sync covers tickets created during test/UAT window. |
| Go-Live & Hypercare | 1–3 days | Switch live traffic to Gladly. Monitor for issues. Parallel-run Zendesk in read-only. |

**Total: 16–29 business days.** This compresses to 10–14 days with a dedicated migration team and a clean Zendesk instance. Instances under 10,000 tickets with simple configurations and no integration re-wiring can complete in 7–10 business days. Enterprise instances with 500,000+ tickets, multiple brands, and complex automations may take 4–6 weeks.

### Risk Register

| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Duplicate customers from email conflicts | High | High | Deduplicate Zendesk users by email before load. Build canonical email map. Merge logic in transformation layer. |
| Attachment loss | High | Medium | Archive attachments to S3/GCS. Link URLs in Gladly conversation notes. Keep Zendesk read-only for lookup. |
| Missing requester email (voice, messaging, old data) | High | Medium | Pre-classify unimportable records. Keep a read-only Zendesk archive for reference. Log rejection counts. |
| Rate-limit stalls (429 errors) | Medium | Low | Exponential backoff with jitter. Monitor `Ratelimit-Remaining-Second` headers. Pre-calculate migration window. |
| Broken automation workflows | Medium | High | Rebuild Zendesk Triggers/Macros as Gladly Rules before go-live. Test with sandbox tickets. Prioritize top-10 most-fired automations. |
| Integration gaps | Medium | High | Audit all Zendesk apps and integrations during discovery. Map each to Gladly equivalent or workaround. |
| Incomplete customer profiles | Low | Medium | Validate customer record counts post-load. Spot-check 5% sample. |
| Multi-brand identity fragmentation | Medium | High | Build cross-brand email canonicalization before import. Test with known multi-brand customers. |

For a comprehensive approach to zero-downtime migrations, see our [zero-downtime migration guide](https://clonepartner.com/blog/blog/zero-downtime-help-desk-data-migration/).

## What Do Customers and Agents Notice During Migration?

**[For customer success]** Done correctly, customers notice nothing. Here is what to plan for:

- **Conversation history:** Historical tickets appear as conversation items on the customer's Gladly timeline. Agents see the full history when a returning customer contacts support. However, imported items are **not searchable** in Gladly — agents can see them on the customer timeline but cannot full-text search across imported history. ([help.gladly.com](https://help.gladly.com/implementation/docs/historical-conversation-item-data-import/))
- **AI features:** Imported historical items do not feed Gladly Sidekick (Gladly's AI assistant) or AI-powered answer suggestions. Sidekick operates on native Gladly data and configured Answers — not on imported conversation history. Plan for a ramp-up period where AI suggestions improve as new native data accumulates.
- **Ticket numbers are gone.** Gladly does not use ticket numbers. Imported historical data behaves more like reference context on the customer profile than live reportable work. Leaders should not expect legacy Zendesk data to show up in native Gladly analytics.
- **Attachments:** If your Zendesk tickets contain screenshots, PDFs, or recordings, these will **not** appear in Gladly's imported timeline. Brief your agents on where to find archived attachments (e.g., a shared drive, S3 bucket, or read-only Zendesk instance linked in a pinned note).
- **Voice history:** Zendesk Talk call recordings cannot be imported. Call metadata (duration, disposition) can be embedded in conversation item text during transformation, but playback is not available. Archive recordings separately if needed for compliance.
- **SLAs:** Zendesk SLA metrics are not carried over. Reset SLA tracking on go-live. Communicate to stakeholders that historical SLA data lives in Zendesk Explore exports, not in Gladly.
- **Downtime:** Zero downtime is achievable with a delta-sync strategy — run the historical load while Zendesk is still live, then sync the delta immediately before cutover.

### Change Management Checklist

- [ ] Train agents on Gladly's conversation-based UI at least 1 week before go-live
- [ ] Prepare a "day one" quick-reference card: how to find imported history, where attachments are archived, how to create Topics, how to use Answers (replacing Macros)
- [ ] Set up a dedicated Slack channel or internal ticket queue for agent questions during the first 48 hours
- [ ] Brief team leads on what is and isn't in Gladly (no CSAT history, no attachment playback, no ticket numbers)
- [ ] Communicate externally only if customers will notice a change (e.g., new chat widget, new email sender address, new SMS short code)
- [ ] Update internal documentation and SOPs that reference Zendesk-specific features (Views, Macros, ticket statuses)

## What Data Cannot Be Migrated from Zendesk to Gladly?

Be explicit with stakeholders about these hard limits:

| Non-Migratable Data | Reason | Recommended Action |
|---|---|---|
| Attachments, images, recordings | Historical import is text-only | Archive to S3/GCS; link in Gladly notes |
| CSAT / Satisfaction Ratings | No import path | Export from Zendesk Explore; archive separately |
| SLA metrics and ticket lifecycle data | No Gladly equivalent for imported records | Archive from Zendesk; reset SLA tracking at go-live |
| Side Conversations | No Gladly equivalent | Convert to internal notes or archive |
| Ticket Forms | No concept in Gladly | Restructure using Topics and custom attributes |
| Ticket Statuses (New/Pending/Solved) | Gladly only supports Open/Closed | Map all non-Closed to Closed for historical import |
| Light Agent / Contributor roles | No read-only agent tier in Gladly | Assign full agent licenses or remove access |
| Suspended tickets | No Gladly equivalent | Triage and delete before migration |
| Merged ticket cross-links | Different merge model | Document merge history; cannot replicate chains |
| Organizations | No first-class equivalent | Flatten key fields to customer `customAttributes` or use Lookup Adapters |
| Macros, Triggers, Automations | Different logic model | Rebuild manually as Gladly Rules and Answers |
| Zendesk Talk call recordings | Historical import is text-only | Archive recordings to cloud storage for compliance |
| Custom ticket statuses | Gladly has Open/Closed only | Map to custom attributes if status tracking is needed |

## Edge Cases: Identity, Truncation, Multi-Brand, and API Caps

Most migration failures come from identity, not transport. The migration breaks when the same customer exists under multiple emails, when teams assume attachments will be native in Gladly history, or when validation relies on truncated API responses or fresh reports.

### Duplicate Requesters and Identity Fragmentation

Zendesk allows multiple end-user records with no email (phone-only, anonymous). Gladly requires a valid email for every imported record. Records without a valid email will be **silently rejected** — no error, no log entry in the historical import process. Audit your Zendesk user base before extraction — run `GET /api/v2/search?query=type:user role:end-user email:""` to identify email-less users.

The trickier problem is alias fragmentation. A single customer may exist under multiple Zendesk requester records with different email addresses. If you do not canonicalize emails before import, that customer gets split across multiple Gladly profiles. Multi-brand and multi-channel Zendesk instances are especially prone to this — the same customer may have tickets under `[email protected]` in brand A and `[email protected]` in brand B.

### Multi-Brand Migration

If your Zendesk instance serves multiple brands, each brand's tickets, help center, and configurations require separate treatment:

- **Inbox mapping:** Each Zendesk brand typically maps to a separate Gladly Inbox. Configure inboxes and email channels per brand before import.
- **Identity deduplication across brands:** This is the highest-risk area. Build a cross-brand customer identity map before migration. Match on email first, then phone number, then name + company as a fuzzy fallback.
- **Import sequencing:** You can run all brands in a single import pass if email canonicalization is complete. Otherwise, run brand-by-brand and merge duplicates post-import (more expensive and error-prone).
- **Help Center content:** Each brand's Help Center maps to a separate set of Gladly Answers. Import and tag Answers by brand/topic.

### Truncated Conversation Items

Gladly truncates imported bodies at **25,000 characters** and subjects at **100 characters**. Zendesk ticket descriptions and comments with long HTML content (common in email-heavy instances) may be cut. Pre-process by stripping HTML tags and checking character counts before load. For content exceeding the limit, append an external archive link to the truncated body so agents can access the full text.

### The 100-Conversation / 1,000-Item API Retrieval Cap

Gladly's REST API returns at most **100 conversations per customer** and **1,000 items per conversation**, both unpaginated. This is a **retrieval limit**, not an ingestion limit — data beyond these thresholds still exists in Gladly but is not returned by standard GET calls. The `Gladly-Limited-Data` response header indicates when data has been truncated. For post-migration validation on high-volume customer profiles, use Gladly's Export API rather than standard GET endpoints. ([developer.gladly.com](https://developer.gladly.com/rest/))

### Attachment Strategy

Since Gladly's historical import does not include attachments, you have three practical options:

1. **Archive to cloud storage (S3/GCS)** and link URLs in a pinned note on each Gladly customer profile. Use Zendesk's `GET /api/v2/tickets/{id}/comments` response to extract `attachments [].content_url` for each comment.
2. **Embed attachment URLs in conversation item text** during transformation — append download links to the imported body. Note that Zendesk attachment URLs use temporary tokens that expire; download and re-host files before import.
3. **Keep Zendesk in read-only mode** as a lookup archive for attachments, audits, and records that could not be imported due to missing email addresses. This is often the cheapest option and avoids discovering a missing compliance artifact later. Budget for continued Zendesk licensing (typically at a reduced tier).

### Inline Attachments in Zendesk

Zendesk allows agents to paste images directly into comments. These are stored as inline attachments with temporary AWS-signed URLs. If you are extracting these for archival, your extraction script must identify `<img>` tags in Zendesk HTML payloads, download the source file before the signed URL expires (typically 5–7 days after ticket closure), and store it in your archive destination. Process inline attachments during the extraction phase, not as a post-migration cleanup.

### Zendesk Talk / Voice Data

Zendesk Talk stores call recordings, voicemails, call duration, wait time, and disposition. None of these transfer to Gladly's historical import. To preserve voice history:

- Export call recordings via the Zendesk Talk API (`GET /api/v2/channels/voice/calls/{id}/recording`) and archive to cloud storage.
- Embed call metadata (duration, disposition, callback number) in the conversation item body during transformation.
- For compliance-required call recordings (HIPAA, PCI, financial services), ensure your archive meets retention requirements independently of either platform.

### GDPR/CCPA Deletion Flows

Deleted customers or conversations in Gladly can be expected — Gladly supports deletion flows for CCPA and GDPR requests. If you see records disappear after migration, verify whether a deletion request was processed before assuming data loss. Build a post-migration reconciliation report that flags record count discrepancies and cross-references against Gladly's deletion logs. ([help.gladly.com](https://help.gladly.com/developer-tutorials/docs/data-model-notes?utm_source=openai))

## How Do You Validate a Zendesk to Gladly Migration?

Validation proves data integrity. Do not rely on top-level record counts alone.

### Record-Count Reconciliation

| Check | Source Count (Zendesk) | Target Count (Gladly) | Acceptable Variance | How to Verify |
|---|---|---|---|---|
| Total customers created | Unique requester emails | Customer profiles | 0% — exact match | Gladly Export API or customer search |
| Total conversations | Total tickets (with valid requesters) | Total conversations | 0% for tickets with valid requesters | Gladly Export API |
| Total conversation items | Total public + internal comments | Total conversation items | ≤1% (body/subject truncation may cause drops) | Per-customer item count via API |
| Topics | Tags used on tickets | Topics in Gladly | 100% match (created pre-migration) | Gladly admin UI |
| Agents | Active agent users | Agent profiles | 100% match | Gladly admin UI |
| Custom attributes | Zendesk custom field values | Gladly custom attribute values | 0% for string fields; check enum mapping | Spot-check sample via API |

### Sampling Strategy

1. **Random sample:** Pull 100 random Zendesk ticket IDs. For each, verify the corresponding Gladly customer profile exists, the conversation item count matches the ticket comment count, and the original timestamps are correct.
2. **Edge-case sample:** Specifically check tickets with 50+ comments, tickets with attachments (verify archive links work), tickets from requester emails that appear on multiple tickets, tickets with custom field values, and tickets from phone-only or email-less requesters (should be excluded).
3. **Multi-brand sample:** If migrating multiple brands, verify that cross-brand customers are merged into a single Gladly profile and that brand-specific Topics and Inboxes are correctly applied.
4. **Negative test:** Confirm that Zendesk-only objects (SLAs, side conversations, suspended tickets) did **not** create unexpected records in Gladly.

Do not use same-hour Gladly reports as your only source of truth — report data has approximately a one-hour latency. Use direct API calls or Gladly's Export API for validation immediately after load. ([help.gladly.com](https://help.gladly.com/docs/why-is-my-reporting-data-not-current/?utm_source=openai))

### UAT Protocol

Have 3–5 agents search for known returning customers in Gladly and confirm:

- Historical conversation items appear on the timeline in correct chronological order
- Customer name, email, and phone are correct
- Topics (from Zendesk tags) are applied
- Custom attributes are populated with correct values
- Agent assignments on historical items are accurate (if imported via API path)
- Attachment archive links work (if you embedded them in conversation item text)
- Integration data loads correctly (Shopify order lookup, Salesforce account data via Lookup Adapter)

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

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

**Build in-house when:**

- Your Zendesk instance has fewer than 10,000 tickets
- You have minimal custom fields and no attachment archival requirements
- Your data is mostly email-based (few phone-only or anonymous requesters)
- You operate a single Zendesk brand
- You have a developer with 40+ hours available and Zendesk/Gladly API experience
- You can tolerate a longer timeline and iterative debugging

**Use a managed service when:**

- Your instance exceeds 50,000 tickets or 10,000 unique customers
- You need attachment archival and linking
- You require zero downtime and a delta-sync cutover
- You operate multiple Zendesk brands with cross-brand customer overlap
- Your engineering team is already committed to other projects
- You have compliance requirements (HIPAA, SOC 2, PCI) that demand audit trails during migration
- You have multi-channel data (voice, messaging) with identity fragmentation challenges
- You have complex integrations (Shopify, Salesforce, Jira) that must be re-wired simultaneously

The hidden cost of DIY is not the build — it is the re-migration. A rate-limit miscalculation or deduplication bug at 2 AM creates duplicate customer profiles that take days to untangle. The engineering time for a first-time Zendesk-to-Gladly migration typically runs **120–200 hours** including testing and fixes.

## The Decision That Saves Rework Later

Decide early whether your goal is **historical context**, **native Gladly analytics**, or **workflow parity**. You can get all three eventually, but not through one naive import path.

- If your main goal is **agent context** (agents can see past interactions), the official history-import route is usually enough. Accept that imported data will not be searchable, will not feed AI features, and will not appear in Gladly analytics.
- If your main goal is **native reporting and workflow parity**, you need a broader program: history import for context, live cutover for active work, integration re-wiring for operational continuity, and often a read-only Zendesk archive for attachments and audits.
- If your main goal is **compliance continuity**, keep Zendesk in read-only mode as your system of record for historical data and use Gladly exclusively for forward-looking interactions.

The teams that avoid rework are the ones that separate legacy history, live work, integration re-wiring, and archive strategy before the first export runs.

> Need help migrating from Zendesk to Gladly? Our engineers have handled hundreds of helpdesk migrations — including complex custom field mappings, zero-downtime cutovers, and high-volume datasets. Book a free 30-minute scoping call and we'll map out your migration plan.
>
> [Talk to us](https://cal.com/clonepartner/meet?duration=30)

## Frequently asked questions

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

A Zendesk to Gladly migration typically takes 2–4 weeks from discovery to go-live. Instances under 10,000 tickets with simple configurations can complete in 7–10 business days. Enterprise instances with 500,000+ tickets and complex automations may take 4–6 weeks.

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

Attachments, CSAT ratings, SLA metrics, side conversations, ticket forms, suspended tickets, and merged ticket cross-links cannot be migrated to Gladly. Macros, Triggers, Automations, and Views must be manually rebuilt as Gladly Rules, Answers, and Inboxes. Zendesk Organizations have no Gladly equivalent and must be mapped to custom attributes.

### Can Zendesk ticket history be preserved in Gladly?

Yes. Zendesk ticket comments import as conversation items on the customer's Gladly timeline with original timestamps preserved. However, imported items are text-based only — no attachments, images, or recordings — and are not searchable in Gladly's search function, though agents can view them on the customer profile.

### How much does a Zendesk to Gladly migration cost?

DIY API migration costs 120–200 hours of engineering time ($15,000–$40,000 at typical rates). Managed migration services range from $5,000–$25,000 depending on volume and complexity. Gladly's native historical import incurs a Professional Services fee negotiated during your contract.

### Does Gladly have a native Zendesk import tool?

Gladly supports Zendesk as a native source for historical conversation imports. You export Zendesk data in JSON format, upload it to a Gladly-provided Dropbox link, and their implementation team processes the import. This is text-based only — no attachments — and imported items are not searchable or reportable.
