Skip to content

Dixa to Salesforce Service Cloud Migration: Technical Guide

Technical guide to migrating from Dixa to Salesforce Service Cloud — covering API extraction, data mapping, field limits, Bulk API loading, and workflow rebuild.

Nachi Nachi · · 20 min read
Dixa to Salesforce Service Cloud Migration: 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

Dixa to Salesforce Service Cloud Migration: Technical Guide

Info

TL;DR — Dixa to Salesforce Service Cloud Migration

Dixa conversations export via the Exports API (31-day query windows, 10 requests/second per token). The critical mapping decision: store conversation history as EmailMessages (up to 131,072 characters by default, configurable to 384,000) rather than CaseComments (hard 4,000-character truncation — silent, no error returned). Dixa's flat conversation model must be translated into Salesforce's Account → Contact → Case hierarchy. Preserving historical timestamps requires enabling "Set Audit Fields upon Record Creation" (org-level Setup) and assigning the "Set Audit Fields" user permission to the API user's profile or permission set — both steps are required. Dixa's Flow Builder logic must be rebuilt across Salesforce's distributed configuration model (Assignment Rules, Omnichannel Routing, Entitlement Processes, Flow Builder). Voice recordings should be offloaded to external storage (AWS S3) with URLs mapped to Cases. Use Salesforce Bulk API 2.0 for the data load — it handles up to 100 million records per 24-hour period and doesn't consume your org's REST API quota. Realistic timeline: 3–6 weeks depending on volume and Flow complexity.

A Dixa to Salesforce Service Cloud migration moves your operations from a specialized, real-time routing platform into an enterprise CRM. Teams undertake this because the rest of the organization already runs on Salesforce, and maintaining a separate data silo for support creates reporting blind spots, duplicate contact records, and integration overhead.

The data transfer is manageable — Dixa's APIs stream conversation and message data in JSON. But the target side has real constraints: CaseComment bodies cap at 4,000 characters with silent truncation, CreatedDate is read-only by default and requires two separate configuration steps to override, and Salesforce governor limits affect large-scale inserts in ways that aren't obvious until you hit them. The workflow redesign is the harder half: Dixa's single-canvas Flow Builder must be decomposed into Salesforce triggers, assignment rules, escalation rules, SLA policies, and Omnichannel Routing configurations.

This guide covers the architectural differences, API constraints, data mapping, transformation logic, load strategy, failure modes, and cutover plan required to execute this migration accurately.

For a deep dive into extracting data from Dixa, see How to Export Data from Dixa: Methods, API Limits & Data Mapping. For Salesforce import strategies, see How to Export Data from Salesforce Service Cloud: Methods & Limits. If you are evaluating Zendesk as an alternative target, see our Dixa to Zendesk Migration Guide.

Why Teams Migrate from Dixa to Salesforce Service Cloud

The move is driven by concrete architectural constraints, not preference:

  • CRM consolidation. Running Dixa alongside Salesforce creates duplicate contact records, broken pipeline-to-support reporting, and manual data syncing. Service Cloud resolves this by putting support, sales, and success data on a single customer record.
  • Enterprise reporting. Salesforce Reports and Dashboards support cross-object joins and custom report types. Dixa's analytics are conversation-scoped; they cannot join to opportunity or account data without an external integration.
  • Compliance requirements. Salesforce offers HIPAA BAA eligibility, FedRAMP authorization (Government Cloud), and Shield Platform Encryption. Dixa holds SOC 2 Type II and GDPR compliance but does not publicly offer HIPAA or FedRAMP paths.
  • Platform extensibility. Salesforce AppExchange offers thousands of managed packages with native data access. Dixa's integration ecosystem is smaller and requires webhook-based data extraction.
  • AI depth. Salesforce Einstein for Service — case classification, next-best-action, article recommendations — operates across your full CRM dataset. Dixa's automation is strong within conversations but doesn't extend to CRM-wide context.

Architectural Differences That Shape the Migration

Three structural gaps between Dixa and Salesforce define the migration complexity.

Offer-Based Routing vs. Omnichannel Routing

