Skip to content

FuseDesk to Enchant Migration: A Technical Guide

A technical guide to migrating from FuseDesk to Enchant — covering API constraints, object mapping, dependency order, rate limits, and edge cases.

Abdul Abdul · · 13 min read
FuseDesk to Enchant Migration: A 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

Moving from FuseDesk to Enchant means shifting from a CRM-centric helpdesk — built around Keap/Infusionsoft contact records, departments, and case history — to a lightweight, inbox-centric shared inbox where tickets, labels, and customers are the organizing primitives. While both platforms resolve customer issues, their data models, API behaviors, and structural dependencies are entirely different.

The core engineering challenge is extracting FuseDesk's tightly coupled CRM data through its API and restructuring it for Enchant's flatter, more minimal data model without losing conversation history or customer context.

At ClonePartner, we've executed over 1,500 migrations, and we consistently see teams underestimate the complexity of decoupling helpdesk data from a CRM. Enchant is intentionally minimal — it focuses on speed, conversation flow, and inbox management rather than functioning as a pseudo-CRM. This guide covers the object mapping, extraction strategy, dependency order, API constraints on both sides, and the edge cases that break naive migrations.

Why Teams Move from FuseDesk to Enchant

FuseDesk is purpose-built for the Keap and Infusionsoft ecosystem. If your team is leaving that CRM ecosystem — or simply wants a standalone helpdesk without the CRM dependency — Enchant's multi-channel shared inbox is a natural fit. Enchant supports email, live chat, SMS, WhatsApp, social messaging, and a knowledge base, all without requiring a specific CRM backend.

The typical trigger: the team has outgrown Keap, switched CRMs, or wants a helpdesk that works independently of any specific CRM vendor.

Define Your Migration Scope

Before writing any code, map out what moves programmatically, what gets rebuilt manually, and what you leave behind.

Migrate via API:

  • Departments → Inboxes
  • Reps → Users (manual invite + ID mapping)
  • Contacts → Customers
  • Cases → Tickets
  • Case history (emails, notes, calls) → Messages
  • Case Tags → Labels

Rebuild manually in Enchant:

  • Canned responses / email templates / note templates
  • Automation rules and workflows
  • Knowledge base content
  • SLA policies
  • Business hours

Will not transfer:

  • CRM-specific data (Infusionsoft Contact IDs, Company IDs, CRM tags, campaign links)
  • FuseDesk snippets and template merge fields
  • Webhook configurations
  • Chat widget settings
  • Third-party app integrations (Zapier zaps, WordPress plugin config)
Warning

CRM data loss is the biggest risk. FuseDesk stores Infusionsoft/Keap Contact IDs and Company IDs on every case and contact. Enchant has no equivalent CRM linkage. If you need to preserve this association, write the CRM IDs into the Enchant customer summary field or maintain an external mapping table before you begin.

Check your FuseDesk data retention settings before starting. FuseDesk PRO and Enterprise plans support automatic archival, anonymization, and deletion of cases, chats, contacts, and emails. Anonymized records will have PII scrubbed — names, emails, and phone numbers are irreversibly removed. If your data has been anonymized, those records cannot be meaningfully migrated.

Object Mapping: FuseDesk → Enchant

The data models are structurally different. Here is the field-level mapping for each core object.

Departments → Inboxes

FuseDesk Field Enchant Field Notes
departmentid inbox_id Store mapping for ticket import
name Inbox name Set during Enchant inbox setup
repids Enchant doesn't restrict users to inboxes via API

FuseDesk departments include a list of assigned rep IDs. Enchant inboxes don't enforce rep membership via the API — any user can be assigned to a ticket in any inbox. Create your Enchant inboxes through the admin UI before migration and build a departmentid → inbox_id lookup.

Reps → Users

FuseDesk Field Enchant Field Notes
repid user_id Map for ticket assignment
Rep name first_name, last_name
Rep email email

Enchant does not expose a user creation endpoint in its public API. Invite agents manually through the Enchant admin UI, then pull the user list via GET /api/v1/users and build a repid → user_id mapping table. This step must happen before any ticket import.

