Launched:self-serve migrations intoSuperhuman Docs (Coda)
Try it now
01Agent-first
Runs where you already work
Plug it into Claude, ChatGPT or Cursor. Describe the move in plain English; the agent runs it.
02Engineer-led
Our production engine, unlocked
The pipeline our engineers use on managed enterprise migrations — the same code, now something you can drive yourself.
03Pricing
Try 10 pages free, then $1 a page
Credit-based, pay-as-you-go. No scoping call, no quote — sample it on your own docs before you spend anything.
04Sources
NotionSlabConfluenceSoonGoogle DocsSoon
Skip to content

Salesforce Service Cloud to Front: ETL Migration Guide

A technical guide to extracting Salesforce Service Cloud Cases, EmailMessages, and attachments and loading them into Front via the Import Message API.

Roopendra Talekar Roopendra Talekar · · 17 min read
Salesforce Service Cloud to Front: ETL Migration 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

Salesforce Service Cloud to Front: ETL Migration Guide

Info

TL;DR — Salesforce Service Cloud to Front Migration

There is no native Salesforce-to-Front importer. This migration requires a custom ETL pipeline: extract Cases, EmailMessages, CaseComments, and ContentVersions via Salesforce Bulk API 2.0 and REST API, flatten the relational model into chronological conversation threads, and load via Front's Import Message API (POST /inboxes/{inbox_id}/imported_messages) — one message per request, under tight per-company rate limits. The hardest parts are attachment extraction (ContentDocumentLink joins that burn API calls), threading (import the first message, retrieve the conversation_id, then thread remaining messages), and throughput (Front caps at 50–200 rpm depending on plan). Most data migrations complete within 1–5 business days.

Migrating from Salesforce Service Cloud to Front means converting an enterprise relational data model — Cases, EmailMessages, CaseComments, ContentVersions, Contacts, Accounts — into Front's conversation-centric inbox architecture, much like the architectural shift required in a Salesforce to Zendesk migration. Front collapses all of that into a flat, chronological message thread inside a conversation.

Front's built-in importers only cover Freshdesk, Zendesk, and Help Scout — and even those are limited to roughly 9,000 tickets and are not actively maintained. For Salesforce data, the only viable route is a custom ETL pipeline using Front's Import Message API. This guide covers the exact object mapping, SOQL queries, transformation logic, API constraints on both sides, threading strategy, error handling, and the failure modes that appear in real migrations. For a detailed look at exporting from Salesforce, see How to Export Data from Salesforce Service Cloud. For target-side preparation, keep the Front Migration Checklist nearby.

All API-specific claims reflect documentation as of mid-2026. Verify rate limits and field constraints against current platform docs before implementation.

Salesforce Service Cloud to Front: Data Model Mapping

A Salesforce Service Cloud Case maps to a Front Conversation — but the mapping is not 1:1. Salesforce treats a support ticket as a primary record surrounded by related objects for emails, notes, and files. Front treats the conversation thread itself as the primary record, with messages and comments nested inside it.

Salesforce Object Front Equivalent Mapping Notes
Case Conversation One Case becomes one Conversation. Subject maps directly.
EmailMessage (Incoming=true) Inbound message Import as type email with sender set to the customer.
EmailMessage (Incoming=false) Outbound message Import as type email with sender set to the agent.
CaseComment (IsPublished=true) Message Customer-visible comments must be imported as messages, not internal comments. Plain text only — no HTML variant exists.
CaseComment (IsPublished=false) Internal comment Use POST /conversations/{id}/comments after the conversation exists.
ContentVersion / Attachment Message attachment Download binary from Salesforce REST API, re-upload to Front via multipart/form-data. 25 MB per message limit.
Contact Contact Match by email handle. Front enforces unique email per contact.
Account Account Match by domain. Front links contacts to accounts via domain.
Case Owner (User) Teammate (assignee) Match by email. Use assignee_id on the imported message or PATCH after import.
Case Status Conversation status Map Closed → archived, any open status → open.
Case Priority / Custom Fields Tags or custom fields No direct equivalent — use Front tags or conversation custom fields (plan-dependent).
Warning