Dixa pushes conversations to agents in real time based on availability, skills, and priority. Salesforce Omnichannel Routing is conceptually similar but requires explicit setup: Service Channels, Routing Configurations, Presence Statuses, and either queue-based or skill-based routing rules.

Omnichannel supports two routing models:

  • Least Active — Routes to the agent with the fewest open work items. Best for chat and case workloads.
  • Most Available — Routes to the agent with the most remaining capacity relative to their configured capacity. Better for high-volume environments where capacity weighting matters.

To replicate Dixa's priority-weighted routing, set the Priority value on each Routing Configuration (lower number = higher priority) and configure queue capacity limits to control maximum concurrent work items per agent. Dixa's automatic priority escalation (conversations that age in queue gain priority) maps to Salesforce's Escalation Rules combined with flow-based field updates on the Case's Priority field.

Flow Builder vs. Distributed Configuration

Dixa's Flow Builder is a visual canvas where queue assignment, IVR trees, auto-replies, priority rules, and escalation paths exist in a single interface. In Salesforce, the same logic spans multiple objects: Assignment Rules, Escalation Rules, Entitlement Processes, Salesforce Flow Builder, Apex Triggers, and Omnichannel Routing Configurations. Expect the workflow rebuild to consume 40–60% of your total migration effort — this estimate reflects the decomposition of a single Dixa Flow that may contain 15–20 decision nodes into 4–6 separate Salesforce configuration objects.

Native Voice vs. Service Cloud Voice

Dixa includes native telephony — phone, IVR, callback queuing, and call recording built in. Salesforce requires Service Cloud Voice (an add-on SKU built on Amazon Connect) or a third-party CTI adapter. You cannot natively play back historical Dixa call recordings inside a Salesforce Case without custom development. Budget for Service Cloud Voice setup and licensing separately if your team uses Dixa telephony.

Data Hierarchy: Flat vs. Relational

Dixa is flat: a User has Conversations. Salesforce is relational: an Account has Contacts, Contacts have Cases, Cases have CaseComments, EmailMessages, and ContentVersions. Every data mapping decision flows from this structural difference—a challenge common to other flat-to-relational moves like migrating from Intercom to Salesforce Service Cloud.

Dixa to Salesforce Data Mapping

Dixa Object Salesforce Object Notes
Conversation Case One conversation = one Case. Status mapping required (open/pending/closed → picklist values).
Message (inbound/outbound) EmailMessage Preferred over CaseComment — supports HTML, up to 131K characters default, preserves sender/recipient.
Internal Note CaseComment (IsPublished=false) Or FeedItem on Case (Chatter). 4,000-character limit on CaseComment applies here too.
End User (contact) Contact Map email, phone, name. Link to Account if org uses Account hierarchy.
Agent User Match by email. Salesforce Users must exist before Case import.
Queue Queue Configured in Setup. Map Dixa queue names to Salesforce Queue DeveloperNames.
Tag Case Topic or Custom Field Topics allow multiple tags per record. Tags indicating specific processes (e.g., "Refund Requested") should map to custom fields for reporting.
Custom Attribute (conversation) Custom Field on Case Text → Text, Select → Picklist.
Custom Attribute (end user) Custom Field on Contact Same approach.
CSAT Rating Custom Number Field on Case Salesforce has no native CSAT field. Create CSAT_Score__c (Number) and CSAT_Date__c (Date).
Conversation Wrap-Up Note CaseComment or Custom Field Wrap-up notes are separate from message-level internal notes in Dixa's data model.
Attachment ContentVersion → ContentDocumentLink Files use the ContentVersion/ContentDocument model. Link via ContentDocumentLink to parent Case.
Knowledge Article Knowledge__kav Requires Record Types and Data Categories setup before import. PublishStatus must be set explicitly or articles import as Drafts.

Users to Contacts and Accounts

Dixa End Users map to Salesforce Contacts. Salesforce Contacts must belong to Accounts. If your Dixa instance lacks company-level data, you have two options:

  • Create a generic "Unclassified" Account to house orphaned Contacts.
  • Enable Person Accounts (a one-way, irreversible org change — recommended only for B2C organizations with no B2B use cases).