Warning

Identity mapping is non-negotiable. When you create a ticket or message in Enchant via the API, you must specify the user_id of the author. If you fail to map a former FuseDesk Rep who is no longer with the company, your script will either fail or default to assigning those historical replies to your API admin account, destroying historical accuracy. For deleted reps, create a placeholder "Legacy Agent" user in Enchant and map their ID to preserve the visual context of a staff reply.

Contacts → Customers

FuseDesk Field Enchant Field Notes
contactid / contactUuid customer_id
Name (from CRM) first_name, last_name
Email contacts [].value (type: email)
Phone contacts [].value (type: phone)
Infusionsoft Contact ID summary Preserve as reference
Company ID summary No native company field in Enchant

FuseDesk contacts are deeply tied to your CRM. In Enchant, customers are standalone records with a summary free-text field — use this to stash CRM IDs or other metadata you need to preserve.

Enchant supports email, twitter, and phone contact types. Any FuseDesk contact channels outside these three (SMS handles, social media IDs stored in the CRM) will need to be stored in the summary field or dropped.

Cases → Tickets

FuseDesk Field Enchant Field Notes
caseid client_id Use for idempotency
summary subject
status (new, open, closed) state (open, hold, closed) Map newopen
depid inbox_id Use department mapping
repid user_id Use rep mapping
contactid customer_id Use contact mapping
date_opened created_at Override default timestamp
casetags label_ids Use label mapping

Enchant's API only allows ticket creation with type set to email. Other FuseDesk case origins (phone calls, live chat) will all be imported as email-type tickets. Preserve the original channel in a label (e.g., original:phone) or as a note on the ticket if you need to track it.

Info

Status mapping detail: FuseDesk uses three statuses — new, open, and closed. Enchant supports open, hold, closed, snoozed, and archived. Map FuseDesk new and open to Enchant open, and closed to closed. If you want to distinguish "waiting on customer" cases, use Enchant's hold state, but FuseDesk doesn't have a native equivalent — you'd need to identify these from case tags or CRM data.

Case History → Messages

FuseDesk case history is a mix of emails, notes, and call logs. Enchant messages are either reply (inbound or outbound) or note.

FuseDesk History Type Enchant Message Type Notes
email (inbound) reply (direction: in)
email (outbound) reply (direction: out) Requires user_id
note note Requires user_id
call note No call type in Enchant — prepend " [Phone Call]" to body

For outbound replies and notes, user_id is required. Sort messages strictly by their original creation date (oldest first). If you insert them out of order, the conversation history will be unreadable.

Case Tags → Labels

FuseDesk case tags map directly to Enchant labels. Fetch all case tags via FuseDesk's /api/v1/casetags/ endpoint. Enchant does not expose a label creation endpoint in the public API — create them through the Enchant admin UI, then retrieve their IDs via the API for use during ticket import.

For a migration, it is generally safer to create labels as account-wide rather than inbox-specific.

Extraction: Getting Data Out of FuseDesk

FuseDesk's API authenticates via API key passed in the X-FuseDesk-API-Key header. You'll need admin access to create a key with full read permissions under Settings → API Keys.

FuseDesk Rate Limits

FuseDesk enforces an hourly rate limit. The API response headers include X-FuseDesk-Usage-Limit (typically 1,800 calls/hour) and X-FuseDesk-Usage-Remaining. Build a backoff strategy that checks remaining calls and pauses before hitting zero.

Extraction Order

  1. DepartmentsGET /api/v1/departments/all (returns active and archived)
  2. RepsGET /api/v1/reps/
  3. Case TagsGET /api/v1/casetags/
  4. CasesGET /api/v1/cases/ with pagination (limit max 500, offset-based)
  5. Case detail + historyGET /api/v1/cases/{CASEID} per case
  6. Contacts — Extracted from case data (linked via contactid)

Pagination and Extraction Code

FuseDesk case search supports limit (max 500) and offset parameters. Page through all cases:

import requests
import time
 
FUSEDESK_APP = "yourappname"
API_KEY = "your_api_key"
BASE_URL = f"https://{FUSEDESK_APP}.fusedesk.com/api/v1"
HEADERS = {"X-FuseDesk-API-Key": API_KEY}
 
def fetch_all_cases():
    all_cases = []
    offset = 0
    limit = 500
    while True:
        resp = requests.get(
            f"{BASE_URL}/cases",
            headers=HEADERS,
            params={"limit": limit, "offset": offset, "status": "all"}
        )
        resp.raise_for_status()
        remaining = int(resp.headers.get("X-FuseDesk-Usage-Remaining", 100))
        if remaining < 50:
            time.sleep(120)  # back off before exhausting limit
        cases = resp.json()
        if not cases:
            break
        all_cases.extend(cases)
        offset += limit
    return all_cases

Each case's conversation history is returned when you GET /api/v1/cases/{CASEID}. The response includes the full history array with emails, notes, and calls. This is where most of your API calls go — one per case — so plan for rate limiting on large accounts.

Tip

Batch extraction tip: If you have 5,000+ cases, the per-case detail fetch alone consumes 5,000+ API calls. At 1,800/hour, that's nearly 3 hours just for extraction. Run extraction overnight and store results locally as JSON before starting the import.

Loading: Importing Data into Enchant

Enchant's REST API authenticates via bearer token. Get your token by installing the API app from the Enchant settings panel.

Enchant Rate Limits

Enchant enforces 100 credits per minute across all endpoints, tokens, and users for the entire account. A basic request costs 1 credit. There's also a burst limit of 6 requests per second. At full throughput, you can sustain roughly 90–95 meaningful requests per minute.

For a migration of 10,000 tickets with an average of 3 messages each, you're looking at:

  • 10,000 customer creates/lookups
  • 10,000 ticket creates
  • 30,000 message creates
  • Attachment uploads on top of that

That's 50,000+ API calls at ~90/minute — about 9+ hours of import time.

Monitor the HTTP headers in Enchant's responses:

  • X-RateLimit-Limit: Total requests allowed in the current window
  • X-RateLimit-Remaining: Requests left
  • X-RateLimit-Reset: Unix timestamp when the limit resets

If you hit a 429 Too Many Requests error, your script must catch the exception, read the X-RateLimit-Reset header, pause execution, and retry the exact same request. Do not drop the request, or you will have missing data.

Import Order (Dependency Chain)

Helpdesk migrations are strictly hierarchical. You cannot create a ticket until the customer exists. You cannot create a message until the ticket exists. Follow this order:

  1. Users — Invite manually, then fetch IDs via GET /api/v1/users
  2. Labels — Create in Enchant admin UI
  3. Inboxes — Create in admin UI, then get IDs
  4. CustomersPOST /api/v1/customers
  5. Tickets with initial messagesPOST /api/v1/tickets with inline messages array
  6. Remaining messagesPOST /api/v1/tickets/{id}/messages
  7. Ticket state updatePATCH /api/v1/tickets/{id} to set final status and labels

Creating Customers

Query FuseDesk contacts and push each to Enchant:

{
  "first_name": "Jane",
  "last_name": "Doe",
  "contact_points": [
    {
      "type": "email",
      "value": "jane.doe@example.com"
    }
  ]
}

Store the returned Enchant customer_id against the FuseDesk contactid in your mapping table.

Creating Tickets with Messages

Enchant supports creating a ticket with an initial set of messages in a single API call — your most efficient import path:

import requests
 
ENCHANT_SITE = "yoursite"
ENCHANT_TOKEN = "your_bearer_token"
ENCHANT_BASE = f"https://{ENCHANT_SITE}.enchant.com/api/v1"
ENCHANT_HEADERS = {
    "Authorization": f"Bearer {ENCHANT_TOKEN}",
    "Content-Type": "application/json"
}
 
