Migration Playbook

Enchant Desk365

Enchant to Desk365: The Complete Migration Playbook

A 35-step runbook across six phases — track your progress, and open the right tool at every step.

0 / 35 steps complete 0%
TL;DR

Enchant to Desk365 migration requires API-based extraction (100 credits/min), careful label-to-category mapping, and awareness of Desk365's tight rate limits (100/hr on Standard). Plan for a transformation layer between the two data models.

There is no native migration path from Enchant to Desk365; all data must be extracted via the Enchant REST API v1 and ingested into Desk365 via API v3, with a custom transformation layer in between. The fundamental structural gap is that Enchant uses a flat, shared-inbox model built around labels, while Desk365 enforces strict relational data models with Agents, Groups, Contacts, Companies, custom fields, ticket types, and SLA policies. Label-to-field mapping, state normalization, priority derivation, and conversation thread reconstruction all require bespoke transformation logic before any data can be loaded. A naive loop-and-push script will result in lost conversation history, broken agent attribution, orphaned attachments, and missing structured metadata.

Read this first

Pair-specific gotchas that catch teams out. Each one has cost somebody a weekend.

Social channel data loss risk

Enchant supports tickets from Twitter, Facebook Messenger, Instagram DM, WhatsApp, and SMS. Desk365's source values don't include these channels natively. If preserving the original channel is important, store the Enchant type value in a Desk365 custom field (e.g., cf_original_channel) before migration.

Handling inactive agents

If you have historical tickets assigned to agents who have since left the company, Desk365 will return a 422 Unprocessable Entity error if you attempt to assign the ticket to a non-existent agent. Either create a "Migration Archive" dummy agent in Desk365 to hold these tickets, or map all inactive agents to a specific active administrator in your agent mapping table.

Rate limiting strategy

Implement exponential backoff when receiving 429 responses. Read the Retry-After header if provided; otherwise back off exponentially (2s, 4s, 8s, 16s) on successive 429s. Fixed sleep timers are fragile — rate limit reset windows vary based on account activity.

Checkpoint your extraction

Record each successfully fetched ticket ID in your local tracking database immediately after download. If rate limits or network issues interrupt the run, resume from the last checkpoint rather than restarting from zero.

The Standard plan limit of 100 calls per hour is prohibitive for any meaningful migration

At that rate, loading 10,000 tickets would take over 100 hours of API time, excluding conversations and attachments. Upgrade to Plus or Premium before starting migration, and downgrade after completion. At 50 calls/minute (Plus/Premium), migrating 10,000 tickets with conversations still takes 12–20 hours.

Private note mapping is critical

If you accidentally map Enchant internal notes (type: note) to agent replies instead of private notes, customers will see internal team discussions in their support portal. Test this mapping explicitly on your 50-ticket pilot before running the full migration.

File size limits

Desk365 enforces attachment size limits (typically 15–25MB depending on plan; verify in your account settings). The API returns 413 Request Entity Too Large for oversized files. Your script must check attachment ["size"] before downloading from Enchant. If the file exceeds the limit, skip the upload and append a text note to the message body: [Attachment stripped during migration: filename.ext (32.4MB) — exceeded size limit].

The runbook

Work top to bottom. Tick steps as you go — your progress is saved in this browser.

01 Discovery Establish why you are moving, what "done" means, and who signs off. 0/5

Objective A written scope with agreed success criteria, a named owner per workstream, and a budget approved by finance.

  1. Pull the real numbers out of Enchant

    Support ops 1 day

    Export counts for tickets (open and closed separately), contacts, organisations, attachments, macros, triggers, automations, views and SLA policies. Note the oldest ticket date — history depth drives the whole timeline. Estimating from memory is the single most common cause of a blown migration window.

    Data Profiler Get real record counts instead of estimating from memory
  2. Decide what history actually moves

    Support lead 2 days

    Agree a cut-off with the support lead: all history, last 24 months, or open tickets plus a read-only archive. Every extra year of closed tickets adds API time and cost without adding much agent value. Get this in writing — it is the decision people relitigate mid-cutover.

    A "move everything" default is what turns a two-week migration into a two-month one.

    COI & ROI Calculator Build the 36-month business case you will need for sign-off
  3. Confirm Desk365 can hold your support model

    Solution architect 2-3 days

    Walk your current workflow through Desk365: multi-brand, business hours, SLA targets, CSAT, side conversations, public vs internal notes, and any channel you depend on (voice, chat, WhatsApp, social). List anything with no native equivalent — those are project risks, not configuration details.

  4. Build the business case

    Project sponsor 1-2 days

    Model licence delta, migration effort, agent retraining, and the cost of staying put (Cost of Inaction). Executives approve a number, not a plan, and you will be asked for it again at the go/no-go.

    Helpdesk Migration Planner Turn ticket volume into a dated Enchant → Desk365 timeline
  5. Name owners and set the go/no-go date

    Project manager 1 day

    One named owner each for data, configuration, integrations, and agent enablement, plus a decision-maker who can call a rollback. Put the go/no-go meeting in calendars now, 48 hours before the freeze.