CaseComment vs. EmailMessage: The Correct Choice

CaseComment.CommentBody has a hard limit of 4,000 characters. Salesforce silently truncates content that exceeds this — no API error, no warning, no truncation flag in the response. Content is permanently lost with no indication it happened. If you're loading 18-message email threads concatenated into a single CaseComment, you will lose data without knowing it.

Map Dixa messages to EmailMessage instead. It supports HtmlBody and TextBody up to 131,072 characters by default, configurable to 384,000 characters at the org level. It preserves sender/recipient addresses, headers, and HTML formatting. Use CaseComment with IsPublished=false for internal notes, accepting the 4,000-character limit (internal notes are typically shorter).

What broken CaseComment data looks like in production: A 6,200-character email thread appears in Salesforce as 4,000 characters ending mid-sentence. Agents see a complete message in the UI. There is no visual indicator of truncation. You discover the loss during a customer dispute when the agent cannot find context that existed in Dixa. Post-migration validation queries (see below) are the only reliable way to detect this before it matters.

Warning

Check your org's EmailMessage limit before migration. The default HtmlBody limit is 131,072 characters. Orgs with very large historical email threads should verify this limit via a test insert before running bulk loads.

How to Extract Data from Dixa

Extraction Timing: The Math

Before writing code, calculate your extraction timeline. With a 31-day query window and 10 requests/second rate limit:

  • 3 years of history = 36+ sequential API calls per endpoint (conversations + messages = 72+ calls minimum)
  • At 10 req/sec with typical response times of 2–4 seconds per call (network + server processing), a full historical export takes approximately 5–15 minutes of wall-clock time for the API calls themselves
  • The bottleneck is data volume per call, not request rate. A call returning 50,000 conversations may take 8–12 seconds. At 100K conversations across 3 years, plan for 30–90 minutes of extraction time including pagination and retry overhead
  • Attachments are separate. Binary file downloads from Dixa's CDN URLs are not subject to the same rate limit but add significant time proportional to file count and size

The Dixa Exports API (exports.dixa.io) streams conversation and message data as JSON arrays.

  • /v1/conversation_export — Returns conversation metadata: IDs, status, channel, queue, agent, timestamps, tags, custom attributes, wrap-up notes.
  • /v1/message_export — Returns individual messages with content, direction, author, and timestamps.

Key constraints:

  • 31-day query window. Each request requires created_after and created_before parameters spanning no more than 31 days.
  • Internal notes are not in the message export. They live under conversation_wrapup_notes in the conversations endpoint, or via GET /v1/conversations/{id}/notes on the REST API.
  • Rate limit: 10 requests/second per token, burst allowance of 4, daily ceiling of 864,000 requests per token. No Retry-After header on HTTP 429 responses — implement exponential backoff starting at 1 second, doubling to a max of 30 seconds.
  • Rate limits are per token, not per organization. Splitting work across multiple API tokens increases total throughput proportionally.
curl -u "bearer:<API_TOKEN>" \
  "https://exports.dixa.io/v1/conversation_export?created_after=2025-01-01&created_before=2025-01-31"

What a Dixa 429 response looks like:

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
 
{"error": "rate_limit_exceeded", "message": "Too many requests"}

No Retry-After header is included. Your script must track its own request cadence and implement backoff independently.

REST API (For Record Hydration)

The Dixa REST API at https://dev.dixa.io/v1 (not app.dixa.io — that returns 404) provides per-conversation retrieval: GET /v1/conversations/{id}/messages, internal notes, ratings, tags, and custom attributes. Use this to hydrate individual conversations with data the Exports API omits.

Pagination is cursor-based (pageToken and limit, max 100 per page).

CSV Export (Validation Only)

Dixa's in-app CSV export provides conversation metadata — queue, agent, timestamps, ratings, tags — but does not include message content. Use it to validate record counts before and after migration, not as a primary extraction path.

Handling Attachments and Inline Images

