Skip to content

Zendesk to Gladly Migration: The Complete Technical Guide

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.

Roopi Roopi · · 28 min read
Zendesk to Gladly Migration: The Complete Technical Guide
TALK TO AN ENGINEER

Planning a migration?

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

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

Zendesk to Gladly Migration: The Complete Technical Guide

Info

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) 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)

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.
  • 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)
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)
  • 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)
  • 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.

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)

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.

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)

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)

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)

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.

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.

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)

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.

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)

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.
Danger

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)

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)

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.

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)
  • 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)

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)

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)

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.

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.

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.

More from our Blog

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

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

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

Raaj Raaj · · 6 min read
Gladly Migration Checklist
Checklist/Gladly

Gladly Migration Checklist

Moving to Gladly? Use our migration checklist to transition from a ticket-based system to a people-centered model. Learn how to map customer timelines and API data safely.

Tejas Mondeeri Tejas Mondeeri · · 7 min read