CaseComment.CommentBody is limited to 4,000 bytes (not characters) when read via API. HTML-encoded entities count against this limit — & burns 5 bytes for 1 visible character. Salesforce silently truncates comments exceeding this limit at the source (a data loss risk we also highlight in our Intercom to Salesforce migration guide). If your org stores long replies in CaseComments instead of EmailMessages, some content may already be lost before extraction begins.

The IsPublished flag on CaseComment is critical to get right. Front comments are private to teammates — visible only internally. If you load every Salesforce CaseComment as a Front comment, any customer-visible notes disappear from the message timeline agents see. Internal notes become Front comments; published notes become imported messages. (developer.salesforce.com)

Tip

If Salesforce remains your CRM after the move, do not force every CRM field into Front. Front's native Salesforce integration can display and update Salesforce records from the inbox, log conversation threads, and run one-way contact and account syncs (supporting up to 1M synced contacts and 500K synced accounts). Store what agents need inline and link back to Salesforce for deeper CRM context instead of flattening every relationship into Front custom fields. (help.front.com)

Why There Is No Native Import Path

Front does not offer a Salesforce Service Cloud importer. Its three built-in importers (Freshdesk, Zendesk, Help Scout) are limited, and Front itself states they are "not actively maintained" — recommending partner services for larger migrations. CSV import is not an option for conversation data; Front has no bulk CSV conversation import feature.

The only API endpoint designed for historical data ingestion is the Import Message endpoint (POST /inboxes/{inbox_id}/imported_messages). It accepts one message per request, returns 202 Accepted asynchronously, and deduplicates by external_id. Every EmailMessage and every published CaseComment requires its own API call. (help.front.com)

A Salesforce org with 10,000 Cases averaging 6 EmailMessages each requires roughly 60,000 API calls just for message bodies — before contacts, accounts, attachments, or internal comments.

Step 1: Extract Data from Salesforce

Extraction uses two Salesforce APIs in combination. Bulk API 2.0 handles high-volume flat object queries (Cases, Contacts, Accounts). REST API handles EmailMessages, CaseComments, and binary file downloads. Bulk API 2.0 is designed for operations above roughly 2,000 records, but it does not support parent-to-child relationship subqueries — so you must extract objects separately and join them locally during transformation. (developer.salesforce.com)

For a deep dive on extraction methods and limits, see How to Export Data from Salesforce Service Cloud.

Core SOQL Queries

Cases:

SELECT Id, CaseNumber, Subject, Status, Priority, Origin,
       AccountId, ContactId, OwnerId, CreatedDate, ClosedDate,
       Description, Type
FROM Case
WHERE CreatedDate >= 2024-01-01T00:00:00Z

EmailMessages:

SELECT Id, ParentId, Subject, TextBody, HtmlBody,
       FromAddress, ToAddress, CcAddress, BccAddress,
       MessageDate, Incoming, HasAttachment,
       IsExternallyVisible, CreatedById
FROM EmailMessage
WHERE ParentId IN (SELECT Id FROM Case WHERE CreatedDate >= 2024-01-01T00:00:00Z)

CaseComments:

SELECT Id, ParentId, CreatedDate, CreatedById,
       CommentBody, IsPublished
FROM CaseComment
WHERE ParentId IN (SELECT Id FROM Case WHERE CreatedDate >= 2024-01-01T00:00:00Z)

ContentDocumentLinks (for attachments):

SELECT ContentDocumentId, LinkedEntityId
FROM ContentDocumentLink
WHERE LinkedEntityId IN :caseOrEmailIds

ContentVersions (file metadata):

SELECT Id, ContentDocumentId, Title, FileExtension,
       ContentSize, Checksum, CreatedDate
FROM ContentVersion
WHERE ContentDocumentId IN :docIds
AND IsLatest = true

EmailMessageRelations (for CC/BCC participant mapping):