Dixa stores attachments as CDN URLs within conversation parts. Migration process:

  1. Parse Dixa message bodies for attachment URLs.
  2. Download binary files to your migration server.
  3. Upload to Salesforce as ContentVersion records.
  4. Salesforce automatically generates a ContentDocument.
  5. Create ContentDocumentLink records to tie files to Cases or EmailMessages.

Do not migrate Dixa URLs as plain text into Salesforce fields. Dixa CDN URLs expire or become inaccessible after contract termination.

Inline base64 images require special handling. Dixa occasionally stores inline images as base64-encoded strings in HTML message bodies. If loaded as-is into EmailMessage.HtmlBody, these strings can push individual records over the 131,072-character limit, causing the API call to fail with:

{"errorCode": "STRING_TOO_LONG", "message": "HtmlBody: data value too large"}

Your transformation layer must: parse the HTML body for <img src="data:image/...;base64,..."> tags, extract and decode the base64 string, save it as a binary file, upload it as a ContentVersion, and rewrite the <img> tag to reference the new Salesforce file URL.

Transformation Layer: JSON to Salesforce

The extraction scripts produce JSON. The Salesforce Bulk API 2.0 expects CSV. The transformation layer between them is where most migration bugs occur.

Conversation to Case + EmailMessages

# Pseudocode: transform Dixa conversation JSON to Salesforce load format
 
def transform_conversation(conv, messages, queue_map, user_map):
    case = {
        "Dixa_Conversation_Id__c": conv["id"],          # External ID
        "Subject": conv.get("subject", f"Conversation {conv['id']}"),
        "Status": map_status(conv["status"]),            # "open" → "New", "closed" → "Closed"
        "Origin": map_channel(conv["channel"]),          # "email" → "Email", "chat" → "Chat"
        "OwnerId": queue_map.get(conv["queue_id"]),      # Salesforce Queue ID
        "ContactId": user_map.get(conv["end_user_id"]), # Salesforce Contact ID
        "CreatedDate": conv["created_at"],               # Requires "Set Audit Fields" permission
        "ClosedDate": conv.get("ended_at"),
        "CSAT_Score__c": conv.get("csat_rating"),
        "Description": conv.get("wrap_up_note", "")[:32768]  # Case description limit
    }
 
    email_messages = []
    for msg in messages:
        body_html = clean_inline_images(msg.get("html_body", ""))
        body_text = msg.get("text_body", "")
 
        # Enforce character limits before load
        if len(body_html) > 131072:
            body_html = body_html[:131072]  # Log truncation for review
        
        email_messages.append({
            "Dixa_Message_Id__c": msg["id"],             # External ID on EmailMessage
            "ParentId": None,                            # Populated after Case insert
            "FromAddress": msg["author_email"],
            "ToAddress": msg.get("recipient_email", ""),
            "Subject": conv.get("subject", ""),
            "HtmlBody": body_html,
            "TextBody": body_text[:32768],
            "MessageDate": msg["created_at"],
            "Incoming": msg["direction"] == "inbound",
            "Status": "0"                                # 0 = New
        })
 
    return case, email_messages

Salesforce CSV Format for EmailMessage Bulk Upsert

Dixa_Message_Id__c,ParentId,FromAddress,ToAddress,Subject,TextBody,MessageDate,Incoming,Status
msg_001,5001A00001XyzABC,customer@example.com,support@yourcompany.com,Order #1234,Message content here,2024-01-15T14:23:11Z,true,0

The ParentId column uses the Salesforce Case Id — not the External ID — because EmailMessage does not support polymorphic External ID references in Bulk API 2.0. Insert Cases first, store the returned Salesforce IDs in your mapping database, then populate ParentId before loading EmailMessages.

How to Load Data into Salesforce Service Cloud

Step 1: Prepare the Salesforce Org