Enchant → Desk365 specifics

Microsoft 365 integration
Desk365 supports native Teams ticketing, Entra ID (Azure AD) agent sync, and a Power Automate connector. Enchant has no Microsoft 365 integrations.
Company-level management
Enchant has no Companies entity — customers are standalone records. Desk365 has a full Companies object with associated contacts, company-specific SLA policies, and department-level management.
SLA enforcement
Enchant has basic SLA support through rules. Desk365 has native SLA policies with configurable first response and resolution targets, business hours configuration, per-company SLA overrides, and breach escalation rules.

Don't move on until

  • Record counts confirmed for tickets, contacts, organisations and macros
  • Success criteria signed off by the support lead
  • Freeze window provisionally booked with the business
02 Data Audit Find out what is actually in the data before you try to move it. 0/6

Objective A profiled, cleaned export with every quality defect either fixed at source or explicitly accepted.

  1. Take a full Enchant export and profile it

    Data engineer 1-2 days

    Export to CSV or JSON and profile every file: row counts, null rates per column, distinct values, and type consistency. Compare row counts against the API totals from Discovery — a gap here means your export is silently truncated, usually by pagination.

    Data Profiler Profile the Enchant export for nulls, outliers and type drift
  2. Validate file structure before anyone writes a transform

    Data engineer 1 day

    Check delimiters, quoting, encoding (expect UTF-8, watch for BOMs and Latin-1), duplicate headers, and embedded newlines in ticket bodies. Ticket descriptions with raw newlines and commas break naive CSV parsers and silently shift columns.

    A single unescaped quote in one ticket body can shift every subsequent column without any error.

    CSV Validator Catch broken headers and ragged rows in the raw export
  3. Inventory PII and set retention

    Compliance / DPO 2 days

    Scan for emails, phone numbers, payment card fragments, national IDs and anything else regulated in ticket bodies and custom fields — support tickets are where customers paste things they should not. Decide what gets migrated, masked, or dropped, and record the legal basis.

    Ticket bodies and attachments routinely contain card and ID data that never appears in a structured field.

    PII & Compliance Scanner Find regulated fields before they land in a new system
  4. Quantify duplicates, orphans and dead references

    Support ops 1-2 days

    Count duplicate contacts (same email, different casing), tickets whose requester no longer exists, organisations with no members, and attachments whose parent ticket is gone. Fix these in Enchant where you can — migrating them just moves the mess.

    Data Cleaner Strip empty rows, stray whitespace and dead columns
  5. Clean and normalise the export

    Data engineer 2 days

    Trim whitespace, drop empty rows and columns, normalise casing on emails and tags, and standardise every timestamp to UTC ISO 8601. Timezone drift is invisible at load time and shows up weeks later as SLA reports nobody can reconcile.

  6. Produce a masked copy for sandbox work

    Data engineer 0.5 day

    Generate a realistic but fake version of the export for testing and for any vendor who needs sample data. Loading real customer PII into a sandbox is a breach in most jurisdictions, and sandboxes are rarely covered by your DPA.

    PII Masker Generate a safe copy for sandbox and vendor testing

Don't move on until

  • Export parses cleanly with no ragged rows or encoding errors
  • PII inventory complete and retention decisions recorded
  • Duplicate and orphan records quantified and triaged
03 Field Mapping Turn two schemas into one signed-off mapping spec. 0/6