def create_ticket(customer_id, inbox_id, subject, messages, user_id=None, label_ids=None):
    payload = {
        "type": "email",
        "subject": subject,
        "customer_id": customer_id,
        "inbox_id": inbox_id,
        "messages": messages
    }
    if user_id:
        payload["user_id"] = user_id
    resp = requests.post(
        f"{ENCHANT_BASE}/tickets",
        headers=ENCHANT_HEADERS,
        json=payload
    )
    resp.raise_for_status()
    ticket = resp.json()
    if label_ids:
        requests.patch(
            f"{ENCHANT_BASE}/tickets/{ticket['id']}",
            headers=ENCHANT_HEADERS,
            json={"label_ids": label_ids}
        )
    return ticket

Preserving Timestamps

By default, creating a ticket via API uses the current server time as the creation date. This ruins historical reporting. Pass the created_at parameter in your ticket and message payloads to override this with the original FuseDesk timestamps.

Idempotency

Network requests fail. If your script crashes halfway through 50,000 tickets, you need to restart without creating duplicates. Enchant supports idempotency via the client_id parameter — pass the FuseDesk caseid as the client_id. If Enchant sees a creation request with a client_id it already has, it will return the existing ticket instead of creating a duplicate.

Handling Attachments

Attachments are the most resource-intensive part of any migration. You cannot pass a FuseDesk URL to Enchant — those URLs will break once you deprecate FuseDesk or if they require authentication.

FuseDesk's API does not expose a dedicated attachment download endpoint for case history items. You may need to extract attachments from your CRM or email system directly.

On the Enchant side, upload attachments via POST /api/v1/attachments as Base64-encoded data, then reference the returned ID when creating the message:

import base64
 
def upload_attachment(file_path, file_name, mime_type):
    with open(file_path, "rb") as f:
        encoded = base64.b64encode(f.read()).decode("utf-8")
    resp = requests.post(
        f"{ENCHANT_BASE}/attachments",
        headers=ENCHANT_HEADERS,
        json={"name": file_name, "type": mime_type, "data": encoded}
    )
    resp.raise_for_status()
    return resp.json()["id"]
Warning

Base64 encoding inflates file size by ~33%. Large attachments will hit HTTP payload limits. Test with your largest files early. Write exception handling to catch upload errors, log the failed attachment, and append a text note to the ticket indicating an attachment was dropped.

The Custom Field Workaround

Enchant does not support custom fields on tickets. If your FuseDesk instance relies on custom fields pulled from Keap or ActiveCampaign (e.g., "Subscription Tier", "Churn Risk", "Last Order Date"), you have two options:

Option A: The Label Method. If the custom field has a limited set of discrete values (e.g., "Tier: Gold", "Tier: Silver"), map these to Enchant Labels. This preserves filterability.

Option B: The Internal Note Method. If the custom field contains unique string data (e.g., "Order ID: 12345"), compile all custom fields into a single formatted HTML block and inject it as the very first internal note on the Enchant ticket. This keeps the data searchable and visible to the agent without requiring native custom fields.

Edge Cases That Break Migrations

Deleted or anonymized FuseDesk data. If FuseDesk's data retention settings have anonymized records, PII is irreversibly scrubbed. Email addresses and names are gone. These contacts can't be matched or meaningfully recreated in Enchant.

HTML vs. plain text. FuseDesk case history emails may include body as plain text. Enchant messages support HTML via the htmlized field. Set htmlized: false for plain text imports, or htmlized: true if you have stored HTML versions.

Tickets over 10,000. Enchant's ticket listing endpoint warns that retrieving more than 10,000 total tickets requires iterating using since_created_at instead of page-based pagination. This applies during verification — not import — but plan your validation queries accordingly.

CRM merge fields in templates. FuseDesk email templates and note templates use CRM merge fields (e.g., Keap contact fields). These will not function in Enchant. Rebuild all templates from scratch.

Channel type loss. Enchant's API only allows ticket creation with type set to email. Phone calls and live chat cases from FuseDesk will all become email-type tickets. Add a label like original:phone or original:chat to preserve the original channel.