Before loading any data:

  • Create custom fields on Case and Contact: Dixa_Conversation_Id__c (Text, External ID, Unique), Dixa_EndUser_Id__c (Text, External ID, Unique), CSAT_Score__c (Number), CSAT_Date__c (Date).
  • Create a Dixa_Message_Id__c External ID field on EmailMessage for idempotent message upserts.
  • Set up Queues in Salesforce matching your Dixa queue structure.
  • Enable "Set Audit Fields upon Record Creation" in Setup → User Interface → and assign the "Set Audit Fields" permission to the API user's profile or a dedicated permission set. Both steps are required — enabling the org setting without the user permission produces no error but CreatedDate remains today's date.
  • Disable automation temporarily. Turn off assignment rules, escalation rules, auto-response rules, and Apex triggers that fire on Case insert. 100K Case inserts triggering email notifications will exhaust your org's daily email sending limits and create noise in your monitoring.
Tip

Use a sandbox first. Always run the full migration in a Salesforce sandbox before touching production. Sandbox orgs get the same API limits as production, including Bulk API 2.0 capacity and governor limits.

Step 2: Load in Strict Relational Order

Salesforce enforces referential integrity at insert time. Load order is non-negotiable:

  1. Accounts — Store returned Salesforce Id values in your mapping database.
  2. Contacts — Upsert on Dixa_EndUser_Id__c. Map to Account Id.
  3. Cases — Upsert on Dixa_Conversation_Id__c. Map to Contact Id and Account Id.
  4. EmailMessages — Insert with ParentId = Salesforce Case Id (from step 3 results).
  5. CaseComments — Insert internal notes with ParentId = Salesforce Case Id, IsPublished = false.
  6. ContentVersions — Insert attachment files.
  7. ContentDocumentLinks — Link ContentDocuments to Cases or EmailMessages.

Salesforce Governor Limits That Affect Migration

Beyond daily API quotas, these governor limits affect large-scale inserts and cause failures that aren't obvious until you hit them:

  • Heap size limit: 6 MB (synchronous), 12 MB (asynchronous). Apex triggers firing during insert (even disabled ones that escape your shutdown) will fail if they attempt to process large record sets in a single transaction. Verify all triggers are disabled before bulk loads.
  • CPU time limit: 10,000ms (synchronous), 60,000ms (asynchronous). Complex before/after insert triggers on Case can hit CPU limits during Bulk API jobs. Bulk API 2.0 processes records in chunks of 10,000 — each chunk is subject to governor limits independently.
  • DML statements per transaction: 150. Relevant if any active triggers perform additional DML on Case insert.
  • SOQL queries per transaction: 100. Triggers querying related records on each Case insert hit this quickly in bulk contexts.

Bulk API 2.0 itself bypasses most synchronous governor limits by executing asynchronously, but any Apex triggers that remain active during the load are subject to them.

For any migration exceeding 10,000 records, use Salesforce Bulk API 2.0:

  • Processes up to 100 million records per 24-hour period
  • Automatically chunks data into internal batches of 10,000 records
  • Does not count against the org's REST/SOAP daily API limit (Enterprise Edition: 100,000 + 1,000 per user license)
  • Supports upsert operations against External ID fields for idempotency
# Create a Bulk API 2.0 upsert job for Cases
curl -X POST https://yourorg.my.salesforce.com/services/data/v61.0/jobs/ingest \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "object": "Case",
    "operation": "upsert",
    "externalIdFieldName": "Dixa_Conversation_Id__c",
    "contentType": "CSV"
  }'

Bulk API 2.0 error response format — failed records are returned in a results file, not as API errors:

sf__Id,sf__Error,Dixa_Conversation_Id__c,Subject
,FIELD_INTEGRITY_EXCEPTION:ContactId does not exist,conv_12345,Order #789

Check the results file after every job. A job that reports "Completed" may still have thousands of failed records — completion status reflects job processing, not record success rate.

Bulk API 2.0 ContentVersion jobs are capped at 150 MB of CSV payload per job. Split attachment-heavy migrations across multiple jobs.

Warning

CreatedDate requires two configuration steps. Enable "Set Audit Fields upon Record Creation" in Setup and assign the "Set Audit Fields" permission to the API user. Enabling only the org setting produces no error — the API call succeeds, but CreatedDate is silently set to the insert timestamp. You will not discover this until you query historical records and find every 2021 ticket shows today's date.

Post-Migration Validation Queries

Run these SOQL queries after each load phase to verify data integrity before proceeding to the next phase.

