Zendesk to Front: Migrating Attachments & Side Conversations
Zendesk side conversations and oversized attachments are the top causes of silent data loss in Front migrations. Here's how to handle both at the API level.
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
Zendesk to Front: Migrating Attachments & Side Conversations
Zendesk side conversations and ticket attachments are the two data types most likely to be silently dropped during a Zendesk to Front migration. Front has no native equivalent of side conversations, and its per-message attachment limit is half of Zendesk's. Skip planning for both and you will finish your migration with incomplete ticket histories and missing files — and your agents will not notice until a customer calls about a thread that looks empty.
Front's built-in Zendesk importer is documented as "not actively maintained" and covers conversations, messages, attachments, comments, and assignments — but not side conversations. If those threads matter to your team, treat them as a custom mapping problem, not a checkbox.
This guide covers the exact API behavior on both sides, the mapping decisions you need to make before writing any code, and the edge cases that catch teams mid-migration. For the full Zendesk-to-Front migration workflow — field mapping, rate limits, and step-by-step process — see Zendesk to Front Migration: The 2026 Technical Guide. If you are already planning rollout, pair this with the Front Migration Checklist.
What are Zendesk side conversations?
A Zendesk side conversation is a separate thread attached to a ticket that lets an agent loop in a third party without cluttering the main customer conversation. The customer never sees it; the back-and-forth stays docked to the ticket it belongs to.
Zendesk supports four side conversation channel types:
- Email — the most common type. An agent sends an email from within the ticket to someone outside the customer thread.
- Slack — a linked Slack thread synced back to the ticket.
- Microsoft Teams — same concept as Slack, via a Teams channel.
- Child ticket — a separate Zendesk ticket linked to the parent, assigned to a different group or agent.
Side conversations are only available on Zendesk Suite plans: Professional, Enterprise, or Enterprise Plus. They are also available as a Collaboration add-on for Support Professional plans and above. If your Zendesk instance is on a lower plan, you will not have side conversation data to extract.
Each side conversation has its own subject, state (open/closed), participant list, and an ordered series of events — the actual messages exchanged. Those events can include attachments with their own content_url, filename, content type, and file size.
Do not assume your ticket export is complete just because comments look complete. Standard ticket comments and side conversations live on different Zendesk API surfaces. If you only extract /api/v2/tickets/{ticket_id}/comments, you will miss email side threads, Slack/Teams discussions, and child-ticket side conversations entirely. (developer.zendesk.com)
Why side conversations have no 1:1 mapping in Front
Front organizes work around two primitives: conversations (message threads in shared inboxes) and comments (internal notes visible only to teammates). That is the entire model.
A Zendesk ticket maps to a Front conversation. Internal notes in Zendesk map to Front comments. But a side conversation is neither — it is a multi-message, multi-participant thread that is internal to the support team yet separate from both the customer thread and the internal notes.
This structural gap forces a design decision before any code is written. The right mapping depends on how your team used side conversations in Zendesk and what you prioritize: chronology, privacy, or preserving the fact that the thread was a separate workstream.
Strategy 1: Flatten into Front comments
Import each side conversation as a series of comments (internal notes) on the parent Front conversation. Prepend each comment with metadata — the side conversation subject, the original sender, and the timestamp.
When this works: Teams that used side conversations for quick internal questions and rarely need to reference the full back-and-forth. The content is preserved and searchable; the threading is lost.
Trade-offs:
- Comments in Front do not support threading. A 12-message side conversation becomes 12 separate comments interleaved with the main conversation's internal notes.
- Front's Add Comment endpoint does not accept a
created_atparameter, so comments cannot be backdated — they all appear as posted on migration day. (dev.frontapp.com) - Comments on a shared inbox conversation are visible to anyone with inbox access, which may broaden visibility beyond the original side conversation participants.
Strategy 2: Import as separate linked conversations
Create a new Front conversation for each Zendesk side conversation, imported into the same inbox (or a dedicated "side conversations" inbox). Tag it with the parent ticket ID and use a naming convention like [Side Conv] Original Subject — Parent #12345.
When this works: Teams that ran substantive multi-message side conversations with external vendors or cross-functional teams and need to preserve full thread structure. Front's Import Message endpoint preserves created_at, sender, recipients, subject, HTML body, and attachments — so chronology is maintained. (dev.frontapp.com)
Trade-offs:
- Front has no native parent-child conversation relationship. The link between parent and side conversation is maintained only through tags and naming conventions.
- Agents must search or filter by tag to reconnect a side conversation to its originating ticket.
Strategy 3: Hybrid — comments for short threads, conversations for long ones
Set a message-count threshold. Side conversations at or below the threshold become comments; those above it become separate linked conversations. This keeps the comment stream clean while preserving substantive threads.
Why 3 messages as the threshold: In practice, a 1–2 message side conversation is typically a quick question with a single answer — the content value is in the text, not the structure. At 4+ messages, the thread usually involves back-and-forth negotiation or decision-making where losing chronology degrades the audit trail meaningfully. Three messages is the inflection point where agents start relying on thread structure rather than just message content. The threshold is configurable and should be adjusted if your team used side conversations primarily for longer vendor negotiations (lower to 2) or primarily for quick pings (raise to 5).
This is the approach that works best for most Zendesk-to-Front migrations because it avoids both a cluttered comment stream (Strategy 1 applied universally) and an inbox flooded with single-message stub conversations (Strategy 2 applied universally).
Which mapping fits which side conversation type?
The channel type of the original side conversation also affects the decision:
| Zendesk source | Recommended Front target | Rationale | Trade-off |
|---|---|---|---|
| Email side conversation (short, ≤3 messages) | Comments on parent conversation | Keeps context inline; clearly internal | Cannot backdate; threading lost |
| Email side conversation (long, >3 messages) | Separate Front conversation | Preserves timestamps, sender, recipients, full thread | Requires tag-based cross-referencing |
| Slack or Teams side conversation | Comments if audit context only; separate conversation if it drove real decisions | Zendesk only captures messages synced back to the ticket — original Slack/Teams reactions, edits, and thread replies outside the sync window are not available | Comments broaden visibility to full inbox |
| Child ticket | Separate Front conversation | Child tickets are already standalone work items in Zendesk | Needs explicit cross-reference via tags or custom fields |
Do not collapse sensitive external threads into shared-inbox comments without a permissions review. A Front comment is private to Front users, but it is visible to anyone who can access that shared inbox. That is a different visibility model from a Zendesk side conversation that only involved a few agents and an outside participant.
How to extract side conversations from Zendesk
Zendesk exposes side conversations through two main endpoints:
- Per-ticket:
GET /api/v2/tickets/{ticket_id}/side_conversations— returns all side conversations for a given ticket, with optional sideloading of events. - Incremental export:
GET /api/v2/tickets/side_conversations/events?start_time={start_time}— returns all side conversation events created since a Unix timestamp. This is the efficient path for bulk extraction.
The incremental endpoint returns events across all tickets, so you can extract all side conversation data in a single paginated pass rather than hitting every ticket individually. For a 50,000-ticket migration, this is the difference between tens of thousands of API calls and a few hundred.
Each event contains the message body (plain text and HTML), the from and to participants, the created_at timestamp, and an attachments array with content_url, file_name, content_type, and size for each file.
The incremental side conversation events endpoint is restricted to Admins. A non-admin API token will receive HTTP 403. Plan your credentials accordingly before starting extraction.
Estimated API call volumes by ticket count
How long extraction actually takes depends on your ticket volume, side conversation density, and attachment count. The following estimates assume the incremental events endpoint for side conversations and a page size of 100 events:
| Ticket volume | Estimated side conv. API calls | Estimated attachment downloads | Approximate extraction time (at Zendesk rate limits) |
|---|---|---|---|
| 10,000 tickets | ~50–200 paginated calls | Varies by usage | 1–3 hours |
| 50,000 tickets | ~200–800 paginated calls | Varies by usage | 4–12 hours |
| 200,000 tickets | ~800–3,000 paginated calls | Varies by usage | 1–4 days |
These estimates cover extraction only. Front's single-message import endpoint (no bulk endpoint exists) and its per-plan rate limits (50–200 requests/minute) typically make the import phase 2–5× longer than extraction at high ticket volumes.
How to migrate Zendesk attachments to Front
Attachments usually migrate cleanly — if you handle source URLs, size limits, and inline-image behavior deliberately.
The authentication barrier
By default, Zendesk instances have "Require authentication to download" enabled for attachments. If you pass a Zendesk attachment URL directly to Front's import API, Front's servers will receive HTTP 401 when attempting to fetch the file, resulting in broken images and missing PDFs.
Zendesk also warns that a comment attachment's content_url can point to an externally hosted file, so your downloader should verify the domain before forwarding credentials. (developer.zendesk.com)
You must implement a staging process:
- Query the Zendesk API for ticket comments:
GET /api/v2/tickets/{ticket_id}/comments?include_inline_images=true - Parse the
attachmentsarray within each comment. - Use a Zendesk API token to authenticate and download the raw file to secure staging storage.
- Construct a
multipart/form-datarequest. - Push the file to Front using
POST /inboxes/{inbox_id}/imported_messages.
Front's create-message and reply endpoints only accept file attachments as multipart/form-data. You cannot send attachments as JSON-encoded base64 in the request body — the API will silently ignore them or return an error.
Private attachments and expiring URLs
Zendesk accounts with private attachments enabled generate time-limited, pre-signed URLs for each file. These URLs are short-lived. If you perform a bulk migration or download, you must download the file immediately after accessing the attachment endpoint.
You cannot build a manifest of all attachment URLs first and then download them in a second pass. The URLs will have expired. The migration script must download each attachment immediately after fetching the comment or side conversation event that references it.
For side conversation attachments specifically, the content_url in the event payload follows the same pattern and requires authentication. These URLs also expire.
Stream, don't batch. The safest architecture for attachment extraction is: fetch a page of events → for each event with attachments, download the files immediately to local or cloud staging → move to the next page. This avoids URL expiry and keeps memory usage bounded.
The inline image trap
Inline images — screenshots pasted directly into a Zendesk comment rather than attached as files — are a frequent source of silent data loss.
The Zendesk ticket comments API has an include_inline_images parameter. The default is false. When set to true, inline images are also listed as attachments in the response.
If you do not explicitly set include_inline_images=true when extracting comments, those images will not appear in the attachments array. The comment's HTML body will still reference them via <img> tags pointing to Zendesk-hosted URLs, but once the Zendesk account is deactivated, those URLs return 404 and the images are permanently lost.
The fix:
- Always request comments with
include_inline_images=true. - Download each inline image by its
content_url. - Re-upload it as an attachment on the corresponding Front message with an explicit
Content-IDheader so Front can render it inline, or re-encode it as a base64 data URI in the HTML body.
Large files or inline images that exceed Front's per-file limits may cause the API to return an error or, in some cases, fail silently. Validate attachment sizes before upload, not after.
Front's attachment size limits
The single most common attachment failure is the file size ceiling gap: Zendesk allows files up to 50 MB while Front's import endpoint caps at 25 MB. Any Zendesk attachment between 25 MB and 50 MB will fail on import unless you handle it explicitly.
Front's limits vary by channel type:
| Channel | Per-message limit |
|---|---|
| Gmail | 25 MB |
| Office 365 | 100 MB |
| Generic SMTP (SendGrid) | 19.5 MB |
| Custom SMTP | 25 MB |
| Discussions, tasks, comments | 100 MB |
| All other channel types (including import endpoint) | 25 MB |
The import message endpoint falls under "all other channel types," so 25 MB is the effective ceiling for all migrated data, regardless of which channel type the destination inbox uses.
Front also enforces a maximum of 100 attachment files per email message. That is a generous limit, but if a Zendesk ticket accumulated hundreds of attachments across comments, distribute them correctly across the corresponding Front messages rather than consolidating everything onto a single import call.
For oversized files, the practical options are:
- Link instead of embed. Upload the file to cloud storage (S3, GCS, or similar) and insert a download link in the message body. Append a note indicating the file exceeded Front's native 25 MB limit.
- Compress where possible. Uncompressed screenshots and log bundles can often be reduced below 25 MB without meaningful loss.
- Split across messages. Rarely practical, but technically possible for multi-file comments where individual files are under 25 MB but the total exceeds the per-message ceiling.
Set an oversize-file policy before the full load starts. Flag every attachment over 25 MB during your pre-migration audit and decide on your handling strategy — link, compress, or skip — before the first sample migration. Inventing that policy during cutover weekend is how attachments get permanently lost. (dev.frontapp.com)
API rate limits that shape the migration
Both APIs enforce rate limits that directly affect migration throughput and architecture.
Front's API limits by plan:
| Plan | Requests per minute | Burst limit |
|---|---|---|
| Starter | 50 | ~5 req/sec per resource |
| Professional | 100 | ~5 req/sec per resource |
| Enterprise | 200 | ~5 req/sec per resource |
Front's import path is single-message only — there is no bulk import endpoint. (help.front.com)
Rate limits are enforced per-company, not per API token. If you have other integrations running alongside your migration script, they share the same quota. A Starter-plan company running a migration at full speed — 50 requests/minute — with an active Zapier integration will see the integration's requests counted against the same cap.
Zendesk rate limits (relevant endpoints):
| Endpoint | Limit |
|---|---|
| General API | 400 requests/minute (standard plans) |
| Incremental Exports | 10 requests/minute |
| Incremental Side Conversation Events | 600 requests/10 minutes |
In practice, you need queueing, retries with Retry-After header handling, checkpointing, and a resumable pipeline — not one long script. A script that fails at record 47,000 of 50,000 without a checkpoint forces a full restart.
At the API level, the core workflow:
# 1) Pull Zendesk ticket comments, including inline images
GET /api/v2/tickets/{ticket_id}/comments?include_inline_images=true
# 2) Pull side conversation events (bulk, all tickets)
GET /api/v2/tickets/side_conversations/events?start_time={unix_timestamp}
# 3) Download each attachment binary immediately (authenticated; URLs expire)
# Do not defer — download within the same loop iteration
# 4) Import into Front
POST /inboxes/{inbox_id}/imported_messages
Content-Type: multipart/form-data
body_format=html
external_id=<source_event_id> # idempotency key; prevents duplicate imports
created_at=<source_event_unix_timestamp>
attachments[]=@downloaded-file
metadata[is_inbound]=true|false
metadata[should_skip_rules]=true # prevents historical imports from triggering automationsThe metadata[should_skip_rules]=true flag is critical for historical imports. Without it, every imported message triggers Front's current automation rules — tagging, routing, and auto-replies — as if the messages just arrived. (dev.frontapp.com)
The external_id field serves as an idempotency key. If the import pipeline fails and restarts, Front will skip any message whose external_id was already imported rather than creating duplicates.
Edge cases worth planning for
Deleted side conversations. Zendesk does not return deleted side conversations via the API. If agents deleted side conversations before the migration, that data is gone with no recovery path.
Side conversations on archived/closed tickets. The API returns side conversations regardless of ticket status, but verify your extraction script does not filter these out based on ticket state.
Duplicate attachments. The same file can appear in both the main ticket comment and a side conversation (e.g., an agent copies an attachment from the customer thread into a vendor email). Decide in advance whether to deduplicate by hash or accept the storage cost of importing both copies.
Character encoding in filenames. Zendesk preserves original filenames including Unicode characters. Front's import endpoint generally handles these, but filenames containing path separators (/, \) or null bytes will fail. Sanitize filenames during staging before upload.
Slack/Teams attachment limitations. Files shared natively in Slack or Teams may not be synced back to Zendesk's side conversation events. Zendesk may only have a reference URL pointing to Slack's CDN — which will break once Slack's retention policy deletes it or the workspace changes. Audit Slack/Teams side conversation content before migration to determine whether supplementary direct extraction is needed.
Deactivated agents. Front requires an author for comments and messages. Deactivated Zendesk agents often import as unassigned. Define a fallback attribution strategy before cutover — a system account, an operations lead, or a "Former Agent" placeholder — so historical ticket ownership is legible.
Quoted reply attachment propagation. Front's quoted replies carry forward prior attachments and inline images, which is how a thread can approach the 100-file ceiling even when the latest reply contains no new attachments. (help.front.com)
Side conversation event ordering. When mixing side conversation events with main ticket comments in a single chronological Front thread, verify that the created_at timestamps are sorted correctly before import. Out-of-order imports can result in a thread that reads nonsensically.
What to validate in a sample migration
Validate the ugliest records first, not the easy ones. Your sample set should include:
- Tickets with ordinary comment attachments
- Tickets with inline images embedded in comments (not attached as files)
- Email side conversations with attachments
- Slack or Microsoft Teams side conversations
- Child-ticket side conversations
- Threads close to Front's 100-file or 25 MB per-file limits
- Tickets assigned to deactivated Zendesk agents
- Tickets where the same attachment appears in both the main thread and a side conversation
Then validate outcomes that a CSV spot-check will not catch:
- Event parity: Did every side conversation event become either a Front message, a Front comment, or a deliberate documented omission?
- Attachment integrity: Can you actually open the migrated files, not just see filenames? Compare byte sizes between source and destination.
- Chronology: Are imported timestamps in the correct order, especially when side conversation events are interleaved with main thread events?
- Visibility: Did anything narrowly shared in Zendesk become broadly visible in a Front shared inbox?
- Author fallback: If an original Zendesk agent no longer exists in Front, is the fallback attribution acceptable to your team?
- Automation isolation: Did
should_skip_rules=trueprevent historical imports from triggering current routing rules? Verify no spurious auto-replies were sent. - Record-count parity: Total side conversation events extracted from Zendesk should equal the count of comments or messages created in Front, minus deliberate omissions. Track this number explicitly.
A good sample is not a random sample. Pick records that combine multiple failure modes in one place: private notes, inline images, large files, deactivated agents, and one or more side-conversation types. Those are the tickets that reveal whether the mapping logic is actually safe at scale.
Planning the migration scope
Before writing any migration code, audit your side conversation and attachment usage:
- Count side conversations per ticket. Use the incremental export endpoint to get a total. If fewer than 5% of tickets have side conversations, Strategy 1 (flatten to comments) is likely sufficient and avoids the complexity of managing a separate linked-conversation structure.
- Measure attachment volume. Sum the
sizefield across all attachment objects in both ticket comments and side conversation events. This tells you how much data needs to move and how long the download phase will take. - Identify oversized files. Flag every attachment over 25 MB and decide on your handling strategy before the first sample migration.
- Check for private attachments. If "Require authentication to download" is enabled in your Zendesk admin settings, your extraction script needs authenticated requests and must download files immediately — no deferred batch download.
- Audit Slack/Teams side conversations. Determine whether the content Zendesk captured is sufficient or whether you need to extract directly from Slack or Teams as a supplementary source.
- Identify deactivated agents. Pull your full Zendesk agent list and cross-reference against active Front users before migration. Define your fallback attribution policy for every deactivated agent.
For a complete pre-migration checklist covering contacts, tags, custom fields, and inbox configuration, see the Front Migration Checklist.
Data security during migration
Moving historical attachments requires temporarily handling sensitive customer data, PII, and potentially PHI. Staging databases used to buffer attachments and side conversation events should be protected by AES-256 encryption at rest and TLS 1.2+ in transit. Access should be restricted to the migration engineer or engineers directly working on the project — not a shared ticket queue.
Data minimization matters: staging databases should auto-purge no later than 30 days after project close to avoid retaining customer data beyond the migration window. If your source data includes PHI, ensure your migration provider or internal team has a BAA in place before extraction begins.
When to bring in help
If your Zendesk instance has more than a few thousand tickets with side conversations and attachments, the extraction-transform-load pipeline gets non-trivial fast. The combination of Zendesk's rate limits, private attachment URL expiry, Front's 25 MB ceiling, the single-message import constraint, and the side-conversation mapping decision creates enough moving parts that a test migration covering all failure modes is essential before going live.
ClonePartner has handled this scenario across hundreds of Zendesk-to-Front migrations, including instances with 200,000+ conversations. We run unlimited sample migrations until the data is right, every project is owned by a dedicated migration engineer, and pricing is fixed. For a case study of a full Zendesk history migration to Front, see how LawnGuru moved their complete ticket history.
Frequently Asked Questions
- Does Front support Zendesk side conversations?
- No. Front has no equivalent of Zendesk side conversations, and Front's built-in Zendesk importer does not cover them. During migration, side conversations must be mapped to Front comments (internal notes) or imported as separate tagged conversations. The right strategy depends on thread length and sensitivity.
- What is the attachment size limit for Front's import API?
- Front's import message endpoint caps attachments at 25 MB per message using multipart/form-data. Zendesk allows up to 50 MB per file, so any attachment between 25–50 MB must be hosted externally and linked, compressed, or split across messages.
- Why are inline images missing after migrating from Zendesk to Front?
- Zendesk's ticket comments API excludes inline images from the attachments array by default. You must pass include_inline_images=true when fetching comments, then download and re-upload each image to Front. Otherwise, images reference Zendesk URLs that will break when the account is closed.
- How do I extract side conversation attachments from Zendesk?
- Use the incremental side conversation events endpoint (GET /api/v2/tickets/side_conversations/events) to extract all events in bulk. Each event includes an attachments array with content_url for downloading. This endpoint requires admin-level API credentials.
- Can Front's native Zendesk importer bring over side conversations?
- No. Front's importer documentation lists conversations, messages, attachments, comments, and assignments — but not side conversations. Front also states the importer is not actively maintained. Side conversations require custom API extraction and mapping.