Skip to content

The Complete Guide to Migrating from Enchant to Help Scout

Migrating from Enchant to Help Scout? Learn the exact API sequence to map customers, transfer conversation threads, and handle attachments with zero data loss

Tejas Mondeeri Tejas Mondeeri · · 6 min read
The Complete Guide to Migrating from Enchant to Help Scout
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

Making the switch from Enchant to Help Scout requires a clear technical plan. This guide focuses on using the available APIs to ensure your historical context remains intact while you transition to your new workspace.

Define Your Migration Scope

Most of your high-volume data — tickets, messages, customers, and attachments — can be handled programmatically. These objects have clear counterparts in both systems.

Certain structural elements require manual setup before the migration begins:

  • Users: Help Scout's API manages existing users rather than creating new ones, so team members must be added manually with correct permissions.
  • Mailboxes (Inboxes): Every Enchant ticket belongs to an inbox. You must recreate these as mailboxes in Help Scout before migration so you can map inbox_idmailboxId during import.

For data that is no longer relevant — old spam, expired drafts — archive it in Enchant before you begin rather than carrying noise into Help Scout.

Data Schema: Enchant → Help Scout Field Mapping

The table below shows the core object and field mapping between the two platforms.

Enchant Object Enchant Field / Endpoint Help Scout Equivalent Help Scout Field / Endpoint Notes
Ticket GET /tickets Conversation POST /v2/conversations Status, subject, created_at map directly
Inbox inbox_id Mailbox mailboxId Must be pre-created manually
Message (reply) type: reply Thread POST /v2/conversations/{id}/reply Customer-facing
Message (note) type: note Thread (note) POST /v2/conversations/{id}/notes Internal only
Customer GET /customers Customer POST /v2/customers Multiple contacts (email, phone) map to Help Scout's contact array
Label label_id Tag tags [] on conversation String-based in Help Scout
Attachment GET /attachments/{id} Attachment POST /v2/attachments → returns attachmentId Must be pre-uploaded; one attachment per message

Known gaps — data with no direct API equivalent in Help Scout:

  • Collision detection settings (no equivalent object)
  • Enchant workflow trigger types that depend on Enchant-specific ticket states
  • Enchant's credit-weighted action log (no equivalent audit trail object)

If you cannot map a field, document it explicitly before the migration runs. Dropping it silently creates invisible data loss.

Migration Sequence

Order matters. Creating a thread before the parent customer record exists will produce orphaned or failed records. Follow this dependency chain:

1. Customers          → POST /v2/customers
2. Attachments        → POST /v2/attachments (capture returned attachmentId)
3. Conversations      → POST /v2/conversations (reference customerId + mailboxId)
4. Threads            → POST /v2/conversations/{id}/reply or /notes
                        (embed attachmentId captured in step 2)
5. Tags               → PATCH /v2/conversations/{id} (apply tag array)

Pseudocode: attachment-safe thread creation

for ticket in enchant_tickets:
    customer_id = upsert_customer(ticket.customer)       # Step 1
 
    attachment_ids = []
    for attachment in ticket.attachments:
        result = helpscout.post('/v2/attachments', {
            'fileName': attachment.filename,
            'mimeType': attachment.mime_type,
            'data': base64_encode(attachment.content)
        })
        attachment_ids.append(result['attachmentId'])    # Step 2
 
    conversation_id = helpscout.post('/v2/conversations', {
        'subject': ticket.subject,
        'mailboxId': inbox_id_map[ticket.inbox_id],
        'customer': {'id': customer_id},
        'status': map_status(ticket.status),
        'createdAt': ticket.created_at
    })['id']                                             # Step 3
 
    for message in ticket.messages:
        endpoint = '/reply' if message.type == 'reply' else '/notes'
        helpscout.post(f'/v2/conversations/{conversation_id}{endpoint}', {
            'body': message.body,
            'isHtml': message.html,                     # Enchant boolean field
            'attachments': attachment_ids if message.has_attachments else []
        })                                               # Step 4
 
    helpscout.patch(f'/v2/conversations/{conversation_id}', {
        'tags': [label_map[l] for l in ticket.labels]
    })                                                   # Step 5

