Deskpro to Puzzel Case Management Migration: Technical Guide
Technical guide for migrating from Deskpro to Puzzel Case Management. Covers API extraction, data model mapping, custom field translation, and phased cutover.
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
Deskpro to Puzzel Case Management Migration: Technical Guide
TL;DR: Deskpro → Puzzel Case Management Migration
A Deskpro to Puzzel Case Management migration is a structural data-model translation, not a CSV copy job. Deskpro's CSV export captures ticket properties and the first message only — it strips conversation threads, internal notes, and attachments. Extract through the Deskpro REST API v2 (or direct MySQL dumps for on-premise instances). Load into Puzzel through tenant-specific API ticket channels with Basic Token or OAuth authentication. Deskpro's Departments, Labels, Organizations, and Custom Fields do not map 1:1 to Puzzel's Teams, Tags, Categories, and Form Fields — each requires deliberate mapping decisions. Triggers, SLAs, and automation rules cannot be migrated programmatically. A typical mid-size migration (10,000–50,000 tickets) takes 2–4 weeks.
What Is a Deskpro to Puzzel Case Management Migration?
A Deskpro to Puzzel Case Management migration moves tickets, contacts, organisations, departments, labels, custom fields, conversation threads, internal notes, and attachments from Deskpro into Puzzel Case Management while preserving message history, timestamps, and relational integrity.
< cite index="70-10">Deskpro is a comprehensive helpdesk software that helps businesses manage customer support across multiple channels. It offers ticketing, live chat, voice, knowledge base, and automation features. < cite index="69-1">Departments are the main organizational structure of your Deskpro Helpdesk and allow you to control access to Tickets as well as define unique Ticket properties for your Agents. Tickets carry labels, custom fields, SLAs, and full conversation histories with agent notes. Deskpro is available in both cloud and on-premise deployments.
< cite index="16-1">Puzzel Case Management is a Case/Ticket management tool that provides your contact centre or helpdesk with the ability to manage written interactions in a secure and efficient way. < cite index="16-2,16-3">Each e-mail in the queue is converted into a support ticket and assigned a unique case/ticket ID which is then filtered, categorised and distributed to the right team or agent. It sits inside the broader Puzzel CX ecosystem — designed for contact centres that need skill-based routing, SLA tracking, and multi-channel queuing across email, SMS, and API channels.
Teams move from Deskpro to Puzzel for several reasons: consolidating ticketing into an existing Puzzel Contact Centre deployment, moving to a platform with tighter contact centre integration, or standardizing on Puzzel's unified agent desktop across voice and written channels. Whatever the driver, the migration is a structural translation — much like a Deskpro to Kustomer migration, Deskpro and Puzzel have fundamentally different data models.
Why CSV Is the Wrong Migration Path
Both platforms offer CSV export, but neither produces a file that the other can consume for a full migration.
Deskpro's CSV export limitations: < cite index="23-4,23-5">Deskpro's CSV Importer allows you to upload tickets, users, and organizations via CSV format. Keep in mind that ticket imports using CSV are limited—they only include ticket properties and the first message, excluding ticket message content and attachments. The CSV ticket export from Deskpro's reporting module similarly captures metadata and field values but not full conversation threads, inline images, or binary attachments. Deskpro's own export guidance says report-based exports work in small chunks (a constraint we also highlight in our Deskpro to Help Scout migration guide), suggests slicing large ranges by ticket ID, warns that reports handle only about 55 fields, and recommends the API for anything larger.
Puzzel's CSV export limitations: < cite index="42-1">To export a specific range of tickets, go to the Tickets page, use the Ticket Attributes widget to filter the Tickets List for only those Tickets you wish to export. This export captures ticket attributes and metadata, not full message bodies or attachment binaries. Puzzel's Report Builder produces CSV, XLSX, and PDF output — useful for reconciliation after a load, not as a migration transport (a limitation that also applies when extracting data for a Puzzel to Kayako migration).
The result: API extraction from Deskpro and API loading into Puzzel are both mandatory for any migration that needs to preserve conversation history, notes, and attachments.
Deskpro Data Extraction: API and Database Options
Your extraction method depends on your Deskpro deployment model.
Deskpro Cloud: REST API v2
< cite index="6-1,6-2">The Deskpro API is a REST API that runs over HTTP(S). All API requests are made to a URL that begins with http://example.com/api/v2/.
< cite index="8-11,8-12,8-13">The most common way to use the API is via an API key. An admin can create keys from Admin > Apps > API Keys. To authenticate an API request, you send an Authorization header like Authorization: key YOURKEY.
For migration work, use a superuser API key. < cite index="3-3,3-4">A superuser API key is a special type of API key that is not associated with a particular agent. Instead, it is able to make requests as any agent. This gives you access to all tickets across all departments without per-agent permission restrictions.
Key extraction endpoints:
| Entity | Endpoint | Notes |
|---|---|---|
| Tickets | GET /api/v2/tickets |
Paginated, 10 per page default |
| Ticket messages | GET /api/v2/tickets/{id}/messages |
Full thread with HTML body |
| Ticket attachments | GET /api/v2/tickets/{id}/attachments |
Returns blob metadata |
| People (contacts) | GET /api/v2/people |
Includes custom person fields |
| Organizations | GET /api/v2/organizations |
Linked to people |
| Agents | GET /api/v2/agents |
Needed for agent mapping |
| Departments | GET /api/v2/ticket_departments |
Hierarchical structure |
| Custom fields | GET /api/v2/ticket_custom_fields |
Field definitions |
| Labels | GET /api/v2/ticket_labels |
Free-form tags |
# Extract tickets from Deskpro with pagination
curl -s -H "Authorization: key 1:YOUR_API_KEY" \
-H "Accept: application/json" \
"https://yourhelp.deskpro.com/api/v2/tickets?page=1&per_page=200&order_by=id&order_dir=asc" \
| jq '.data[] | {id, subject, status, department_id, person_id, date_created}'For deeper source-side detail, see our Deskpro export guide.
Deskpro On-Premise: Direct Database Extraction
If you host Deskpro on your own infrastructure, bypass the REST API entirely. Deskpro stores its data in a MySQL database. Taking a direct SQL dump or connecting a script to a database replica is significantly faster and avoids API rate limits.
Key tables to target:
tickets— core ticket metadatatickets_messages— agent replies, user replies, internal notespeople— users and agentsorganizations— companiesblobs— attachment metadata and file paths
Pagination and Rate Limits
< cite index="32-1,32-2,32-3">You can specify API limits on every API key you create. For example, it is not uncommon to set an upper limit on an API key to prevent some kind of mistake in its use. You can define these limits in terms of an hourly limit or a daily limit. < cite index="32-4,32-5">For cloud customers, there is also a default global limit to prevent abuse. You can raise this on request by contacting us at support@deskpro.com.
Pagination cap and active-ticket defaults: Community reports indicate that Deskpro's API returns a maximum of 1,000 results per filtered query. If you have more than 1,000 tickets matching a filter, partition your extraction by date range, department, or status. Deskpro's API also returns only active tickets by default — if you do not explicitly request inactive or archived tickets, your extraction will silently miss large parts of your history. Always verify meta.pagination.total in your responses.
Estimating extraction time: Use this model rather than a fixed assertion.
extraction_hours = (ticket_count / requests_per_second) × message_depth_factor + (attachment_count × avg_upload_seconds / 3600)
Where:
requests_per_second≈ 2–5 for Deskpro Cloud under standard rate limitsmessage_depth_factor= 1 + (avg_messages_per_ticket / 10) — each ticket requires one messages sub-requestavg_upload_seconds≈ 1–3 seconds per attachment blob depending on size
Example: 50,000 tickets, average 8 messages per ticket, 20% with attachments averaging 2 attachments each:
- Ticket list requests: 50,000 / 200 per page = 250 paginated requests
- Messages requests: 50,000 × 1 = 50,000 sub-requests
- Attachment requests: 10,000 × 2 = 20,000 blob downloads
- At 2 requests/sec sustained: approximately 10–12 hours including retries and backoff
Attachment Extraction
Each attachment blob from Deskpro has a download_url in the API response. Deskpro secures attachments — you cannot pass a URL to Puzzel and expect it to download the file. Your migration middleware must:
- Query the Deskpro API for the attachment blob.
- Download the file into temporary storage using the Deskpro API token, preserving the original filename and MIME type.
- Convert the file to Base64 or upload via
multipart/form-datato Puzzel's attachment endpoint. - Map the resulting Puzzel attachment ID to the corresponding message payload.
Puzzel Case Management: API Channels and Loading
Setting Up the API Ticket Channel
< cite index="60-1,60-2">Go to: Settings > Ticket Channels > API. Click the button on the top right. < cite index="60-4,60-5,60-6">Select an authentication level. Global (Access to all ticket) or select an Organisation. Select your Token Type (Basic Token OR oAuth Token).
Just as we outline in our Zoho Desk to Puzzel migration guide, this creates an inbound API channel that accepts ticket creation requests. < cite index="11-1,11-2">The Help menu (Help -> API Documentation) now links directly to the newly introduced API documentation powered by Swagger UI. Interactive Reference: Easily browse, search, and test API endpoints with a modern, interactive interface. Each tenant gets its own Swagger instance — use this as your primary reference for payload schemas and endpoint availability.
Puzzel API rate limits: Puzzel does not publish a universal rate limit in its public documentation — limits are tenant-configured and may vary by contract tier. Before building your loading scripts, explicitly ask your Puzzel account team for:
- Maximum ticket creation requests per minute on the API channel
- Maximum message append requests per minute
- Maximum attachment upload size per request (the outgoing email size limit is documented at 10 MB, but the API upload limit may differ)
- Whether IP whitelisting applies to OAuth token requests from your migration host
Without this information, your loading scripts will need aggressive exponential backoff and a per-request delay that you tune empirically during test loads. Start with 1 request per second and increase only after confirming no 429 Too Many Requests responses across 500+ consecutive requests.
Verify the API on your actual target tenant before building the loader. Puzzel's API features ship as release-driven additions rather than a single static public spec. Recent releases added tag and category lookup, richer ticket search, reply endpoints, inbound-message endpoints, and clearer API change tracking in ticket timelines. IP whitelisting can also block OAuth token requests from non-whitelisted addresses. Always confirm capabilities on your specific tenant.
For the Puzzel import side, see our Puzzel export and import reference.
Ticket Creation and Message Loading
Puzzel's API ticket channel accepts inbound ticket payloads. The typical workflow:
- POST a ticket payload with subject, body (HTML), sender contact information, team assignment, and category values.
- POST follow-up messages (replies and notes) as subsequent interactions on the created ticket.
- POST attachments linked to specific messages.
< cite index="15-5,15-6,15-7">When adding a 'note' to a ticket using the API, it is now possible to add a flag to a submitted 'note' to mark it as public or private. When a note has been marked as private, it will not be exposed when retrieving ticket content via an API channel. Map Deskpro's internal notes (agent-only) to Puzzel private notes and customer-facing replies to public messages.
Example payload structure for appending a message:
{
"caseId": "PUZ-12345",
"messageBody": "Customer replied regarding the invoice.",
"direction": "Inbound",
"channel": "Email",
"authorId": "contact_8891",
"isInternal": false
}Contact Deduplication Behavior in Puzzel
A frequently overlooked scenario: many Puzzel tenants are not empty at migration time. If your organisation has been using Puzzel for voice or another channel, contacts may already exist in Puzzel with the same email address as Deskpro contacts. Puzzel's behavior when you POST a contact that shares an email with an existing contact is not guaranteed to merge silently — depending on tenant configuration, you may get a duplicate record, a rejected request, or a merge.
Before loading any contacts:
- Export the existing Puzzel contact list via the API.
- Build a local lookup table: Deskpro email → existing Puzzel contact ID.
- For contacts with a matching email, skip creation and use the existing Puzzel contact ID when linking tickets.
- For contacts without a match, create new records and store the returned Puzzel contact ID.
- Log every contact POST response — inspect for unexpected duplicate warnings or silent merges.
Failing to handle this results in tickets linked to phantom duplicate contacts that do not appear in Puzzel's contact search and cannot receive outbound email correctly.
Ticket Status Mapping: Deskpro → Puzzel
Deskpro and Puzzel use different status models. This table shows the recommended approximations — note where no direct equivalent exists.
| Deskpro Status | Puzzel Equivalent | Notes |
|---|---|---|
| New | Open / Unassigned queue state | Deskpro "new" means unread and unassigned. Puzzel represents this via queue position, not a discrete status field. |
| Awaiting Agent | Open | Map to Open. No Puzzel status directly represents "pending agent response." |
| Awaiting User | Pending | Closest match if your Puzzel tenant has a Pending status configured. Verify existence on your tenant. |
| Resolved | Resolved / Closed | Direct match in most tenant configurations. |
| Archived | Closed | Map archived tickets to Closed. Puzzel does not have a separate archive state. |
| Spam | No equivalent | Exclude spam tickets from migration or load into a dedicated "Spam Review" team for manual triage. |
Because Puzzel queue states are partly determined by team routing configuration rather than a simple status field, validate this mapping against your specific Puzzel routing design before writing the load script.
Timestamp Preservation
A major constraint in helpdesk migrations is preserving the original ticket creation date. Many APIs default to stamping createdAt with the time the request is received.
Verify whether your Puzzel tenant's API channel supports a createdAt override on ticket creation. If it does not, all imported tickets will stamp with the import time. Fallback strategy:
- Inject the original Deskpro creation date into the first message of the ticket thread.
- Format it clearly:
[Original Ticket Created: 2023-10-14 09:30:00 UTC]. - This ensures agents have historical context even if the system-level timestamp reflects the migration date.
Confirm this with Puzzel support before writing your loading scripts.
Data Model Mapping: Deskpro → Puzzel
This is where most migration complexity lives. The two platforms organize ticket data differently.
Structural Entity Mapping
| Deskpro Entity | Puzzel Entity | Mapping Notes |
|---|---|---|
| Department | Team | Deskpro supports hierarchical departments (parent/child). Puzzel Teams are flat. Flatten or concatenate names. In PCC-linked tenants, Team changes affect queue behavior. |
| Label | Tag | 1:1 conceptual mapping. Deskpro labels are free-form strings. Puzzel tags apply to tickets. Clean up synonyms before load. |
| Organization | Organisation | Direct mapping. Verify field schema differences. |
| Person (user/contact) | Contact | Map email, name, phone. Deskpro people can have multiple emails — Puzzel contacts may handle multi-email differently. |
| Agent | Agent/User | Map by email. Agents who no longer exist should map to a "Legacy Agent" placeholder. |
| Custom Field | Form Field | Deskpro custom fields are per-department. Puzzel Form Fields are tied to Forms and Categories. Requires manual mapping per field. |
| SLA | SLA | Cannot be migrated programmatically. Recreate manually in Puzzel. |
| Trigger / Escalation | Event Rule / Inbound Rule | Cannot be migrated. Rebuild in Puzzel's rule engine. |
| Knowledge Base Article | N/A | Puzzel Case Management does not include a knowledge base module. Migrate KB content separately if needed. |
Custom Field Type Translation
Deskpro supports these custom field types: text, textarea, choice (dropdown), multi-choice, checkbox, date, number, toggle, and hierarchical (nested choice). < cite index="53-5">Here is an example of declaring a Ticket Custom Field of type text with an alias and a title.
Puzzel Form Fields support text, dropdown, checkbox, date, and number types. Key translation issues:
- Nested/hierarchical choice fields in Deskpro have no direct equivalent in Puzzel. Flatten into single-level dropdowns or split into multiple fields.
- Multi-choice fields may need to map to multiple checkbox fields or a comma-separated text field, depending on Puzzel's form configuration.
- Toggle fields (boolean) map to checkbox fields.
Department → Team Flattening
Deskpro allows nested departments like Support > Technical > Networking. Puzzel Teams are flat. Three options:
- Concatenate: Create Puzzel Teams like "Support - Technical - Networking".
- Leaf-only: Only create Teams for the deepest level ("Networking").
- Top-level only: Collapse everything under the top-level department ("Support").
Option 1 preserves the most information but creates long Team names. Option 2 works when most tickets sit at leaf departments. Decide based on your reporting requirements in Puzzel.
Puzzel Form Field Coupling: Why It Breaks Silently
Deskpro custom fields are scoped per department. A field named "Contract ID" defined in the Support department is a completely independent object from a field named "Contract ID" in the Billing department — they have separate field IDs, separate value histories, and separate display rules.
Puzzel Form Fields work differently: a single Form Field object is defined at the field level and then referenced by one or more Forms. If you create one "Contract ID" field and attach it to both your Support Form and your Billing Form, you have created shared state between those two forms.
The consequence: if you later rename the field (for example, changing "Contract ID" to "Contract Reference"), that rename propagates to every Form that references it simultaneously. For historical tickets displayed under the old category, the field label in the ticket timeline changes retroactively — there is no version history for field labels. Similarly, if you change the field type or delete the field, every Form referencing it is affected.
This is not a theoretical risk. It occurs whenever a migration engineer maps multiple Deskpro department-scoped fields to a single Puzzel Form Field because the names were identical. The safe approach:
- Default to creating separate Form Fields per Form, even if the names are identical.
- Consolidate fields only after confirming they represent the same logical data with the same value set across all departments.
- Document every field-to-form relationship before going live.
Design Decisions That Cause Rework
Several Puzzel-specific behaviors catch teams off guard during migration:
Note visibility. Puzzel added settings that can make notes and message forwards visible to authenticated API channels or the Puzzel Customer Hub. The published recommendation is to keep those settings disabled unless you have a specific need. Decide explicitly whether Deskpro agent-only notes stay internal, become structured post-it notes, or are excluded from customer-facing history.
Attachment behavior. Puzzel documents a 10 MB outgoing email size limit. Attachments larger than that may be represented as downloadable links rather than inline files. If your Deskpro history includes many large attachments, test how the receiving team wants them represented after migration.
Active vs. inactive history. Deskpro's API returns only active tickets by default. If you do not explicitly account for inactive/archived tickets, your first rehearsal can look complete while missing large parts of your archive.
Multi-channel email processing. Puzzel's Multi-Email Channel Ticket Processing feature can create or update multiple tickets from a single email when multiple configured channel addresses are involved. During cutover, this is either useful or disastrous depending on your routing design. Decide whether it stays off until routing is stable.
Ticket URL rot. Deskpro ticket URLs follow the pattern https://yourhelp.deskpro.com/tickets/TICKETID. After migration, these URLs in email history, internal Slack messages, and saved bookmarks will no longer resolve to the correct ticket. Decide before cutover whether you will:
- Leave Deskpro in read-only mode permanently (preserves URL access but requires maintaining the instance).
- Redirect the old Deskpro domain to a static archive page.
- Accept the link rot and document it in your migration announcement to staff.
User/contact notification. Puzzel does not automatically notify contacts that their ticket history has moved platforms. If your contacts have access to a self-service portal, decide whether to send a migration announcement. If ticket IDs change (Deskpro IDs to Puzzel IDs), contacts referencing old ticket numbers in follow-up emails will need staff assistance to locate their history.
Step-by-Step Migration Process
Phase 1: Audit and Mapping (3–4 days)
- Inventory Deskpro data — count tickets by department, status, and date range. Count contacts, organizations, custom fields, labels. Distinguish active vs. inactive tickets.
- Map Deskpro entities to Puzzel entities — use the mapping table above as a starting point. Write the mapping as versioned config, not tribal knowledge in a spreadsheet.
- Decide scope — are you migrating all historical tickets or only open/recent ones? Migrating only open tickets plus the last 12 months of closed tickets is a common pattern that reduces volume by 60–80%.
- Set up Puzzel — create Teams, Categories, Forms, Form Fields, Organisations, and Tags in Puzzel before loading any tickets. If your teams depend on Contact Centre routing, validate every Team-to-queue relationship up front.
- Create the API ticket channel in Puzzel and generate authentication tokens. Verify endpoint behavior on your specific tenant via the Swagger UI.
- Confirm Puzzel API rate limits and timestamp override support with your Puzzel account team before writing a single line of loading code.
# Example: versioned mapping config
department_to_team:
support-emea: Support EMEA
billing: Billing
field_rules:
contract_id: organisation_field
product_family: category
entitlement_tier: form_field
mailbox_rules:
support@brand-a.example:
team: Brand A Support
status_map:
new: open
awaiting_agent: open
awaiting_user: pending
resolved: resolved
archived: closed
spam: EXCLUDE
agent_fallback:
deleted_agents: legacy-agent@yourcompany.comPre-Flight Checklist (Run Before Phase 2)
Before extracting a single ticket from Deskpro, verify:
- Superuser API key created and tested — confirm it returns tickets from all departments
-
meta.pagination.totalverified against Deskpro admin ticket count — numbers must match - Inactive/archived ticket count confirmed — run a separate API query with status filters and compare against admin reports
- Puzzel API ticket channel created and token tested with a single POST
- Puzzel rate limit confirmed with account team (or empirically validated at 1 req/sec over 500 requests)
- Timestamp override behavior confirmed on Puzzel tenant
- Contact deduplication behavior tested: POST a contact with an existing email and observe the response
- Puzzel form fields created and IDs documented — do not load tickets before forms exist
- Status mapping table reviewed against your Puzzel tenant's actual configured statuses
- Attachment size limit confirmed: test a 15 MB attachment upload to Puzzel API
- Deleted Deskpro agent list compiled — map to Legacy Agent placeholder
- Multi-channel email processing setting confirmed (on or off) for cutover
Phase 2: Extraction from Deskpro (3–5 days)
- Extract reference data first — departments, agents, custom field definitions, labels, organizations, people.
- Extract tickets in batches — paginate through
GET /api/v2/tickets, partitioning by date range if your total exceeds 1,000 per query. Explicitly include inactive/archived tickets. - For each ticket, extract messages —
GET /api/v2/tickets/{id}/messagesreturns the full thread. - For each ticket with attachments, download blobs — store with ticket ID reference and original metadata.
- Store everything in a staging format — JSON lines (JSONL) or a staging database. Never transform in place.
Phase 3: Transform and Test Load (3–5 days)
- Build an ID mapping table — Deskpro IDs → Puzzel IDs for every entity type (agents, contacts, organisations, teams, tags, form fields).
- Translate ticket payloads — for each Deskpro ticket, produce a Puzzel-compatible payload with mapped team, categories, form field values, tags, and status.
- Translate message threads — order messages chronologically. Map agent replies to agent messages, customer replies to contact messages, and internal notes to private notes.
- Handle HTML content — Deskpro stores messages as HTML. Puzzel accepts HTML in ticket bodies. Strip or remap any Deskpro-specific inline image references — download inline image blobs, re-upload to Puzzel, and rewrite
<img src>URLs. Skipping this step results in broken images in migrated threads. - Validate with a test load — push 50–100 tickets into a Puzzel test environment. Verify field mapping, thread ordering, attachment integrity, note visibility, and status assignment. Include at least 5 tickets with attachments over 8 MB to test the size boundary.
Phase 4: Production Load and Delta Sync (2–3 days)
- Load contacts and organisations first — these must exist in Puzzel before tickets reference them. Check for duplicates before each contact POST using your pre-built lookup table.
- Load tickets in chronological order — oldest first. This preserves ticket numbering sequence if Puzzel auto-assigns sequential IDs.
- Load messages per ticket in order — first message, then each reply and note chronologically.
- Upload attachments — link each attachment to its corresponding message. Log every upload response and retry failures with exponential backoff (start at 2 seconds, cap at 60 seconds, maximum 5 retries).
- Delta sync — after the bulk load, extract any tickets created or updated in Deskpro since extraction started (filter by
date_updated). Load these as a delta batch. Run the delta sync multiple times, closing the gap between the two systems.
Phase 5: Validation and Cutover (2–3 days)
- Count validation — total tickets, contacts, and organisations in Puzzel must match Deskpro source counts.
- Spot-check 20–50 tickets — verify message thread order, attachment presence, custom field values, team assignment, tag assignment, and status. Focus on complex tickets: reopened tickets, cross-department handoffs, heavy note usage, large attachments.
- Verify edge cases — merged tickets, deleted-then-restored tickets, tickets with 50+ messages, tickets with attachments exceeding Puzzel's size limits, tickets assigned to deleted agents.
- Final cutover — schedule a maintenance window. Run one final delta sync. Redirect inbound email channels to Puzzel. Disable Deskpro ticket creation. If Puzzel multi-channel email processing is enabled, verify shared-mailbox behavior before opening traffic.
- Keep Deskpro in read-only mode for 2–4 weeks post-cutover as a reference fallback. Communicate the old-ticket-ID-to-new-ticket-ID mapping to your support team so they can handle contacts who reference Deskpro ticket numbers.
For a zero-downtime approach to this cutover process, see our zero-downtime help desk migration guide.
Edge Cases and Failure Modes
Merged tickets in Deskpro. Deskpro supports ticket merging, where two or more tickets are combined into one. The merged ticket retains all messages from both originals, but the original ticket IDs may appear as redirects or stubs. Your extraction script should handle HTTP 301 redirects or merged_into fields gracefully.
Orphaned agent assignments. If a Deskpro ticket is assigned to an agent who left the company years ago, that agent does not exist in Puzzel. Puzzel will reject the ticket creation if you pass an invalid assignee_id. Maintain a mapping table that routes deleted Deskpro agents to a "Legacy Agent" placeholder in Puzzel.
Attachment size mismatches. Deskpro may allow attachments up to 20–50 MB (configurable per instance). Puzzel documents a 10 MB outgoing email size limit, and per-attachment API limits may differ. Your script must catch 413 Payload Too Large errors and log them rather than crashing the migration loop.
Inline images vs. attachments. Deskpro stores inline images (pasted into the message body) as blobs referenced by <img> tags with internal URLs. These URLs break after migration. Download each inline image blob, re-upload to Puzzel, and rewrite the <img src> in the message HTML.
Rate limit halts. Deskpro Cloud enforces API rate limits. If your script lacks exponential backoff, Deskpro returns 429 Too Many Requests errors. Read the Retry-After headers and pause execution accordingly. Apply the same logic to Puzzel API calls — if you have not confirmed the Puzzel rate limit, treat any 429 as a signal to halve your request frequency and re-test before resuming.
Broken routing from wrong mapping. If Departments are mapped as Tags instead of Teams, you preserve labels but break operating flow. In PCC-linked tenants, Team changes affect queue behavior — routing is not cosmetic.
Leaked notes. Teams that assume note visibility settings rather than checking Puzzel's public/private configuration can expose agent-internal notes to customers. Verify note privacy settings on your Puzzel tenant before loading a single note.
Duplicate tickets at cutover. If a shared mailbox forwards into several Puzzel channels while multi-channel email processing is enabled, a single inbound email can create multiple tickets.
Duplicate contacts from partial Puzzel population. If your Puzzel tenant already has contacts (from voice or another channel), POSTing Deskpro contacts without checking for existing email matches creates duplicates. Tickets linked to duplicate contacts will not appear correctly in contact timelines and outbound email may route to the wrong record.
Deskpro ticket URL rot. Deskpro ticket URLs become unreachable after the instance is decommissioned. Decide before cutover how to handle saved links in email history and internal documentation.
Multi-brand Deskpro deployments. A single Deskpro instance can serve multiple brands through separate department hierarchies and Help Center portals. If your Puzzel deployment uses separate tenants per brand, you are effectively running N migrations in parallel — each requires its own API channel, field mapping, and team configuration. Add 1–2 weeks per additional brand.
What Cannot Be Migrated
Be explicit with stakeholders about what stays behind:
- Triggers and escalations — must be rebuilt in Puzzel's Event Rules and Inbound Rules engine. < cite index="47-14,47-15">The Control Centre centralises all essential functions, allowing your managers to view, route and report on inbound ticket queues. Enhance efficiency by letting them configure automated workflows including establishing inbound rules and events—all from one place. Document every Deskpro trigger before migration — it is easy to miss one that fires on a rare condition.
- SLA policies — recreate manually in Puzzel.
- Macros and snippets — Puzzel uses response templates; recreate manually.
- Knowledge base articles — Puzzel Case Management has no KB module. Migrate KB content separately.
- Chat transcripts — Deskpro live chat history does not map to Puzzel's ticketing model.
- User portal customizations — Deskpro Help Center themes and branding do not transfer.
- Report definitions — Puzzel has its own Report Builder; recreate dashboards.
- Webhook configurations — Deskpro webhooks must be reconfigured as Puzzel Outbound Integrations.
- Historical Deskpro ticket URLs — links in email history, bookmarks, and internal documentation will break unless Deskpro remains accessible in read-only mode.
- Agent performance history — Deskpro's agent reporting history (tickets resolved per agent, response times) does not transfer. Export these reports from Deskpro before decommissioning.
Timeline Estimates
Estimate your migration duration using these inputs rather than treating the table as fixed:
Variables that extend duration:
- Custom field count: each field type mismatch (hierarchical → flat, multi-choice → checkbox) adds mapping and testing time
- Attachment volume: large attachment counts dominate extraction time
- Thread depth: tickets with 50+ messages take significantly longer per ticket than tickets with 2–3 messages
- Multi-brand setup: each additional brand adds 1–2 weeks
- Puzzel tenant readiness: if Teams, Forms, and Categories are not pre-built, load cannot start
| Migration Size | Ticket Count | Estimated Duration | Dominant Variable |
|---|---|---|---|
| Small | < 10,000 | 1–2 weeks | Setup time dominates |
| Mid-size | 10,000–50,000 | 2–4 weeks | Field mapping complexity |
| Large | 50,000–200,000 | 4–6 weeks | Extraction and attachment volume |
| Enterprise | 200,000+ | 6–10 weeks | Parallel brand migrations, validation |
These estimates assume: single Deskpro instance, single Puzzel tenant, available engineering capacity for full-time work during the project, and Puzzel tenant pre-configured before loading begins. Scope migrations against the complexity inputs above, not solely against ticket count.
Tools and Approach Comparison
| Approach | Pros | Cons |
|---|---|---|
| Custom scripts (API-to-API) | Full control, handles edge cases, preserves all data | Requires engineering time, must handle rate limits |
| Third-party migration tool | Lower upfront effort | May not support Puzzel as a target, limited field mapping flexibility |
| CSV export/import | Quick for metadata-only | Loses threads, notes, attachments — not viable for full migration |
| Managed migration service | Expert handling, faster timeline, risk mitigation | External cost |
For most teams, custom API-to-API scripts are the correct approach. Third-party tools like Help Desk Migration support Deskpro as a source but may not support Puzzel Case Management as a target — verify before committing.
Summary: Key Technical Decisions
Before writing a line of code, these decisions must be made explicitly:
- Scope — all historical tickets, or open + rolling 12 months?
- Department → Team strategy — concatenate, leaf-only, or top-level?
- Custom field isolation vs. sharing — separate Form Fields per Form, or shared? (Default: separate)
- Note visibility — private notes stay private, or exposed to Customer Hub?
- Timestamp strategy — API override if available, or inject into first message?
- Deleted agent handling — Legacy Agent placeholder email?
- Large attachment handling — exclude, link, or attempt upload?
- Status mapping — confirm Puzzel's available statuses against your Deskpro status set
- Contact deduplication — lookup-before-POST strategy confirmed?
- Cutover URL strategy — Deskpro read-only, redirect, or accept link rot?
- Multi-channel email processing — off during cutover?
- User/contact notification — migration announcement to contacts?
Document these decisions in the versioned mapping config before Phase 2 begins. Changing them mid-migration requires re-running affected transformation and load steps.
Frequently Asked Questions
- Can I migrate from Deskpro to Puzzel Case Management using CSV export?
- No. Deskpro's CSV export only includes ticket properties and the first message — it strips full conversation threads, internal notes, and attachments. You must use the Deskpro REST API v2 for extraction and Puzzel's API ticket channel for loading.
- How do Deskpro Departments map to Puzzel Case Management?
- Deskpro supports hierarchical departments (parent/child nesting), but Puzzel Teams are flat. You must flatten by concatenating names (e.g., 'Support - Technical - Networking'), using leaf-only mapping, or collapsing to top-level departments. In PCC-linked tenants, Team mapping also affects queue behavior.
- Can I migrate Deskpro triggers, SLAs, and macros to Puzzel?
- No. Deskpro triggers, escalations, SLA policies, and macros cannot be exported as configuration and imported into Puzzel. You must manually recreate equivalent logic using Puzzel's Event Rules, Inbound Rules, and SLA configuration.
- How long does a Deskpro to Puzzel migration take?
- A mid-size migration (10,000–50,000 tickets) typically takes 2–4 weeks: 3–4 days for planning, 3–5 days for extraction, 3–5 days for transformation and testing, 2–3 days for production load, and 2–3 days for validation and cutover.
- What happens to tickets assigned to agents who no longer work here?
- If you attempt to assign a migrated ticket to a user ID that does not exist in Puzzel, the API will reject it. Map deleted or inactive Deskpro agents to a generic 'Legacy Agent' placeholder account in Puzzel to preserve the ticket history.