-- Verify Case count matches Dixa export count
SELECT COUNT(Id) FROM Case WHERE Dixa_Conversation_Id__c != null
 
-- Find Cases with no linked EmailMessages (potential extraction gaps)
SELECT Id, CaseNumber, Dixa_Conversation_Id__c
FROM Case
WHERE Id NOT IN (SELECT ParentId FROM EmailMessage)
AND Status != 'New'
LIMIT 200
 
-- Detect suspiciously short EmailMessages (possible truncation)
SELECT Id, ParentId, MessageDate, LEN(TextBody)
FROM EmailMessage
WHERE LEN(TextBody) < 100 AND Incoming = true
ORDER BY MessageDate DESC
LIMIT 100
 
-- Check CreatedDate preservation (sample: Cases should span historical date range)
SELECT MIN(CreatedDate), MAX(CreatedDate), COUNT(Id)
FROM Case
WHERE Dixa_Conversation_Id__c != null
 
-- Find ContentDocumentLinks missing their parent Case
SELECT Id, LinkedEntityId, ContentDocumentId
FROM ContentDocumentLink
WHERE LinkedEntityId IN (
  SELECT Id FROM Case WHERE Dixa_Conversation_Id__c != null
)
AND ContentDocumentId NOT IN (SELECT Id FROM ContentDocument)

Use the Dixa CSV export counts as your baseline. If the CSV shows 87,432 conversations and your Case query returns 87,201, investigate the 231 missing records before cutover.

Field-Level Constraints and Known Failure Modes

Constraint Value Failure Mode
CaseComment.CommentBody 4,000 characters Silent truncation — no API error, no warning
EmailMessage.HtmlBody (default) 131,072 characters STRING_TOO_LONG API error on insert
EmailMessage.HtmlBody (max configurable) 384,000 characters Configurable at org level
Salesforce daily REST API limit (Enterprise, 50 users) 150,000 requests REQUEST_LIMIT_EXCEEDED — Bulk API 2.0 uses a separate pool
Bulk API 2.0 daily limit 100M records / 15,000 batches Separate from REST API quota
Bulk API 2.0 ContentVersion job 150 MB CSV payload Split into multiple jobs for attachment-heavy loads
Dixa Exports API window 31 days per request Sequential requests required for multi-year history
Dixa rate limit 10 req/sec per token, 864,000/day No Retry-After header — implement own backoff
Apex synchronous heap size 6 MB Triggers fail on large in-memory datasets during insert
Apex DML statements per transaction 150 Cascading triggers on Case insert can exhaust quickly

Additional Edge Cases

  • Agent @mentions. Dixa allows agents to @mention each other using internal Dixa user IDs. When migrated to Salesforce CaseComment, these appear as plain text (@User1234). Re-linking to Salesforce Chatter mentions requires regex parsing and Dixa ID → Salesforce User ID mapping during transformation.
  • Call recordings. Salesforce cannot efficiently store audio files natively. Upload .wav or .mp3 files to AWS S3 and write the secure S3 URL into a custom URL field (Dixa_Recording_URL__c) on the Salesforce Case.
  • Agent matching. If Dixa agents don't exist as Salesforce Users, Cases cannot be assigned to them. Create all agent User records first, or map unresolved agents to a "Migration Import" user and store the original agent name in a custom text field.
  • Side conversations. Map to related Cases (use a lookup relationship) or to EmailMessages with a custom field flagging them as side conversations.

Workflow Rebuild: Dixa Flows → Salesforce Configuration

There is no automated translation tool for this. Document every Dixa Flow before touching Salesforce — the visual canvas often obscures nested conditions that aren't obvious until you're rebuilding them.

Queue Assignment and Routing

Map Dixa Flow routing logic to:

  • Case Assignment Rules — Route Cases to Queues based on field criteria (origin, priority, custom fields). Handles straightforward branching.
  • Record-Triggered Flows — For conditional logic that assignment rules can't handle. Consolidate multiple Dixa Flows into a single Record-Triggered Flow on Case using Decision elements.
  • Omnichannel Routing Configurations — Configure Priority (lower number = higher priority), Capacity, and Routing Model (Least Active or Most Available) per queue.
  • Email-to-Case — Replaces Dixa's inbound email parsing and creates Cases automatically from inbound email.