Rate Limits and Volume Planning

Both APIs throttle requests, and a large migration will hit those limits without pacing logic.

Enchant uses a credit-based system. Each API call costs credits against a limit of 100 credits per minute. Operations that embed or count related objects (e.g., fetching a ticket with ?embed=messages,attachments) consume more credits than a plain fetch.

Help Scout uses a request-count limit per rolling window. The exact limit depends on your plan and the number of active mailboxes. Monitor the X-RateLimit-Remaining and X-RateLimit-Reset response headers on every call — they tell you how many requests remain in the current window and when it resets.

Volume estimate for planning purposes:

Operation API Calls per 1,000 Tickets (estimate)
Customer upsert 1,000 (one per unique customer)
Attachment upload Varies; assume 2–4 per ticket average = 2,000–4,000
Conversation create 1,000
Thread create 3–8 per ticket average = 3,000–8,000
Tag apply 1,000
Total ~8,000–15,000 calls per 1,000 tickets

For a 10,000-ticket migration, budget 80,000–150,000 API calls. At Enchant's 100-credit/minute ceiling, the export phase alone can take 14+ hours without parallelism or credit-efficient embedding. Build sleep/retry logic around the rate limit headers from day one.

Failure Modes and Error Handling

This is where most migrations break silently.

Attachment upload fails mid-migration: If POST /v2/attachments returns an error, do not proceed to thread creation for that message. Log the failed attachment with its Enchant ID, skip it, and queue it for retry. Creating the thread without the attachment ID means the attachment is permanently lost with no indication in the Help Scout record.

Conversation creation fails: If the POST /v2/conversations call fails (e.g., invalid mailboxId, missing customer), log the full Enchant ticket ID and payload. Do not attempt to create threads for that conversation — they will have no parent and the API will reject them anyway.

Enchant HTML boolean: Enchant tracks whether a message body is HTML via a boolean field on the message object. If your migration script ignores this and sends HTML content as plain text (or vice versa), the thread body will render as broken markup in Help Scout. Read this field explicitly and pass isHtml: true/false on every thread creation call.

Attachment re-use: An attachment uploaded to Help Scout is linked to a single message. If the same file appears on multiple Enchant messages, you must upload it separately for each thread. Attempting to reuse the same attachmentId across threads will produce errors or missing files.

Retry logic: Use exponential backoff on any 429 (rate limited) or 5xx (server error) response. A simple retry without backoff will continuously hit the rate limit ceiling and stall indefinitely.

Post-Migration Configuration

After data transfer completes, rebuild the following manually inside Help Scout:

  • Workflows: Automation logic must be recreated in the Help Scout interface. The API does not support programmatic workflow creation.
  • Saved replies: Recreate these manually. The API can read them but the content is best reviewed and updated during the rebuild.

Validation Checklist

Do not close the migration until you have verified the following:

  • Total conversation count in Help Scout matches total ticket count exported from Enchant
  • Spot-check 20–30 conversations: confirm thread count, attachment count, and tag labels match source records
  • Confirm internal notes are marked as notes (not customer-visible replies) in Help Scout
  • Verify at least one attachment per mailbox opens correctly
  • Check timestamp alignment: createdAt on Help Scout conversations should match created_at on Enchant tickets
  • Confirm no customer records are duplicated (check by email address)
  • Verify tag strings match the label names from Enchant (casing differences can create duplicate tags)

If you'd rather focus on your revenue instead of wrestling with mapping sheets and pagination loops, ClonePartner can handle the full migration for you. Every project gets a dedicated engineer who understands the nuances of both APIs and ensures zero downtime.

Further Reading:

More from our Blog

Unthread to HappyFox Migration: A Technical Guide
Unthread/HappyFox/Migration Guide

Unthread to HappyFox Migration: A Technical Guide

A step-by-step technical guide for migrating from Unthread to HappyFox. Covers API extraction, data model mapping, rate limits, edge cases, and validation.

Raaj Raaj · · 22 min read