CRM integrations do not carry over. Because Enchant is a separate platform, you will need to re-authenticate and configure any Keap, ActiveCampaign, or other CRM integrations natively within Enchant after the migration is complete.

Delta Migration: The Cutover Strategy

Moving tens of thousands of tickets takes time — often several days due to rate limits and attachment downloads. You cannot freeze support operations while waiting.

The solution is a delta migration:

  1. Initial sync: Run the full migration script up to the current date. Your team continues working in FuseDesk.
  2. The delta: Once the initial sync completes, run a modified script that queries FuseDesk only for cases created or modified after the start date of your initial sync.
  3. Cutover: Pick a low-traffic window (e.g., Friday night). Run the final delta sync. Change your DNS/email forwarding rules to point to Enchant.
  4. Go live: Your team logs into Enchant. All historical data is present, and new emails are flowing in.

Validation and Verification

Do not rely on "script finished successfully." Validate the data.

  1. Ticket counts — Compare total cases extracted from FuseDesk against total tickets in Enchant using GET /api/v1/tickets?count=true.
  2. Message counts — Spot-check 50+ tickets across different size buckets. Verify message counts match case history lengths.
  3. Attachment integrity — Can files be downloaded from Enchant?
  4. Customer deduplication — Verify no duplicate customer records were created.
  5. Label accuracy — Confirm case tags mapped correctly to labels.
  6. State accuracy — Verify closed FuseDesk cases show as closed in Enchant, not left open from the creation step.
  7. Author accuracy — Did messages map to the correct users, or did they fall back to the API admin?
Tip

Run a dry-run first. Import 50–100 cases into a test Enchant instance before doing the full migration. This catches mapping errors, encoding issues, and rate-limit surprises before they affect production data.

Migration Timeline Estimate

Account Size Cases Estimated Extraction Estimated Import Total
Small < 1,000 < 1 hour 2–3 hours Half a day
Medium 1,000–10,000 1–6 hours 10–20 hours 1–2 days
Large 10,000+ 6+ hours 2–4 days 3–5 days

These estimates assume rate-limit-aware scripting with proper backoff. Attachments can double the import time.

When to Call in Help

If your FuseDesk account has deep Keap/Infusionsoft integration with thousands of contacts, heavy case history, and compliance requirements around data completeness, this is not a weekend project. The dual rate-limit bottleneck (1,800/hour on FuseDesk, 100/minute on Enchant) makes large migrations slow and error-prone without purpose-built tooling.

At ClonePartner, we've handled 1,500+ helpdesk migrations and built reusable extraction and loading pipelines that handle rate limiting, deduplication, attachment transfer, and data validation automatically.

Frequently Asked Questions

Can I migrate FuseDesk cases to Enchant automatically?
Yes, but only via custom scripts using both APIs. There is no native import tool. You extract cases from FuseDesk's REST API and create tickets in Enchant's REST API, respecting both platforms' rate limits.
What data is lost when migrating from FuseDesk to Enchant?
CRM-specific data is the biggest loss — Infusionsoft/Keap Contact IDs, Company IDs, CRM tags, campaign links, and merge-field templates have no Enchant equivalent. Chat widget configs, Zapier integrations, and automation workflows also don't transfer.
Can I migrate custom fields from FuseDesk to Enchant?
Enchant does not support custom fields on tickets. You must either map discrete custom field values to Enchant Labels or inject the custom data as an internal note on the migrated ticket.
How long does a FuseDesk to Enchant migration take?
A small account (under 1,000 cases) can be migrated in half a day. Medium accounts (1,000–10,000 cases) typically take 1-2 days. Large accounts with 10,000+ cases and attachments can take 3-5 days due to API rate limits on both sides.
How do I handle attachments during the migration?
FuseDesk doesn't expose a dedicated attachment download endpoint, so you may need to extract files from your CRM or email system. On the Enchant side, upload files as Base64-encoded data via the attachments API, then reference the returned ID when creating the message.

More from our Blog