SELECT Id, EmailMessageId, RelationId, RelationAddress,
       RelationObjectType, Type
FROM EmailMessageRelation
WHERE EmailMessageId IN :emailMessageIds

EmailMessageRelation is required when you need canonical participant records for CC'd and BCC'd contacts — the rendered ToAddress and CcAddress strings on EmailMessage contain semicolon-delimited addresses that must be parsed, while EmailMessageRelation provides structured references to the underlying Contact or User records. Omitting this join causes CC/BCC participants to appear as raw email strings rather than linked Front contacts.

The Attachment Extraction Trap

Extracting attachments from Salesforce is the most API-expensive part of the migration. ContentDocumentLink is a junction object connecting files to parent records — skipping this join is the single most common reason attachment migrations fail, leaving orphaned files that cannot be associated with their parent Case or EmailMessage.

Bulk API 2.0 cannot export binary content from ContentVersion.VersionData. Each file must be downloaded individually via the REST API:

GET /services/data/vXX.0/sobjects/ContentVersion/{id}/VersionData
Danger

API Limit Warning: Salesforce Enterprise Edition orgs have a base allocation of 100,000 REST API calls per day plus 1,000 per user license. Bulk API 2.0 query jobs have a separate allocation of 10,000 per 24-hour rolling window. If you have 200,000 attachments, attempting to download them all in a single day will exhaust your limits and disrupt other integrations on your production org. Batch file downloads over several days or use a dedicated extraction tool.

Salesforce Extraction Limits at a Glance

Constraint Limit
Daily REST API calls 100,000 base + 1,000 per user license (Enterprise Edition)
Bulk API 2.0 query jobs 10,000 per 24-hour rolling window
Bulk API 2.0 query results 1 TB per 24-hour rolling window
Concurrent long-running requests 25 (production), 5 (developer/trial)

Timezone Normalization

Salesforce stores CreatedDate and MessageDate in UTC, but org-level timezone settings can affect how these values are displayed in the UI — and some legacy integrations write timestamps in local time. Before loading into Front, normalize all timestamps to UTC and convert to Unix epoch seconds. Front's created_at field accepts Unix timestamps and stores them as UTC. A mismatch causes messages to appear out of chronological order within a conversation thread.

from datetime import datetime, timezone
 
def sf_datetime_to_unix(sf_datetime_str: str) -> int:
    """Convert Salesforce ISO 8601 datetime string to UTC Unix timestamp."""
    dt = datetime.fromisoformat(sf_datetime_str.replace('Z', '+00:00'))
    return int(dt.astimezone(timezone.utc).timestamp())

Step 2: Transform Relational Data into Conversation Threads

Transformation converts Salesforce's multi-object relational model into Front's flat conversation-message model. As with other flat-architecture targets like eDesk, this is where most migrations break.

Merging EmailMessages and CaseComments into a Single Timeline

Front expects a chronological feed. If you import messages out of order, the conversation history becomes unreadable. The transformation logic must:

  1. Collect all EmailMessages and CaseComments for each Case, grouped by ParentId.
  2. Sort by MessageDate (for emails) or CreatedDate (for comments) to build a unified timeline.
  3. Determine message direction. EmailMessage.Incoming=true → inbound (sender is the customer). Incoming=false → outbound (sender is the agent).
  4. Split CaseComments by IsPublished. Published comments become imported messages. Unpublished comments are loaded as internal Front comments via a separate endpoint after the conversation exists.
  5. Identify the first message. If the Case was created via email, the oldest EmailMessage becomes the first message. If it was created via a web form, the Case.Description may serve as the initial message body.

HTML Body Sanitization

Prefer HtmlBody over TextBody when extracting EmailMessages. HTML preserves formatting, inline images, and reply chains. TextBody is a stripped representation that loses structure. Front's imported messages accept body_format of html or markdown, so use html when HtmlBody is available and fall back to markdown when it is not. (developer.salesforce.com)