Objective A reviewed field-level mapping covering every object, with an explicit decision for every field that has no target.

  1. Generate the first-pass Enchant → Desk365 field map

    Solution architect 2 days

    Start from an automated match on both schemas, then review every row by hand. Automated matching gets the obvious 70% right and is confidently wrong on the rest — especially anything named "type", "status" or "custom_field_1".

    Schema Mapper Opens pre-loaded with the Enchant → Desk365 field pair
  2. Map status, priority and channel values, not just field names

    Support lead 1-2 days

    Enumerate every value in each picklist on both sides and map them explicitly. Value-level mismatches are the defect class that survives all the way to production because the field itself mapped fine — a ticket that should be "Pending" arriving as "Open" reopens SLA clocks.

    Statuses with no target equivalent (on-hold, pending-customer) need a policy decision, not a best guess.

  3. Decide how custom fields land

    Solution architect 2 days

    Create the target custom fields first, matching type exactly (a dropdown mapped to free text can never be mapped back). Where Desk365 has no equivalent, decide between a new custom field, a tag, or a note appended to the ticket body — and record which.

  4. Resolve identity and threading

    Data engineer 1 day

    Decide how source IDs are preserved — most platforms will not let you set the primary key, so keep the original ID in a custom field. Without it, reconciliation becomes fuzzy matching and every future support question about an old ticket is unanswerable.

    Losing the original ticket ID makes reconciliation and rollback effectively impossible.

  5. Plan attachments, inline images and threading order

    Data engineer 1-2 days

    Confirm size limits, allowed MIME types, and whether inline images survive as attachments or need rehosting. Decide the comment ordering and author attribution rules: comments loaded out of order, or all attributed to the API user, destroy the conversation history agents rely on.

  6. Freeze and sign off the mapping spec

    Project manager 1 day

    Version the spec, walk the support lead through it row by row, and get explicit sign-off. Any change after this point goes through change control — mid-flight mapping edits are how partial loads happen.

Enchant → Desk365 specifics

Custom fields and structured data
Enchant has no custom fields on tickets — only flat labels for categorization and a single free-text summary field on customers. Desk365 supports custom ticket fields (dropdowns, text, checkbox, date, number, nested dropdowns), custom ticket types, and categories/subcategories with up to three levels of hierarchy.

Don't move on until

  • Every source field is mapped, deliberately dropped, or parked in a custom field
  • Status, priority and channel value maps agreed with the support lead
  • Mapping spec version-controlled and signed off
04 Test Migration Prove the pipeline on a small, representative slice. 0/6

Objective A pilot load into a Desk365 sandbox that reconciles cleanly and has been reviewed by real agents.

  1. Stand up a Desk365 sandbox that matches production config

    Solution architect 2-3 days

    Create the custom fields, groups, brands, business hours and SLA policies first. A pilot into a default sandbox tests nothing, because the failures you care about are all configuration mismatches.

  2. Pick a deliberately nasty pilot sample

    Data engineer 0.5 day

    Take 500-1000 records chosen for difficulty, not convenience: the longest ticket threads, tickets with the most attachments, non-Latin character sets, merged and split tickets, deleted requesters, and every status value. A clean random sample proves only that easy records are easy.

  3. Run the load with masked data and instrument everything

    Data engineer 1-2 days

    Log every API request and response with its source record ID. When 40 records fail out of 10,000 you need to know exactly which ones and why, without re-running the whole batch.

    PII Masker Never load real customer PII into a sandbox
  4. Measure real throughput against the rate limit

    Data engineer 1 day

    Record achieved records-per-hour under Desk365's actual rate limits, including retries and backoff. Extrapolate to the full volume: if the maths says the full load exceeds your freeze window, you fix that now, not on cutover night.

    Published rate limits are ceilings, not throughput. Assume real-world rates are meaningfully lower once retries and backoff are counted.

  5. Reconcile the pilot and triage every failure

    Data engineer 1-2 days

    Diff source against target on record counts and field-level values. Every discrepancy gets a root cause and a fix — "probably fine" at pilot scale becomes thousands of broken records at full scale.

    Migration Validation Tool Diff the pilot batch against source before scaling up
  6. Put real agents in front of the pilot data

    Support lead 2 days

    Have two or three agents work sample tickets end to end in the sandbox. They find the things reconciliation cannot see: unreadable threading, missing context, macros that no longer make sense. Fix the mapping, then re-run.

