
This guide walks you through everything you need to plan, map, move, and verify a Zendesk to Freshdesk migration with a high degree of fidelity. I will keep it practical. You will see exactly what should be recreated as configuration, what should be imported as data, and how to handle the gray areas like timestamps, side conversations, and historical CSAT. When we reach each data object in the migration flow, I include a concise field-mapping table with caveats and small tactics that save hours.
1. Scope the project
Start with a short inventory of what you are moving as data versus what you will rebuild.
Data includes tickets with their full conversation history and files, contacts and companies, tags, custom fields, side conversations, and the knowledge base.
Configuration includes automations, SLAs, business hours, views, roles, and any app integrations.
Some items cannot be imported as native objects in Freshdesk, so you will preserve them as notes or archive files.
With that picture in mind, it's important to create a detailed mapping that names every Zendesk object, the target object in Freshdesk, any transforms, and a validation rule that proves it landed correctly. We will explore the mappings in detail in the upcoming sections.
2. Prepare the destination
Before importing anything, it's necessary to first set up a Freshdesk environment that mirrors your current structure as closely as possible.
Create agents, groups, and roles. Recreate business hours and holidays, then define SLAs.
Add ticket statuses so your status mapping will be clean. Rebuild ticket forms and all custom fields for tickets, contacts, and companies.
Configure mailboxes and signatures. Install the Jira app if you plan to keep engineering links.
When this foundation exists, your importer can reference real ids and you will not end up with orphaned assignments or field values that have nowhere to go.
3. Migrate in a sequence that maintains relationships
The load sequence matters because tickets reference contacts and companies, and conversations reference tickets. The safe order is: companies first, then contacts, then ticket schema, then tickets with their conversation history, then CSAT, then the knowledge base. I will walk through each element in that order, along with the exact mapping and the small caveats that usually bite.
3.1 Companies
Import companies before contacts so links resolve cleanly. Keep the original Zendesk organization id as an external reference in Freshdesk so you can re-run safely and cross-check during validation.
Organization → Company mapping
Zendesk Organization | Freshdesk Company | Notes and caveats |
id | unique_external_id and a read-only field zd_org_id | Using both makes retries idempotent and helps with audits. |
name | name | Keep names as is. |
domain_names[] | domains[] | Preserve all domains for auto-association. |
organization_fields{} | custom fields | Pre-create field schema and allowed values. |
tags[] | tags or a multiselect field | Use tags if available. Otherwise, store in a multiselect. |
After the company load, spot check counts,newly and a few sample records that use multiple domains, custom fields, and tags.
3.2 Contacts
Now bring in contacts and attach them to companies. If your users have multiple emails in Zendesk identities, map them to Freshdesk secondary emails so replies thread correctly.
User → Contact mapping
Zendesk User | Freshdesk Contact | Notes and caveats |
id | unique_external_id and a read-only field zd_user_id | Same idempotency pattern as companies. |
name | name | Preserve capitalization. |
Required for requesters. | ||
user_identities emails | other_emails[] | Add every secondary address. |
organization_id | company_id | Only reference a company that already exists. |
phone, mobile | phone, mobile | Normalize formats if needed. |
user_fields{} | custom fields | Precreate schema. |
tags[] | tags | Optional but useful for segmentation. |
Agents are created in Freshdesk admin, not as contacts. If you need to attribute historical notes to agents you will not provision, prefix the note body with the author name and email so the history remains readable.
3.3 Ticket schema
Create ticket forms and all custom fields before the actual tickets. Align option lists exactly so values drop in without transforms. Build your status and priority crosswalk now and test it on a handful of sample tickets.
3.4 Tickets and full conversation history
Create the ticket shell with core fields, then append the conversation stream in chronological order and attach files to the specific notes they belong to. Preserve authorship as faithfully as the target allows. Freshdesk will stamp newly created and updated times on most objects, so you will keep the original timestamps in fields and in the first note.
Ticket mapping
Zendesk Ticket | Freshdesk Ticket | Notes and caveats |
id | unique_external_id and a read-only field zd_ticket_id | Prevents duplicates and enables delta loads. |
external_id | unique_external_id or a custom field | Use if you already rely on it in Zendesk. |
subject | subject | |
description (HTML) | initial note or description at create | Keep HTML, fix inline image links after upload. |
requester_id | requester contact | Contact must exist. |
assignee_id | responder_id | If the agent does not exist yet, assign to a staging group, then reassign. |
group_id | group_id | Groups must exist. Consider storing original group name in a field for audit. |
status | status | Use your crosswalk. If you need exact labels, create custom statuses in Freshdesk. Store the original Zendesk label in zd_status_label. |
priority | priority | Map directly. If you used custom scales, keep the original in a custom field. |
type | custom field zd_type | Freshdesk types differ. Keep it as a dropdown. |
ticket_form_id | ticket_form_id and optional zd_form | Set the matching form id or keep the name in a field if you cannot match. |
brand_id | product or portal assignment, or zd_brand field | Decide per brand. If consolidating, keep the original brand in a field. |
tags[] | tags | One to one. |
custom_fields{} | custom fields | Schema must exist. |
due_at | due_by or zd_due_at | If not supported, store and drive an automation as needed. |
via.channel | channel field or a tag | Keeps channel reporting intact. |
created_at, updated_at | read-only in target | Add a first private note that states the original created time and author. Also store original_created_at and original_updated_at in read-only fields. |
ccs or followers | CCs | Add them on create so notifications mirror history. |
Conversation mapping
Zendesk Comment | Freshdesk Conversation | Notes and caveats |
public true | public reply | Maintain author identity if possible. |
public false | private note | Keep internal notes internal. |
body_html | body HTML | Clean and normalize. |
attachments[] | uploaded files on that note | Keep original filenames. Rebuild inline references after upload. |
Side conversations | private note with transcript and files | Start note with participants and original timestamps. |
Import tickets in batches and verify a sample after each batch. Look for thread order, missing files, broken inline images, and the wrong requester on replies. Those four catch most defects early.
3.5 Ticket CSAT
If you care about historical satisfaction, recreate ratings on the corresponding tickets. Targets usually do not allow backdating, so you capture the original timestamp and any reason code inside a companion private note.
CSAT mapping
Zendesk CSAT response | Freshdesk satisfaction | Notes and caveats |
rating value | rating on the ticket | Create after the ticket and conversation history. |
free text comment | rating comment or a paired note | If the rating object cannot hold all context, add a note. |
rater and time | private note text | Include “Original CSAT at 2024-03-10 11:05 UTC by …”. |
negative reason | appended to the note | No direct field, so keep it in the note body. |
3.6 Knowledge base
The knowledge base is a straightforward structural migration. Create categories, then folders, then articles. After each article exists, add translations and upload attachments. Rewrite any inline asset URLs inside the HTML to point to the files you just uploaded. If you used redirects in Zendesk, keep a CSV mapping and recreate them in your Freshdesk portal or at the web server.
Guide → Solutions mapping
Zendesk Guide | Freshdesk Solutions | Notes and caveats |
Category | Category | Create first. |
Section | Folder | Create under the correct category. |
Article (HTML) | Article (HTML) | Preserve formatting and headings. |
Article attachments and media | Article attachments | Upload, then rewrite inline links. |
Translations | Translations | Add after the base article. Keep locale codes aligned. |
Labels and content tags | Article tags | One to one. |
Redirect rules | Portal redirects | Recreate from a CSV. |
Article comments | Optional appendix in article body | If you must keep them, add a “Legacy comments” section at the end. |
When the load completes, count articles per category and per language on both sides. That quick report surfaces missing translations and misplaced folders immediately.
4. Rebuild the behavior so the system works like it did yesterday
Once the data is in, you want Freshdesk to feel familiar to your team.
Translate your Zendesk triggers and automations into Freshdesk automations on create, on update, and scheduled. Where a Zendesk action used a “Target,” use a Freshdesk webhook action.
Recreate views with equivalent filter logic so agent queues look the same.
Rebuild SLA policies and apply the correct business hours, then open a few test tickets and watch timers to verify first response and resolution behave as expected.
For Jira, store the original issue key in a custom field during import, then use the Freshdesk Jira app to relink tickets in bulk or with a small helper script that reads the field and creates the association.
5. Handle missing gaps
Some Zendesk constructs do not exist as native objects in Freshdesk. The two big ones you will encounter are ticket audits and metric events.
Export those from Zendesk as CSV or JSON and keep them in a secure archive. On the corresponding Freshdesk tickets, add a read-only field or an internal note with a link to the archive location.
Side conversations do not have a one-to-one object in Freshdesk, so the pattern used above is the simplest and most supportable.
Community forums, badges, and votes generally live outside the scope of a help desk, so preserve them as an archive.
Timestamps are another common gap. Since you cannot backdate most records, the combination of read-only “original_created_at” fields and a first note that states the original author and time gives auditors enough context without bending the target platform.
6. Test with intent, run a delta, then cut over
Pick a small set of tickets that cover every tricky case you have seen. Include long threads, large file sets, multiple languages, side conversations, custom statuses, bad ratings, and multiple forms.
Migrate only that set and walk the records side by side with an agent lead. If it passes, scale to a larger batch.
When you are ready for cutover, pause creation in Zendesk, run a delta extraction of anything created or updated since your last run, and apply it with the same mapping and unique_external_id checks.
Switch email routing to Freshdesk, enable chat or voice on the Freshworks stack if applicable, and keep Zendesk in read-only mode for a couple of weeks for reference.
Before go-live, run simple reconciliations. Ticket counts per status and per group should match previous records. A random set of tickets should show the right requester, assignee, tags, fields, number of notes, and every attachment. Knowledge base article counts per category and locale should match. SLAs should tick as expected on fresh tickets created in the new system.
Quick Recap
Prepare Freshdesk first, so the schema and teams are real. Load companies, then contacts, then ticket schema, then tickets with their full conversation history and files, then CSAT, then the knowledge base with translations and redirects. Rebuild automations, SLAs, views, and integrations. Archive audits and metric events outside the help desk and link them for reference. Validate on a golden sample, run a delta, cut over, and monitor. If you follow this sequence and the mappings above, your Freshdesk system will behave like your Zendesk system while being clean and maintainable from day one.
At ClonePartner, we’ve done this numerous times. Each project has a dedicated engineer who tailors the mapping to fit your unique data structure. If you’d prefer to skip the technical complexity, ClonePartner can take care of everything for you, from planning and field mapping to final validation and go-live.