Escalation and SLAs

Dixa's time-based escalation → Entitlement Processes and Milestones for SLA targets, plus Escalation Rules for time-based reassignment and notification when SLAs are at risk.

IVR Rebuild in Amazon Connect

If using Service Cloud Voice, Dixa IVR nodes map to Amazon Connect Contact Flows:

  • Dixa IVR menu node → Amazon Connect Get Customer Input block
  • Dixa queue transfer node → Amazon Connect Transfer to Queue block
  • Dixa business hours node → Amazon Connect Check Hours of Operation block
  • Dixa callback node → Amazon Connect Set Callback Number + Transfer to Queue with callback enabled
  • Dixa text-to-speech prompt → Amazon Connect Play Prompt block with Amazon Polly

Each Dixa IVR tree must be rebuilt as an Amazon Connect Contact Flow. Export Dixa IVR screenshots or documentation before decommissioning.

Auto-Replies and Macros

Dixa's auto-reply nodes → Salesforce Auto-Response Rules (for email channel). Agent shortcut templates → Quick Text or Macros. Dixa chatbot logic → Einstein Bots or a third-party platform (Einstein Bots require a separate license).

Knowledge Migration

Salesforce Knowledge (Knowledge__kav) requires setup before import:

  1. Enable Salesforce Knowledge in Setup.
  2. Create article Record Types (maps to Dixa knowledge categories).
  3. Configure Data Categories and assign them to Knowledge — articles without Data Category assignments are not surfaced in search.
  4. Export Dixa articles as HTML.
  5. Sanitize HTML — Salesforce's rich text editor rejects malformed tags, unescaped characters, and certain inline styles. Common failures: unclosed <div> tags, style attributes with unsupported CSS, and <script> tags (stripped silently).
  6. Set PublishStatus = 'Online' explicitly in your load file. Omitting this field or setting it to null results in all articles importing as Drafts — not searchable by agents or the self-service portal.

The Delta Sync and Cutover Strategy

  1. Initial Sync. Two weeks before go-live, extract all historical Dixa data up to a specific timestamp. Load into Salesforce sandbox for UAT, then production. Captures ~95% of total volume.
  2. Delta Sync. On cutover weekend, query Dixa for conversations created or modified after the initial sync timestamp. Load the gap data.
  3. Cutover. Reroute support email addresses (MX record changes — allow 24–48 hours for DNS propagation). Update chat widget endpoints. Reconfigure phone routing. Re-enable assignment rules, escalation rules, and automation. Run the post-migration validation queries. Deactivate Dixa API tokens to prevent split-brain data entry.

For a deeper look at zero-downtime strategies, see Zero-Downtime Help Desk Data Migration: How to Keep Support Running During the Move.

Migration Timeline

Phase Duration Key Activities
Discovery & Mapping 3–5 days Audit Dixa Flows, tags, custom attributes. Map to Salesforce objects/fields. Identify gaps.
Salesforce Org Prep 3–5 days Create custom fields, queues, assignment rules, permission sets. Configure Omnichannel.
Extraction Script Build 3–5 days Build Exports API extraction, REST API hydration for messages/notes/attachments.
Test Migration (Sandbox) 3–5 days Full load into sandbox. Validate counts, content integrity, timestamps, attachments. Run validation SOQL.
Workflow Rebuild 5–10 days Rebuild Dixa Flows as Salesforce assignment rules, escalation rules, Omnichannel config, IVR.
UAT & Validation 2–3 days Agent testing, CSAT spot checks, attachment verification, routing validation.
Production Cutover 1–2 days Delta sync, final load, DNS/email routing changes, go-live.

Total: 3–6 weeks for a team of ~30 agents with 100K conversations. Complex Dixa Flows, heavy attachment volumes, or zero-downtime requirements push toward the longer end.

What Cannot Be Migrated