Don't move on until

  • Pilot batch reconciles to 100% on record counts
  • Agents have reviewed sample tickets and confirmed they are workable
  • Measured throughput extrapolates to a viable full-load window
05 Cutover Execute the switch inside a controlled, reversible window. 0/6

Objective All in-scope data live in Desk365, agents working in the new system, and a rollback path that stayed available throughout.

  1. Pre-load history before the freeze

    Data engineer 3-10 days

    Load closed tickets and contacts days or weeks ahead while Enchant stays live. Only open tickets and the final delta need to move inside the freeze — this is the single biggest lever on window length.

    Helpdesk Migration Planner Size the freeze window from Desk365's real API limits
  2. Publish the runbook with times, owners and abort criteria

    Project manager 1 day

    A timed sequence: freeze start, final export, delta load, channel switch, smoke test, go/no-go, agent switch. Name who does each step and the explicit condition that triggers a rollback. Decide the abort criteria before the night, when nobody wants to be the one to call it.

  3. Freeze Enchant and take the final delta

    Support ops 2-4 hours

    Stop new ticket creation, let agents finish in-flight replies, then export everything changed since the pre-load. Announce the freeze to the whole business, not just support — someone always tries to raise a ticket during it.

    Tickets created during an unenforced freeze land in the old system and are the most common source of permanently lost data.

  4. Load the delta and open tickets

    Data engineer 2-6 hours

    Run the delta load, then reconcile counts before touching any channel. Do not repoint email until the delta has verified — an inbound ticket arriving mid-load is far harder to untangle than a few extra minutes of freeze.

    Migration Validation Tool Confirm the final delta landed before you reopen
  5. Repoint channels and verify with live traffic

    IT / integrations 2-4 hours

    Switch email forwarding and MX or connector settings, update chat widgets and web forms, and re-authorise integrations. Then send real test tickets through every channel and confirm each lands, routes and triggers the right automation.

    Email forwarding changes can take up to a full DNS TTL to propagate — check the TTL days in advance and lower it if needed.

    Cron Expression Builder Schedule the delta syncs that run through the freeze
  6. Run the go/no-go and switch the agents

    Project sponsor 1-2 hours

    Walk the exit criteria with the decision-maker, call it explicitly, then move agents over with a named person on hand for the first few hours. Keep Enchant read-only rather than cancelled — cancelling the old contract on day one removes your only fallback.

Don't move on until

  • Full historical load complete and counts matched
  • Inbound channels repointed and verified with live test tickets
  • Rollback decision point passed explicitly, not by default
06 Validation Prove the migration is complete, then close it out. 0/6

Objective Documented evidence that data, workflow and reporting all survived, and a signed acceptance.

  1. Run the full reconciliation

    Data engineer 1-2 days

    Compare source and target on every object: total counts, counts by status, counts by group, attachment counts, and field-level spot checks on a random sample. Produce one report you can hand to an auditor.

    Migration Validation Tool Reconcile Enchant and Desk365 record-for-record
  2. Verify field completeness, not just record counts

    Data engineer 1 day

    Re-profile the loaded data and compare null rates per field against the source profile. Matching record counts with a field that silently arrived empty is the failure mode counts alone will never catch.

    Data Profiler Prove field completeness held up through the load
  3. Rebuild reporting and compare against baselines

    Support ops 2-3 days

    Recreate your core dashboards — volume, first response time, resolution time, CSAT — and compare to pre-migration figures for the same period. Explain every variance; a changed SLA calculation is a real finding, not a rounding error.

    SLA and first-response metrics are usually recalculated from the loaded timestamps, so they will differ if any timestamp mapping was approximate.

  4. Test the workflow layer end to end

    Support ops 2 days

    Fire every trigger, automation, SLA escalation, macro and notification with a live ticket. Workflow does not migrate — it gets rebuilt — so it is untested until someone has actually watched it run.

  5. Confirm compliance and produce the audit trail

    Compliance / DPO 1 day

    Re-scan the loaded data for regulated fields, confirm retention and deletion policies are configured in Desk365, and file the evidence with your PII decisions from the audit phase.

    PII & Compliance Scanner Produce the compliance evidence your auditor will ask for
  6. Sign off, then decommission on a schedule

    Project sponsor 1 day

    Get written acceptance against the Discovery success criteria. Keep Enchant read-only for an agreed period (30-90 days is typical), take a final archive export, and only then cancel. Diarise the decommission date so it does not quietly renew.