Salesforce HtmlBody fields often contain artifacts that must be cleaned before loading into Front:

  • Inline image references using the refid:// protocol — these will not render in Front. Replace with direct URLs or base64-encoded data: URIs.
  • Salesforce-specific CSS classes (sfdcBody, htmlDetailBody) — strip these to prevent broken rendering.
  • <style> elements that conflict with Front's email rendering engine.
  • Silent truncation — Salesforce HtmlBody is capped at 131,072 characters per the Salesforce EmailMessage field reference. Emails exceeding this limit are truncated at the source without warning. The TextBody equivalent is capped at 32,000 characters.

metadata.thread_ref and In-Reply-To Headers

When importing email replies, Front's Import Message API accepts an optional metadata.thread_ref field that corresponds to the RFC 2822 Message-ID header value of the original email. If your Salesforce EmailMessage records retain the original MessageIdentifier field (populated when Email-to-Case processes inbound mail), populate thread_ref with that value. This allows Front to apply its native threading logic in addition to the explicit conversation_id parameter, reducing the risk of threading errors if messages arrive out of order during the import. (dev.frontapp.com)

Making Reruns Idempotent

Front rejects imports with a previously-used external_id. Use stable, source-derived identifiers: sf-email-{EmailMessage.Id} for emails and sf-comment-{CaseComment.Id} for published comments. This ensures retries do not create duplicate history. If you need to re-run the migration after a failed attempt, either use a different inbox or delete the previously imported conversations first. (dev.frontapp.com)

Status and Priority Mapping

Front conversations have three core statuses: open, archived, and deleted. Salesforce Cases have a configurable picklist (New, Working, Escalated, Closed, etc.). The mapping is necessarily lossy:

Salesforce Case Status Front State Method
Any open status (New, Working, Escalated) open Default on import
Closed archived Use is_archived metadata flag during import, or PATCH afterward
Custom statuses Tags Apply as Front tags during or after import

Case Priority, Origin, and Type have no native Front equivalent. Map these to tags or conversation custom fields (available on Scale plans and above).

Step 3: Load into Front via the Import Message API

Required OAuth Scopes

Before implementation, configure your Front API token or OAuth app with the following scopes. Missing scopes return 403 Forbidden without a descriptive error message:

Operation Required Scope
Import messages messages:write
Create/update contacts contacts:write
Create/update accounts accounts:write
Post internal comments comments:write
PATCH conversation metadata conversations:write
List teammates (for owner mapping) teammates:read
List inboxes inboxes:read

Front's sandbox environment (api2.frontapp.com with a dedicated sandbox token) is available for testing import pipelines before production load. Run a complete migration against a sandbox with a representative 50–100 Case sample before touching production.

Load Order

