How to Migrate from Jira Service Management to Zendesk
How to migrate from Jira Service Management to Zendesk: object mapping, API rate limits, step-by-step process, edge cases, and build vs. buy guidance.
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
TL;DR — Migrating from Jira Service Management (JSM) to Zendesk is a data-model translation problem, not a file transfer. JSM issues are Jira issues wrapped in ITSM features; Zendesk tickets are conversation-centric objects. No native migration path exists between the two platforms. The biggest risk is exposing internal comments as public replies if your migration script doesn't set public: false on each comment. SLA policies, workflows, approvals, and automation rules cannot be migrated programmatically — they must be rebuilt in Zendesk. Realistic timeline: 1–3 weeks for most environments. Teams with fewer than 5,000 tickets and standard fields can attempt a DIY API script. Everyone else should use a managed migration service.
Migrating from Jira Service Management to Zendesk requires translating an ITIL-aligned, issue-centric architecture into an omnichannel customer support data model. The two platforms organize support data differently at every level — objects, statuses, comments, and field types. JSM's native CSV export flattens relational data, losing ticket threading, inline attachments, and comment visibility. If you have over 10,000 tickets or need to guarantee the privacy of internal comments, use an API-based migration rather than building throwaway in-house scripts. (developer.atlassian.com)
What Is a Jira Service Management to Zendesk Migration?
A JSM to Zendesk migration is the process of extracting service desk data — tickets (issues), comments, users, organizations, attachments, and custom fields — from Atlassian's ITSM platform and loading it into Zendesk's customer support platform while preserving history, relationships, and data integrity.
JSM requests are implemented as Jira issues with request types, request fields, customer-visible statuses, and internal/public comment rules layered on top. Zendesk centers on tickets, users, organizations, ticket forms, and internal notes. The hard work is preserving meaning, visibility, and relationships when the two models do not align 1:1. (developer.atlassian.com)
Why Teams Move from JSM to Zendesk
The most common reasons are platform-specific:
- External customer support is the primary use case. JSM is architected for internal ITSM — incident management, change requests, engineering escalations. Zendesk is purpose-built for external customer conversations across email, chat, social, and phone. Teams that adopted JSM for customer support often hit friction with JSM's rigid issue-based UI and limited native omnichannel capabilities. Atlassian's own comparison content describes a pattern where customer-facing support stays in Zendesk while internal escalations live in JSM. (atlassian.com)
- Agent experience and speed. Zendesk's agent workspace is optimized for high-volume ticket triage. JSM's interface is optimized for workflow-heavy ITSM processes with screens, transitions, and validators that slow down agents handling simple customer queries.
- Ecosystem and integrations. Zendesk's marketplace has 1,500+ pre-built integrations for e-commerce, CRM, and customer data platforms. JSM's strength is Atlassian-ecosystem integrations (Confluence, Jira Software, Bitbucket).
For a deeper architecture comparison, see Zendesk vs Jira Service Management: The CTO's Architecture Guide.
Architectural Differences: Why This Isn't a Simple Export
Two fundamental architectural conflicts make this migration harder than it looks.
JSM issues are Jira issues. Every service request in JSM is a Jira issue with an issue type, project, workflow, screens, and custom field contexts. Zendesk tickets are flat conversation objects with a requester, assignee, status, and tags. There is no concept of "projects" or "issue types" in Zendesk — you use ticket forms and custom fields to replicate that structure. (developer.atlassian.com)
Comment visibility is handled differently. JSM distinguishes between internal comments (visible only to agents) and customer-visible replies using the visibility property on comments. Zendesk uses the public boolean on each comment object. A migration script that does not explicitly map visibility.type: "role" → public: false will expose internal engineering notes to customers. (developer.atlassian.com)
The single biggest failure mode in a JSM to Zendesk migration is comment visibility. Validate public/private comment counts before cutover, and spot-check tickets that contain escalation, security, finance, or incident-response notes.
Request type ≠ ticket form. In JSM, one work type can back many request types, request fields come from the underlying work type, and some fields can be hidden from customers while still used by agents. Zendesk can model similar intake with ticket forms and custom fields, but it is a redesign, not a literal copy. Zendesk documents ticket_form_id as Enterprise-plan only, so confirm your plan tier before assuming a form-per-request-type design. (support.atlassian.com)
Workflow status ≠ Zendesk status. JSM request statuses sit on top of Jira workflows with customer-friendly status mappings. Zendesk custom statuses must live inside fixed status categories: new, open, pending, hold, and solved; closed belongs to the solved category. Workflow graphs never port 1:1. (support.atlassian.com)
How to Map JSM Objects to Zendesk
The cleanest migrations start with an explicit object map. You cannot map these platforms 1:1 without data transformation.
| JSM Object | Zendesk Object | Notes / Caveats |
|---|---|---|
| Issue (Service Request) | Ticket | JSM issue key (e.g., HELP-1234) is lost — Zendesk assigns new IDs. Store the key in external_id and a visible custom field. |
| Reporter / Customer | Requester (End-User) | Must exist as an active user in Zendesk before ticket import. Map JSM accountId or email to Zendesk email. |
| Assignee | Assignee (Agent) | Must be an agent in Zendesk with the correct group membership before ticket assignment. |
| Project | Group or Brand | No direct Zendesk equivalent. Map to Groups (for routing) or Brands (for multi-brand setups). |
| Organization | Organization | 1:1 mapping. Import organizations before users. JSM allows multiple orgs per user; Zendesk supports this on specific plan tiers. |
| Request Type | Ticket Form + Custom Field | Zendesk has no "request type" object. Use Ticket Forms or a custom dropdown field. |
| Issue Type (Incident, Problem, etc.) | Ticket Type | Zendesk supports: question, incident, problem, task. Custom issue types must map to a custom field. |
| Priority (5 levels) | Priority (4 levels) | JSM has Highest/High/Medium/Low/Lowest; Zendesk has Urgent/High/Normal/Low. Decide how to collapse. |
| Labels / Components | Tags | Direct mapping, but Zendesk tags are flat strings — no hierarchy. |
| Public Comment | Public Comment (public: true) |
Preserve author_id and created_at timestamps using the Ticket Import API. |
| Internal Comment | Internal Note (public: false) |
Critical. Failure to set this exposes internal notes to customers. |
| Attachments | Attachments | Upload via /api/v2/uploads first, then reference the token in the comment payload. |
| Request Participants | Collaborators or Followers | Zendesk Ticket Import exposes collaborator_ids and follower_ids. Decide one global mapping rule. (developer.atlassian.com) |
| SLA Policy | SLA Policy | Cannot be migrated. Must be rebuilt manually in Zendesk. |
| Queue | View | Cannot be migrated. Rebuild as Zendesk Views using conditions. |
| Workflow / Transitions | Triggers + Automations | Cannot be migrated. Rebuild manually. |
| Approval | — | No Zendesk equivalent. Zendesk has no native approval workflow. |
| Assets (CMDB) | — | No Zendesk equivalent. Zendesk does not have a CMDB. |
| Knowledge Base (Confluence) | Zendesk Guide | Separate migration. Not covered by ticket migration. |
Field-Level Handling
- Store the old JSM issue key. Put it in Zendesk
external_idand a visible custom field so agents can search both ways. (developer.zendesk.com) - Map picklists by stable value, not label text alone. Zendesk ticket fields are typed objects with defined option values. Normalize JSM select values before loading. (developer.zendesk.com)
- Handle field type mismatches. JSM supports cascading select fields, multi-user pickers, and date-time pickers with time zones. These require transformation to Zendesk's closest equivalent (dropdown, text field, date field). A JSM "Version Picker" field must become a standard dropdown in Zendesk.
- Do not blindly surface internal-only fields. JSM request types can include fields hidden from customers. Decide whether each becomes a hidden Zendesk field, an internal note, or is dropped entirely. (support.atlassian.com)
- Handle deleted picklist values. If historical JSM issues reference deleted picklist values, Zendesk will reject the ticket creation unless you first recreate those legacy values in the Zendesk custom field schema.
API Rate Limits and Extraction Constraints
Extracting Data from JSM
JSM data must be extracted using the Jira REST API for core issue data and the Service Desk API for portal-specific data like comment visibility and request participants.
- Search endpoints: Use
POST /rest/api/3/searchor/rest/api/3/search/jqlwith JQL queries. The primary extraction query is something likeproject = "YOUR-PROJECT" ORDER BY id ASC. - Pagination: Default page size is 50 results. Jira Cloud enforces a hard ceiling of 10,000 results per search window. To paginate beyond 10,000 issues, filter by issue ID (
id > {last_seen_id}) and re-query. (developer.atlassian.com) - Comments and attachments: Require separate API calls per issue. Use
/rest/api/3/issue/{issueIdOrKey}/commentfor comments and theattachmentfield on the issue response for attachment metadata. For accurate public/internal visibility, use the JSM-specific endpoint:GET /rest/servicedeskapi/request/{issueIdOrKey}/comment. (developer.atlassian.com) - Rate limiting: Atlassian documents default burst limits of approximately 100 GETs/sec and 100 POSTs/sec per endpoint, plus per-issue write limits. Some endpoints are stricter — certain Service Desk endpoints are limited to 5 requests/sec. Exceeding limits returns HTTP
429withRetry-AfterandRateLimit-Reasonheaders. (developer.atlassian.com) - Attachment downloads: JSM attachment URLs require active authentication. Your extraction script must pass basic auth or OAuth tokens in the request header.
Jira Cloud's /rest/api/3/search/jql endpoint has known pagination issues. Multiple users have reported broken nextPageToken behavior. If you encounter this, fall back to the legacy /rest/api/3/search endpoint with startAt pagination, or filter by ID ranges.
Loading Data into Zendesk
Zendesk provides a dedicated Ticket Import API designed for migrations: POST /api/v2/imports/tickets (single ticket) and POST /api/v2/imports/tickets/create_many (batch of up to 100 tickets).
Zendesk API rate limits are account-level, not per-agent:
| Zendesk Plan | Requests/Minute |
|---|---|
| Team | 200 |
| Growth | 400 |
| Professional | 400 |
| Enterprise | 700 |
| Enterprise Plus | 2,500 |
| High Volume API Add-on | 2,500 (replaces plan limit) |
The Ticket Import API has specific behaviors that differ from the standard Tickets API:
- Preserves timestamps: You can set
created_at,updated_at, andsolved_aton imported tickets, andcreated_aton individual comments. - Bypasses triggers: Imported tickets do not fire triggers or automations. However, any subsequent update to an imported ticket will re-activate trigger evaluation.
archive_immediatelyflag: Whentrue, tickets imported withclosedstatus bypass the normal lifecycle and go directly to the archive. Zendesk recommends this for datasets exceeding 750,000 historical tickets.- SLAs are not calculated: Zendesk metrics and SLA policies do not apply to imported tickets. Tag imported tickets (e.g.,
migrated_from_jsm) and exclude them from SLA reports. - New ticket IDs: Zendesk assigns new IDs. You cannot preserve JSM issue keys.
The standard Zendesk ticket creation API overwrites historical dates with the current timestamp. To preserve original JSM creation and resolution dates, you must use the Ticket Import API, which accepts created_at and updated_at parameters.
Zendesk's Ticket Import API rejects comments with empty bodies. JSM allows comments that contain only attachments with no text. Add placeholder text (e.g., "(Attachment only)") or the import will fail silently for that comment.
Throughput Math
On a Professional plan (400 req/min), importing tickets in batches of 100 via create_many means each batch consumes 1 request. That's 400 batches × 100 tickets = 40,000 tickets per hour for the import step alone. But each ticket with attachments requires a prior upload call per file, and user/org creation shares the same rate budget. Zendesk also limits background jobs to 30 in-flight at once — exceeding this returns TooManyJobs errors. (developer.zendesk.com)
Realistically, expect 5,000–15,000 fully-formed tickets per hour including attachments and comment threading. Attachment-heavy projects are usually bandwidth- and job-limit-bound, not ticket-create-bound. (developer.zendesk.com)
Migration Approaches Compared
| Method | How It Works | Best For | Key Risk | Complexity |
|---|---|---|---|---|
| CSV Export + Manual Rebuild | Export JSM issues to CSV. Zendesk cannot import tickets via CSV — only users and orgs. Tickets require the API. | Fewer than 500 tickets, no attachment needs | Flattened relationships, no automated ticket import path | Low |
| DIY API Script (Custom ETL) | Write Python/Node scripts that extract from Jira REST API, transform, and load via Zendesk Ticket Import API. | Engineering teams with API experience, 1K–20K tickets | Rate limit handling, comment visibility mapping, attachment re-upload. Throwaway code. | High |
| Third-Party Migration Tool | SaaS tools (e.g., Help Desk Migration on Atlassian Marketplace) that automate field mapping and transfer. | Small-to-medium instances, standard configurations | Limited control over edge cases. Custom fields and complex threading may not map correctly. | Low–Medium |
| Managed Migration Service | An engineer-led team handles extraction, transformation, loading, validation, and cutover. | Enterprise volumes (20K+ tickets), compliance requirements, complex field structures | Cost. But eliminates throwaway ETL code and broken data risk. | Low (for your team) |
Decision guidance:
- < 500 tickets, no attachments: CSV export of users/orgs + manual ticket recreation or a marketplace tool.
- 500–20K tickets, standard fields: A third-party tool or a dedicated engineer building API scripts (budget 2–3 weeks of eng time).
- 20K+ tickets, custom fields, attachments, compliance: A managed migration service. The engineering hours burned on throwaway ETL code almost always exceed the cost of a specialist.
Step-by-Step Migration Process
The import sequence matters because Zendesk tickets reference users and organizations by ID. Importing tickets before their associated users exist will cause failures — or worse, Zendesk will map tickets to the API admin account, destroying your reporting and customer history. Follow this exact sequence.
Step 1: Export and Create Organizations
Extract JSM organizations and push them to Zendesk using POST /api/v2/organizations/create_many (batches of 100). Store the JSM org ID → Zendesk org ID mapping. (developer.zendesk.com)
Step 2: Export and Create Users
Extract all JSM reporters (portal customers) and assignees (agents). Create them in Zendesk via POST /api/v2/users/create_many (batches of 100). Map them to the Organization IDs from Step 1. Save the JSM accountId → Zendesk User ID mapping.
Disable welcome emails before importing users. In Zendesk Admin Center → People → Configuration → End users, deselect "Also send a verification email when a new user is created by an agent or administrator." Otherwise, every imported user receives a password reset email.
Step 3: Export Issues with Full Comment History
Query JSM issues using JQL: project = "YOUR-PROJECT" ORDER BY id ASC. For each issue, fetch:
- All fields (including custom fields)
- All comments with visibility flags via the JSM request comment endpoint (
GET /rest/servicedeskapi/request/{issueIdOrKey}/comment) - All attachment metadata
Paginate in batches using startAt or filter by ID ranges. For projects exceeding 10,000 issues, use ID-based filtering to work around the search ceiling. (developer.atlassian.com)
Step 4: Upload Attachments to Zendesk
For each attachment on each issue, download the file from JSM (the content URL in the attachment object — requires authentication) and upload to Zendesk via POST /api/v2/uploads. Zendesk returns a token that you reference in the comment payload during ticket import.
Step 5: Transform and Import Tickets
For each JSM issue, construct a Zendesk Ticket Import payload. Map the JSM Reporter to requester_id, the Assignee to assignee_id, and explicitly set public: false on every internal comment.
Example payload for a ticket with an internal note and attachment:
{
"ticket": {
"subject": "Server outage in US-East",
"requester_id": 12345678,
"assignee_id": 87654321,
"group_id": 111,
"organization_id": 222,
"status": "solved",
"priority": "normal",
"created_at": "2023-05-10T14:00:00Z",
"updated_at": "2023-05-10T14:30:00Z",
"solved_at": "2023-05-10T14:30:00Z",
"tags": ["migrated_from_jsm", "incident"],
"external_id": "HELP-1234",
"custom_fields": [
{"id": 360001, "value": "hardware_request"}
],
"comments": [
{
"author_id": 12345678,
"value": "I cannot access the portal.",
"created_at": "2023-05-10T14:00:00Z",
"public": true
},
{
"author_id": 87654321,
"value": "Checked the logs, looks like a DNS issue.",
"created_at": "2023-05-10T14:15:00Z",
"public": false,
"uploads": ["token_received_from_step_4"]
}
]
}
}Use POST /api/v2/imports/tickets/create_many for batch import (up to 100 tickets per request). Your loading script must handle rate limits and background job queues:
for batch in ticket_batches:
while True:
resp = zendesk.import_tickets(batch) # up to 100 per batch
if resp.status_code == 429:
sleep(int(resp.headers['Retry-After']))
continue
if resp.json().get('error') == 'TooManyJobs':
sleep(60)
continue
breakThat retry loop is not optional. Zendesk documents Retry-After handling for 429 responses and a 30-job in-flight limit. Jira Cloud also returns 429 with Retry-After on burst rate limiting. (developer.zendesk.com)
Step 6: Delta Sync and Cutover
Run a delta migration immediately before go-live to capture any JSM tickets created or updated during the primary migration window. Keep JSM live during the historical load, then:
- Freeze JSM (set to read-only or stop accepting new requests).
- Migrate remaining active tickets.
- Switch email routing and portal DNS to point to Zendesk.
- Keep JSM read-only until validation is complete.
Timeline, Phases, and Resourcing [For PMs]
Realistic timelines based on volume:
| Volume | Timeline | Recommended Approach |
|---|---|---|
| < 5,000 tickets | 3–5 days | DIY script or third-party tool |
| 5,000–50,000 tickets | 1–2 weeks | API script with dedicated engineer or managed service |
| 50,000–500,000 tickets | 2–4 weeks | Managed service recommended |
| 500,000+ tickets | 3–6 weeks | Managed service with archive_immediately flag |
Do not attempt a "big bang" migration for anything over 50,000 tickets. Use a phased approach.
Sample Phased Timeline (50K tickets)
| Phase | Duration | Activities |
|---|---|---|
| Discovery & Mapping | 2–3 days | Audit JSM data, define field mapping, identify custom fields and edge cases. Delete unused issue types and stale custom fields. |
| Zendesk Configuration | 2–3 days | Create ticket forms, custom fields, groups, SLA policies, triggers, automations. |
| Sandbox Test Migration | 2–3 days | Migrate a 1,000–2,500 ticket sample to a Zendesk sandbox. Verify internal comment privacy, attachment accessibility, and custom field mapping. |
| UAT & Adjustments | 2–3 days | Support agents review sandbox data. Iterate on mapping issues. Conduct Zendesk UI training. |
| Full Historical Load | 1–2 days | Migrate all closed and resolved tickets during off-hours. Monitor throughput. |
| Delta Sync & Go-Live | 1 day | Freeze JSM, migrate remaining active tickets, switch email/DNS routing to Zendesk. |
| Hypercare | 2–5 days | Support ops monitors for issues, validates edge cases in production. |
Risk Register
| Risk | Likelihood | Mitigation |
|---|---|---|
| Internal comments exposed as public | High (if not handled) | Explicit public: false mapping for all JSM internal comments. Validate before cutover. |
| Broken user/org references | Medium | Import users and orgs before tickets. Validate ID mapping table. |
| API throttling stalls import | Medium | Implement exponential backoff, parse Retry-After headers. Run during off-peak. Consider High Volume API add-on. |
| Attachment loss | Medium | Download and re-upload all attachments. Verify file sizes and click-through accessibility. |
| Duplicate tickets after retry | Low | Use external_id (JSM issue key) as idempotency key. |
| Broken inline images | Medium | Parse HTML comment bodies for <img> tags. Replace JSM image URLs with Zendesk attachment tokens. |
| Agent confusion post-migration | Medium | Conduct Zendesk UI training during sandbox testing phase. |
What Customers and Agents Notice During Migration [For Customer Success]
With proper planning, customers should notice zero downtime. The standard approach:
- Run the full historical migration while JSM is still live.
- Perform a delta sync immediately before cutover.
- Switch email routing and portal DNS to Zendesk.
Customers will notice:
- New ticket IDs. Zendesk assigns new IDs. Bookmarked JSM ticket URLs will break. Store the original JSM key in
external_idand a visible custom field so agents can answer "where did HELP-4821 go" immediately. Communicate the ID change proactively. (developer.zendesk.com) - Different portal experience. Zendesk's Help Center looks and feels different from JSM's Customer Portal. JSM request type names (e.g., "Report a hardware issue") are not preserved as structured data — they migrate as tags or custom field values. Prepare a brief customer-facing guide.
- Full history is preserved (when migrated correctly). Customers viewing past tickets in Zendesk see the complete conversation thread with correct timestamps.
Do not promise identical SLA clocks across the cutover. Zendesk does not calculate SLA metrics for imported tickets. Historical SLA outcomes should be preserved for reporting (in your data warehouse or as custom field values on migrated tickets), while live Zendesk SLA timers start fresh under the new policy model. (support.atlassian.com)
The biggest trust risk is missing conversation history. If a customer contacts support about an ongoing issue and the agent can't see the prior JSM thread, it signals incompetence. Preserving full comment history — including the internal notes agents need for context — is non-negotiable.
What Cannot Be Migrated from JSM to Zendesk
Be honest about what doesn't transfer:
- SLA policies and SLA history. Zendesk does not calculate SLA metrics for imported tickets. Rebuild SLA policies in Zendesk. Historical SLA compliance data stays in JSM or should be exported to your data warehouse (e.g., Snowflake or Redshift) for long-term reporting.
- Workflows and transitions. JSM's workflow engine (statuses, transitions, validators, post-functions) has no API-importable equivalent in Zendesk. Rebuild as triggers and automations.
- Approval chains. Zendesk has no native approval workflow. Migrate approval records as internal notes or explore Zendesk marketplace apps.
- CMDB / Assets. Zendesk does not have a configuration management database. Jira Cloud export does not include Assets data. If tickets reference assets, migrate only the reference values or rebuild separately. (support.atlassian.com)
- Opsgenie-backed service data. Atlassian's export documentation explicitly excludes JSM features powered by Opsgenie, including alerts and on-call schedules. (support.atlassian.com)
- JSM issue keys.
HELP-1234cannot be preserved as the ticket ID. Useexternal_idfor cross-reference. - Automation rules. JSM automation rules must be manually recreated as Zendesk triggers, automations, or macros. Even Jira-to-Jira automation imports may need reconfiguration of statuses, issue types, and fields. (support.atlassian.com)
- CSAT survey data. JSM satisfaction ratings do not map to Zendesk's satisfaction survey system.
- Knowledge base (Confluence). Requires a separate migration to Zendesk Guide. Not covered by ticket migration.
Edge Cases and Known Limitations
Suspended/deactivated users. Zendesk's Ticket Import API requires requesters to be active (non-suspended) users. If your JSM data includes tickets from deactivated Atlassian accounts, either temporarily activate those users in Zendesk or map their tickets to a placeholder account like former-employee@yourcompany.com.
ADF to HTML conversion. JSM stores comment bodies as Atlassian Document Format (ADF) JSON. Zendesk accepts HTML via html_body or plain text via value. You need a transformation layer to convert ADF → HTML, or you lose formatting — tables, code blocks, and inline images.
Inline images. Your transformation script must parse HTML bodies for <img> tags referencing JSM URLs and replace them with Zendesk attachment tokens. If you skip this, inline images appear as broken links after migration.
Multi-project migrations. If you're migrating multiple JSM projects into a single Zendesk instance, plan your Group and Brand structure first. Each JSM project typically maps to a Zendesk Group, but overlapping agents across projects can create assignment conflicts.
Linked issues. JSM supports issue linking ("is blocked by", "relates to"). Zendesk has a limited linking feature, but the Ticket Import API does not support creating links during import. Links must be created post-import via the standard API, adding complexity and API calls.
Custom field type mismatches. JSM supports cascading select fields, multi-user pickers, and date-time pickers with time zones. These require transformation to Zendesk's closest equivalent. Multi-level cascading dropdowns need Zendesk conditional ticket fields, which must be configured before the data load.
5,000 comment limit per ticket. Zendesk documents a hard limit of 5,000 comments (public and private) per ticket. Tickets exceeding this need splitting, archiving, or an offline history strategy. (developer.zendesk.com)
Priority level collapse. JSM has 5 priority levels (Highest, High, Medium, Low, Lowest). Zendesk has 4 (Urgent, High, Normal, Low). Decide on the mapping before migration — typically Highest → Urgent and Lowest → Low, but confirm with your support team.
Very large attachment volumes. A 50K-ticket instance with an average of 3 attachments per ticket means 150,000 file downloads from JSM and 150,000 uploads to Zendesk — all competing with your ticket import for rate limit budget. Factor this into your throughput calculations.
Validation and Testing
Validation is where most DIY migrations fail. A migration isn't done when the import script finishes — it's done when every record has been verified.
Record-count reconciliation. Compare total issues in JSM (via JQL count) against total tickets in Zendesk (via API or admin dashboard). Discrepancies usually mean failed imports that returned 4xx errors your script didn't catch. Reconcile by request type, status, organization, and date range.
Field-level spot checks. Sample 5–10% of tickets across different request types, statuses, and date ranges. Verify:
- Subject/summary matches
- Requester and assignee are correct
- Comment count matches (including internal notes)
- Internal comments are actually internal (not public)
- Attachments are downloadable, not 404 errors
- Custom field values are present and correct
- Timestamps are accurate
UAT with agents. Have 2–3 agents work through real ticket scenarios in Zendesk's sandbox. Can they find historical tickets? Are internal notes visible only to agents? Do tags and custom fields filter correctly in Views?
Rollback plan. If validation fails, your rollback is to keep JSM running and delete the imported data from Zendesk. Zendesk supports bulk ticket deletion via the API, but it's slow — plan for this in your timeline. Write the rollback plan before the full load starts.
For a comprehensive validation checklist, see Zendesk Migration Checklist. If you need a failure-recovery framework, see Help Desk Data Migration Failed? The Engineer's Rescue Guide.
Build In-House vs. Use a Managed Service
When In-House Makes Sense
- Fewer than 5,000 tickets with standard fields, no attachments, and a developer with free cycles.
- Your team has already built API integrations with both Jira and Zendesk.
- You're comfortable with the risk of 2–3 weeks of engineering time on throwaway code.
When In-House Is a Bad Idea
- Custom fields and complex threading. Every non-standard field type requires custom transformation logic. Cascading selects, multi-user pickers, and ADF-to-HTML conversion each add days of development.
- Attachment volume. 150,000 file downloads and uploads for a 50K-ticket instance with 3 attachments per ticket — all competing for the same rate limit budget as your ticket import.
- Compliance requirements. If you need audit trails, data residency guarantees, or GDPR-compliant handling of PII during transfer, a managed service with documented processes is significantly easier to justify to your compliance team.
- The real cost is opportunity cost. A senior engineer spending 3 weeks building and debugging a one-time migration script is 3 weeks not spent on product work. The script has zero reuse value after go-live.
One often-overlooked downside of leaving JSM: you lose the native, out-of-the-box integration with Jira Software for engineering escalation. You'll need to implement the Zendesk-for-Jira integration to maintain the link between customer support tickets and engineering bug tracking.
ClonePartner handles the full Jira-to-Zendesk schema transformation — including internal comment visibility, ADF-to-HTML conversion, and attachment re-upload — with built-in rate limit management and zero downtime. Our infrastructure natively manages Zendesk's API rate limits and HTTP 429 Retry-After headers, ensuring sensitive engineering notes are never exposed to customers. As an engineer-led service, we take full accountability for the migration, freeing your team from building and maintaining throwaway ETL scripts.
Frequently Asked Questions
- Can I migrate Jira Service Management to Zendesk without losing data?
- You can migrate tickets, comments (public and internal), users, organizations, attachments, and custom field values without loss using the Zendesk Ticket Import API. However, JSM SLA history, workflow configurations, automation rules, approval chains, CMDB/Assets data, and CSAT survey data cannot be migrated programmatically — they must be rebuilt manually in Zendesk. Original JSM issue keys are also lost; Zendesk assigns new ticket IDs.
- How long does a Jira Service Management to Zendesk migration take?
- A typical migration takes 1–3 weeks end-to-end. Small instances under 5,000 tickets can complete in 3–5 days. Enterprise environments with 100K+ tickets, complex custom fields, and heavy attachment volumes typically require 3–6 weeks including discovery, test migrations, full migration, and validation.
- How do I prevent JSM internal comments from becoming public in Zendesk?
- Extract comments using the JSM request comment endpoints where public/internal visibility is explicit, then set the boolean value public: false on every internal comment in the Zendesk import payload. Treat this as a QA gate — validate public/private comment counts before cutover, not after.
- Does Zendesk preserve original ticket timestamps from JSM?
- Yes, but only if you use the Zendesk Ticket Import API (/api/v2/imports/tickets). It allows setting created_at, updated_at, and solved_at on imported tickets, plus created_at on individual comments. The standard ticket creation API overwrites all dates with the current timestamp.
- What data cannot be migrated from Jira Service Management to Zendesk?
- JSM SLA policies and historical SLA data, workflow configurations, automation rules, approval chains, CMDB/Assets data, Opsgenie-backed service data, CSAT survey data, and original issue keys cannot be migrated programmatically. These must be rebuilt manually in Zendesk or archived separately.