Don't move on until

  • Full reconciliation report attached to the project record
  • Reporting baselines match pre-migration figures within agreed tolerance
  • Formal acceptance signed and archive retention scheduled

Field mapping reference

The field-by-field mapping for each object. Use this as the starting point for your mapping spec.

Object Equivalent 9 fields
Enchant fieldDesk365 fieldNotes
Inbox Group Enchant routes tickets to inboxes; Desk365 routes to groups. 1:1 mapping works for most setups.
User (agent) Agent Agents must exist in Desk365 before tickets reference them.
Customer Contact Enchant customers carry first_name, last_name, summary, and contacts. Desk365 contacts carry name, email, phone, title, company association, and custom fields.
Contact (email/phone/twitter) Contact email / phone Enchant supports multiple contact types per customer. Twitter handles have no direct Desk365 equivalent.
_(no equivalent)_ Company Desk365 has a dedicated Companies entity. You'll need to decide whether to create companies from email domains or skip this entirely.
Label Category / Subcategory / Type / Custom Field Enchant uses labels for everything. Desk365 has structured fields. A mapping table is required.
Ticket Ticket Core migration object. State and field mapping required.
Message (reply in/out, note) Conversation (contact reply, agent reply, private/public note) Structural transformation needed.
Attachment Attachment Must be downloaded from Enchant and re-uploaded to Desk365 via multipart form.
State Status 5 fields
Enchant fieldDesk365 fieldNotes
open Open Direct map
hold Pending Closest equivalent — both mean "waiting on something"
closed Closed Direct map
snoozed Pending Desk365 has no native snooze. Map to Pending, or create a custom "Snoozed" status. The snoozed_until timestamp will be lost unless stored in a custom field.
archived Closed Archived in Enchant is a terminal state. Map to Closed.
Type Source Value 5 fields
Enchant fieldDesk365 fieldNotes
email 1 (Email) Direct map
chat 13 (Web Widget) Closest match
web 12 (Web Form) Direct map
phone, call 7 (Phone/Other) Direct map
sms, whatsapp, fb_messenger, instagram_dm, twitter, twitter_dm 7 (Phone/Other) No direct Desk365 source for social/messaging channels
Customer Contact 6 fields
Enchant fieldDesk365 fieldNotes
first_name First name Direct map
last_name Last name Direct map
contacts [].value (type: email) Email Primary deduplication key
contacts [].value (type: phone) Phone Direct map
summary Notes or custom field No native Notes field; use a custom text field
contacts [].value (type: twitter) Custom field cf_twitter_handle No native Desk365 equivalent
Enchant Desk365 8 fields
Enchant fieldDesk365 fieldNotes
id custom_fields.cf_enchant_ticket_number Store as string in a custom field for cross-reference
subject subject Direct string map
state status Map using state table above
customer_id contact_email Lookup from your customer→email mapping table
user_id agent_id Lookup from your agent mapping table
type source Map using source table above
labels custom_fields, category, type Apply label mapping table
created_at custom_fields.cf_original_created_at See timestamp note below
Data Volume Extraction (Enchant) 3 fields
Enchant fieldDesk365 fieldNotes
1,000 tickets 1–2 hours 1–2 hours
10,000 tickets 8–12 hours 4–6 hours
50,000 tickets 2–3 days 1 day

Risk matrix

Per-object risk for this pair. Plan extra validation around anything marked high.