The dependency chain dictates the loading sequence:

  1. Contacts — Create or update via POST /contacts with the customer's email handle. Front enforces unique handles; duplicates return 409 Conflict.
  2. Accounts — Create accounts and link contacts by domain. (If Salesforce remains your CRM, Front's native Salesforce sync handles this automatically.)
  3. First message per Case — Import via POST /inboxes/{inbox_id}/imported_messages. This creates both the message and the conversation.
  4. Retrieve the conversation_id — The Import endpoint returns 202 Accepted asynchronously. Poll GET /messages/alt:uid:{message_uid} to retrieve the conversation reference. Add a 1–2 second delay before querying.
  5. Remaining messages per Case — Import with the conversation_id parameter to thread into the existing conversation, sorted by date ascending.
  6. Internal comments — Load unpublished CaseComments via POST /conversations/{id}/comments.
  7. Attachments — Include as multipart/form-data in the import call. 25 MB per message limit.
  8. Post-import updates — PATCH conversations with assignee_id, status_id, tags, custom fields, and links back to the source Salesforce Case.
Warning

Front's import endpoint returns 202 Accepted asynchronously. The message and conversation are not immediately queryable. If your pipeline threads messages by conversation_id, you must poll or add a delay before importing the next message in the same thread. Racing this step creates orphaned conversations — messages that should be threaded together end up in separate conversations.

Sample Import Payload

{
  "sender": {
    "handle": "customer@example.com",
    "name": "Jane Doe"
  },
  "to": ["support@yourcompany.com"],
  "subject": "Login issue with production database",
  "body": "<p>I am unable to access the production database since the update.</p>",
  "body_format": "html",
  "external_id": "sf-email-02sXXXXXXXXXXXXX",
  "created_at": 1704067200,
  "type": "email",
  "metadata": {
    "is_inbound": true,
    "is_archived": true,
    "should_skip_rules": true,
    "thread_ref": "<CAOriginalMessageID@mail.example.com>"
  }
}

The created_at field accepts a Unix timestamp, allowing Front to backdate the message to its original Salesforce MessageDate. The external_id enables deduplication across retries. Set should_skip_rules to true to prevent historical imports from triggering Front's assignment rules, tag automations, and notifications. Set is_archived to true for closed Cases to avoid cluttering the open inbox. The optional thread_ref field accepts the original RFC 2822 Message-ID header to reinforce threading logic. (dev.frontapp.com)

Attachment Handling

When a message has attachments, switch from application/json to multipart/form-data. Include the JSON metadata as one part and append file binaries as attachment parts. Front enforces a strict 25 MB limit on total message size including attachments.

Salesforce ContentVersion supports files up to 2 GB, so oversized files are a real edge case. If a Case contains attachments exceeding Front's limit, your ETL script must catch the 413 Payload Too Large error, host the files externally (e.g., Amazon S3), and insert download links into the message body instead.

Warning

Partial custom-field updates clobber data. Front's API erases omitted custom fields when you update a conversation. Always send the full custom-fields object, not just the fields you want to change. (dev.frontapp.com)

API Rate Limits: Both Sides

Rate limits are the primary throughput bottleneck. Both platforms enforce strict constraints, but Front's limits are tighter and more impactful on the import side.

Front API Limits

Front Plan Rate Limit Per-Resource Cap
Starter 50 req/min 5 req/sec per resource type
Growth 100 req/min 5 req/sec per resource type
Scale 200 req/min 5 req/sec per resource type

Front's rate limit is per company, not per token — every integration, API token, and OAuth app on the account draws from the same pool. A migration script running at full speed starves live integrations (Slack notifications, Zapier automations, CRM syncs). Partner OAuth integrations get a separate 120 rpm limit, which is why partner-led migrations avoid impacting your team's live workflows.

Exceeding the limit returns 429 Too Many Requests with a Retry-After header. Exhausting the burst buffer triggers a cooldown period of roughly 10 minutes.

Throughput Math

On Front's Growth plan (100 rpm), importing 10,000 Cases with 6 messages each:

  • 60,000 import calls ÷ 100 rpm = 600 minutes (~10 hours), assuming zero overhead.
  • Add contact creation, conversation status PATCHes, internal comments, and attachment uploads → realistic throughput is 40–60 effective imports per minute after backoff and retries.
  • Total wall-clock time: 16–25 hours for the import side alone.

On Scale (200 rpm), the same volume compresses to roughly 8–13 hours. Rate limit add-ons (300 additional rpm per add-on) can further reduce this.

Error-Handling Decision Matrix

Build explicit handling for each HTTP error code into your loading script. Do not treat all non-200 responses identically.

HTTP Status Cause Correct Action
202 Accepted Message queued, not yet written Poll GET /messages/alt:uid:{uid} after 1–2 second delay
400 Bad Request Malformed payload, invalid field type Log full request body, skip record, flag for manual review
403 Forbidden Missing OAuth scope or inbox access Check token scopes; verify inbox_id is accessible to the token
404 Not Found conversation_id or inbox_id does not exist Verify conversation was successfully created before threading
409 Conflict external_id already used Record already imported; skip silently or verify idempotency
413 Payload Too Large Attachment exceeds 25 MB Strip attachment, upload to external storage, insert download link in body
429 Too Many Requests Rate limit exceeded Read Retry-After header; apply exponential backoff with jitter
500 / 503 Front server error Retry with exponential backoff (max 3 attempts); log if persistent

For 429 responses specifically: implement token-bucket rate limiting in your script rather than reacting to 429s after the fact. Track the X-RateLimit-Remaining and X-RateLimit-Reset headers returned on every Front API response to proactively throttle before the limit is reached.

Validation Methodology

Spot-checking is insufficient for production migrations. Use a structured validation protocol before cutover.

Record-Count Parity

After the initial load, compare record counts between source and target:

# Salesforce side (run via REST API)
sf_counts = {
    'cases': query("SELECT COUNT() FROM Case WHERE ..."),
    'emails': query("SELECT COUNT() FROM EmailMessage WHERE ..."),
    'comments': query("SELECT COUNT() FROM CaseComment WHERE IsPublished=true AND ...")
}
 
# Front side (count via GET /conversations with filters)
front_counts = {
    'conversations': count_front_conversations(inbox_id=TARGET_INBOX),
    'messages': sum(get_message_count(conv_id) for conv_id in conversation_ids)
}

Discrepancies greater than 0.5% warrant investigation before proceeding to delta sync.

Checksum-Based Attachment Validation

Salesforce ContentVersion.Checksum stores the MD5 hash of the file content. After downloading and re-uploading to Front, compute the MD5 of the downloaded binary before upload and log it against the source checksum. A mismatch indicates a corrupted download — retry the extraction rather than loading a corrupted file.

import hashlib
 
def validate_attachment(local_path: str, sf_checksum: str) -> bool:
    with open(local_path, 'rb') as f:
        computed = hashlib.md5(f.read()).hexdigest()
    return computed.lower() == sf_checksum.lower()

Threading Validation

For a random sample of 100 Cases with 3+ messages, verify that:

  • The Front conversation contains the expected message count
  • Messages are ordered chronologically by created_at
  • The first message sender.handle matches the Salesforce EmailMessage.FromAddress on the oldest inbound email

Edge Cases and Failure Modes

Auto-Response Emails in Email-to-Case

If your Salesforce org uses case auto-response rules, those auto-generated emails are stored as EmailMessages linked to the Case. Unless you filter them, they get imported into Front as regular messages in the conversation. Add WHERE IsExternallyVisible = true to your EmailMessage query, or filter by Status values specific to your org's configuration.

Conversation Ownership Without Matching Teammates

If a Salesforce Case Owner's email does not match any Front teammate, the assignee_id parameter silently fails — no error, just no assignment. Build a teammate lookup map before migration: extract all Case Owner emails from Salesforce, list all Front teammates via GET /teammates, and flag mismatches. Unmatched owners should fall back to a default teammate or be left unassigned.

LiveChatTranscript and Messaging Records

Salesforce stores live chat interactions in LiveChatTranscript — a single Body text field containing the full conversation, not individual messages. Migrating chat history requires parsing that monolithic text block into discrete messages with imputed timestamps. This is lossy by nature (a schema translation challenge we also detail in our Freshchat to Salesforce migration guide). MessagingSession and ConversationEntry objects follow different extraction patterns and are a separate workstream.

Salesforce Knowledge Articles

Salesforce Knowledge articles (KnowledgeArticleVersion) can be migrated to Front's Knowledge Base via a separate API, but the content model differs significantly. Treat this as a distinct workstream from conversation migration.

What Cannot Be Migrated

Some Salesforce Service Cloud artifacts have no Front equivalent and must be rebuilt manually in the target platform:

  • Automation rules — Process Builder, Flows, Assignment Rules, Escalation Rules → rebuild as Front Rules
  • Macros and email templates — Quick Text, Email Templates → Front Message Templates
  • SLA policies — Entitlement Processes, Milestones → Front SLA rules (different model)
  • Dashboards and reports — Salesforce Reports → Front Analytics (fresh start; historical metrics do not transfer)
  • Omni-Channel routing — rebuild using Front's assignment rules and load balancing
  • Approval processes — no native Front equivalent

How Long Does a Salesforce Service Cloud to Front Migration Take?

The data migration itself is typically completed within 1–5 business days, depending on data volume, complexity, and API rate limits. Small datasets under 10,000 records can finish in under 24 hours.

Volume (Cases) Estimated Migration Time Primary Bottleneck
1–500 1–2 business days Setup and mapping; limited API pressure
500–5,000 3–7 business days Front rate limits (100–200 rpm); attachment volume
5,000–50,000 7–13 business days Front rate limits; Salesforce daily API consumption; attachment extraction
50,000+ Custom scoping required Multi-day Salesforce extraction; may require rate limit add-ons on Front

These figures describe the ETL data migration only. They do not include your internal Front rollout: configuring inboxes, building rules, training agents, and setting up integrations. That effort is measured in weeks or months. Start your migration scoping at least 3–4 months before any internal go-live deadline or Salesforce contract expiration to leave room for both workstreams.

Planning the Cutover

A zero-downtime cutover requires a delta sync strategy. A full extraction and load for hundreds of thousands of Cases takes days, and your agents must continue working in Salesforce during the historical data load.

The standard protocol:

  1. Initial sync — Extract all closed Cases and historical data up to a specific timestamp. Load into Front.
  2. Validation — Record-count parity checks, checksum-based attachment validation, field-level spot checks, and threading verification on a representative sample.
  3. Delta sync — Extract only Cases modified since the initial sync timestamp. Transform and load the updates.
  4. Cutover — Pause inbound email routing to Salesforce, redirect mail forwarding to Front, run one final delta sync to catch messages received during the DNS propagation window, and log agents into Front.

A good migration leaves agents with complete, searchable conversation history in Front without turning Front into a brittle copy of Salesforce. Customer-visible history is preserved as readable messages, internal notes stay private, key case metadata is searchable via tags and custom fields, oversized files have a documented fallback path, and agents can still jump back to Salesforce when they need deeper CRM context. For more on Front's architecture and capabilities, see our Front technical guide.

At ClonePartner, we execute this end-to-end: one fixed price per project starting at $500, no hourly billing, no per-record metering. We run unlimited sample migrations until the data mapping is right, followed by the full migration and delta syncs. We have completed 1,500+ successful migrations, with one dedicated migration engineer owning each project. Our infrastructure is secured by SOC 2 Type II and ISO 27001 safeguards.

Frequently Asked Questions

Can I import Salesforce Service Cloud cases into Front natively?
No. Front has no native Salesforce importer. Its built-in importers only cover Freshdesk, Zendesk, and Help Scout, and even those are limited and not actively maintained. Salesforce data must be imported via Front's Import Message API using a custom ETL pipeline.
How long does a Salesforce Service Cloud to Front migration take?
The data migration itself is typically completed within 1–5 business days, depending on data volume, complexity, and API rate limits. Small datasets under 10,000 records can finish in under 24 hours. Larger volumes (5,000+ cases) are a custom engagement that may take 7–13+ business days.
How do you handle attachments when migrating from Salesforce to Front?
Salesforce stores files as ContentVersion records linked via ContentDocumentLink. Each file must be downloaded individually via the Salesforce REST API, then included as multipart/form-data in Front's import call. Front caps attachments at 25 MB per message — files exceeding this must be hosted externally and linked in the message body.
How should Salesforce CaseComments map to Front?
Published CaseComments (IsPublished=true) should be imported as messages within a Front conversation so they remain visible to agents. Unpublished CaseComments map to Front's internal comments endpoint. Note that CaseComment.CommentBody is limited to 4,000 bytes and has no HTML variant — only plain text.
What are Front's API rate limits for importing messages?
Front's rate limits are per company, not per token: 50 requests/min on Starter, 100 on Growth, and 200 on Scale, with a per-resource burst cap of 5 requests per second. Exceeding the limit returns a 429 error with a Retry-After header. Partner OAuth integrations get a separate 120 rpm limit.

More from our Blog