Item Why Recommended Workaround
Dixa Flow Builder logic No export format exists — must be reverse-engineered from the visual canvas Document each Flow as a decision tree before decommissioning; rebuild as Salesforce Assignment Rules, Flows, and Omnichannel config
IVR trees Dixa IVR configuration is proprietary and has no standard export Screenshot all IVR nodes; rebuild in Amazon Connect Contact Flows (see IVR node mapping above)
Chatbot configurations Dixa bot logic is not exportable Rebuild in Einstein Bots or a third-party platform; treat as a net-new bot implementation
Real-time analytics dashboards Dixa dashboard configuration is not transferable Rebuild as Salesforce Reports/Dashboards; cross-object reporting in Salesforce is more powerful once configured
Conversation offer history Which agent was offered a conversation, accept/decline patterns — no Salesforce equivalent object Archive as CSV for compliance; not actionable in Salesforce without custom development
Side conversations Dixa side conversations have no direct Salesforce equivalent Map to related Cases or EmailMessages with a custom Is_Side_Conversation__c flag

When to DIY vs. Use a Managed Service

Build it yourself when:

  • Fewer than 20K conversations
  • Minimal attachments (< 1,000 files)
  • Simple Dixa Flows (1–2 queues, no IVR, no chatbot)
  • In-house Salesforce admin and a developer comfortable with Bulk API 2.0 and Python or Node.js data pipelines
  • Cutover window of 4+ hours acceptable

Use a managed migration service when:

  • Conversation volumes exceed 50K with full message history
  • Heavy attachment loads (voice recordings, file shares)
  • Complex Dixa Flows with multiple queues, IVR, or chatbot paths
  • Zero-downtime requirement requiring live sync during cutover
  • No in-house Salesforce developer bandwidth
  • Compliance requirements demand audit-grade data integrity documentation

Making the Right Call

A Dixa to Salesforce Service Cloud migration is a medium-to-high complexity project. The data layer is manageable if you respect the constraints on both sides: Dixa's 31-day query windows, 10 req/sec rate limit, and internal notes endpoint; Salesforce's CaseComment truncation, the two-step CreatedDate permission requirement, and governor limits that activate during bulk inserts. The workflow layer is where the real effort lives — rebuilding Dixa Flows into Salesforce's distributed configuration model consumes 40–60% of total project time and requires thorough documentation of the source before you begin.

Start with a sandbox test migration using one month of data. Run the post-migration validation SOQL queries before touching production. Validate record counts, message content integrity (especially truncation), timestamp preservation, and attachment links. Only then plan production cutover.

For a broader view of Salesforce Service Cloud migration planning, see our Salesforce Service Cloud Migration Checklist.

Frequently Asked Questions

Should I use CaseComment or EmailMessage for Dixa conversation history in Salesforce?
Use EmailMessage in almost all cases. CaseComment has a hard 4,000-character limit on CommentBody that silently truncates content. EmailMessage supports up to 131,072 characters by default (configurable to 384,000), preserves HTML formatting, and retains sender/recipient metadata.
How do I preserve original Dixa timestamps when migrating to Salesforce?
Enable 'Set Audit Fields upon Record Creation' in Salesforce Setup and grant the API user the 'Set Audit Fields' permission. Without this, all migrated Cases will show the import date as their CreatedDate, destroying your historical timeline and SLA reporting.
Can Dixa Flows be migrated to Salesforce automatically?
No. Dixa Flows use proprietary visual routing logic with no export format. You must reverse-engineer each Flow from the visual canvas and rebuild the logic manually using Salesforce Assignment Rules, Escalation Rules, Omnichannel Routing, and Flow Builder.
How long does a Dixa to Salesforce Service Cloud migration take?
A typical migration takes 3–6 weeks, including data mapping, Salesforce org prep, test migration in a sandbox, workflow rebuild, UAT, and production cutover. The workflow redesign (Dixa Flows → Salesforce configuration) is usually the longest phase at 5–10 days.
Can I migrate Dixa call recordings to Salesforce?
Salesforce is not designed to store large audio files natively. The standard practice is to extract Dixa recordings, host them in AWS S3 or similar external storage, and write the secure URL into a custom URL field on the Salesforce Case.

More from our Blog