ObjectRiskNotes
Tickets medium Core ticket properties migrate reliably via API, but state normalization (snoozed, archived) and priority derivation from labels require custom mapping logic that can silently produce incorrect results if the label mapping table is incomplete.
Conversation History high Full conversation threads with inbound replies, outbound replies, and private/public notes cannot be migrated via CSV and require individual API calls per message in strict chronological order, making this the highest-complexity and highest-failure-risk migration step.
Attachments high Attachments must be downloaded from Enchant and re-uploaded via multipart form to Desk365, and any network interruption, expired Enchant URL, or Desk365 file size limit can result in silently orphaned attachments with no automatic retry.
Contacts medium Enchant customer records map reasonably well to Desk365 contacts, but the free-text summary field has no direct equivalent and Twitter contact handles are not supported in Desk365, resulting in partial data loss for social-channel customers.
Companies high Enchant has no Companies entity, so all company records must be synthesized from customer email domains or skipped entirely, with no authoritative source data to validate against and a risk of incorrect groupings or duplicate company records.
Agents medium Agents must be manually created or synced via Azure AD before migration starts, and any historical tickets referencing departed agents will fail with a 422 error unless an inactive-agent fallback mapping is implemented in advance.
Labels / Custom Fields high Enchant labels are used for all categorization and must be individually mapped to Desk365 ticket types, categories, subcategories, or custom fields; any label omitted from the mapping table will result in silent data loss for that classification.
Ticket Status low Most Enchant states map directly to Desk365 statuses, with the exception of snoozed tickets whose snooze timestamp will be lost unless explicitly stored in a Desk365 custom field prior to migration.
SLA Data medium Enchant SLA rules have no exportable structured equivalent compatible with Desk365 SLA policies, so SLA configurations must be manually recreated in Desk365 before migration and cannot be automated as part of the data transfer.
Social Channel Tickets high Tickets originating from Twitter, Facebook Messenger, Instagram DM, WhatsApp, and SMS have no matching Desk365 source channel and will be remapped to a generic fallback value, losing original channel context unless a custom field is used to preserve it.

The hard parts

What makes this specific migration difficult, beyond the mechanics.

Flat-to-Relational Data Transformation

Enchant's label-based flat structure must be decomposed and mapped to Desk365's relational entities including ticket types, categories, subcategories, and custom fields before any import can begin.

Conversation Thread Reconstruction

Enchant messages (inbound replies, outbound replies, and notes) must be individually transformed and re-posted to Desk365 in ascending chronological order to preserve conversation history, as the Desk365 CSV importer cannot reconstruct full threads.

Attachment Re-Upload Requirement

Attachments cannot be referenced by URL; they must be downloaded from Enchant's storage and re-uploaded to Desk365 via multipart form POST, requiring additional API calls and significantly increasing migration time.

Missing Priority and Channel Fields

Enchant tickets have no priority field and map social channel sources (Twitter, WhatsApp, Instagram DM, Facebook Messenger, SMS) to no direct Desk365 equivalent, requiring default values or custom field workarounds to avoid data loss.

Strict Dependency Ordering

Desk365 rejects ticket creation if referenced Agents, Contacts, Groups, or Companies do not already exist, requiring a strict sequential creation order and inactive-agent handling strategy before ticket import begins.

Enchant API Rate Limit Constraints

Enchant enforces a 100-credit-per-minute limit with a 6-request-per-second burst cap, meaning a 10,000-ticket extraction with embedded messages can take 4–8 hours and requires robust exponential backoff and resumability logic.

Tools used in this playbook

All free, all run entirely in your browser — nothing is uploaded.

FAQ

Can I migrate Enchant tickets to Desk365 using CSV import?

Desk365's CSV import handles basic ticket properties and contacts, but it cannot import full conversation threads, notes, or attachments. For a complete migration with history preserved, you need the Desk365 API (v3).

What are the Desk365 API rate limits for migration?

Desk365 rate limits are plan-specific: Standard plan allows 100 API calls per hour, Plus and Premium plans allow 50 API calls per minute. The Standard plan limit is too restrictive for most migrations — upgrade to Plus or Premium during the migration window.

How do Enchant labels map to Desk365 fields?

Enchant uses flat labels for all categorization. In Desk365, you map labels to structured fields: Category, Subcategory, Type, Priority, or custom fields. Build a mapping table before migration and create the corresponding Desk365 structures first.

What happens to tickets assigned to agents who no longer work here?

Desk365 requires a valid agent ID for assignment. You must either create a dummy 'Migration Archive' agent profile in Desk365 to hold these historical tickets or map them to an active administrator's account.

Does Desk365 preserve original ticket timestamps during migration?

By default, the Desk365 API sets created_on to the time of the API call, not the original Enchant timestamp. Check with Desk365 support about overriding timestamps, or store the original timestamp in a custom field or message body.

Or skip all of this and let us handle it

Book a 30-minute call and we'll scope your migration in a single session.