Pylon to Kayako Migration: The Complete Technical Guide
Technical guide to migrating from Pylon to Kayako. Covers API constraints, data model mapping, rate-limit math, attachment handling, and zero-downtime 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
Pylon to Kayako Migration: The Complete Technical Guide
TL;DR: Pylon to Kayako migration requires a custom API-based ETL pipeline — there is no native import path. Pylon's 10 req/min issue export limit and Kayako's undisclosed rate limits (HTTP 429 with Retry-After header) make throughput planning essential. Expect 5–12 business days for planning, execution, QA, and delta sync. CSV exports strip thread context and orphan attachments — do not use them.
Migrating from Pylon to Kayako means moving from a Slack-first, AI-native B2B support platform to a multi-channel helpdesk built around email conversations, live chat, and social channels. There is no checkbox, no wizard, no one-click migration tool. You need a custom API-based ETL pipeline — extract from Pylon's REST API (api.usepylon.com), transform the data model, and load into Kayako's REST API.
The realistic timeline is 5–12 business days — broken down as approximately 1 day for audit and pre-creation, 2–4 days of pipeline runtime (dominated by message extraction at Pylon's 20 req/min limit), 1–2 days for QA, and 1 day for delta sync and cutover. The single biggest constraint is Pylon's issue list endpoint, rate-limited to 10 requests per minute with a mandatory time range parameter capped at 30 days per call.
For teams evaluating alternative migration paths, see our guides on migrating from Pylon to Zendesk, Missive, or eDesk.
Why Teams Move from Pylon to Kayako
Pylon is purpose-built for B2B support where conversations happen in shared Slack channels, Microsoft Teams, and Discord. Its core object is the Issue — a conversational thread tied to an Account with messages, internal notes, custom fields, and CRM-synced metadata.
Kayako is a multi-channel helpdesk where the core object is the Conversation (API field: cases) — a structured support record with messages, notes, SLAs, custom fields, and automation triggers.
Teams make this move for three concrete reasons:
- Multi-channel requirements. Kayako natively supports email, live chat (Kayako Messenger), Facebook, Twitter, and Help Center forms. Pylon is limited to Slack Connect, MS Teams, and Discord — no email-first workflow.
- eCommerce or SMB support workflows. Kayako's conversation-centric model with customer Journey timelines and built-in CSAT ratings suits high-volume, customer-facing support. Pylon's Account Intelligence (health scores, CRM sync, partner account hierarchies) is designed for B2B account management, not ticket volume throughput.
- Self-hosted option. Kayako Classic is available as an on-premise deployment — a hard requirement for some regulated industries. Pylon is cloud-only with no self-hosted option.
When extracting data from Pylon, you are pulling unstructured, chat-based interactions containing Slack Block Kit JSON. When loading into Kayako, you must force those interactions into a rigid schema of Conversations, Messages, and standardized user profiles. If you fail to map this correctly, your Kayako instance will be flooded with unreadable, out-of-order chat fragments containing raw Slack markup.
Pylon vs. Kayako: Data Model Mapping
The mapping is not one-to-one. Pylon's data model is account-centric and conversational. Kayako's is conversation-centric with organizations as a secondary grouping.
| Pylon Object | Kayako Equivalent | API Field (Kayako) | Notes |
|---|---|---|---|
| Issue | Conversation / Case | cases |
Core ticket object. Pylon Issues are Slack-threaded; Kayako Conversations are channel-agnostic. |
| Account | Organization | organizations |
Pylon Accounts carry health scores, CRM sync, partner accounts. Kayako Organizations store name, domains, and custom fields only. Map CRM IDs to Kayako organization custom fields to preserve external integrations. |
| Contact | User (customer type) | users |
Pylon contacts are tied to Slack IDs (U0123ABCD); Kayako requires a valid email address as the unique identifier. Contacts without email must be resolved via CRM or Slack API before import. |
| Message (reply) | Message (reply) | messages |
Slack Block Kit JSON and Slack Markdown must be converted to HTML before import. Raw Slack markup renders as unreadable text in Kayako. |
| Message (internal note) | Note | notes |
Direct mapping. Kayako supports internal notes on conversations. |
| Tag | Tag | tags |
Direct mapping. Both support tags on conversations. |
| Custom Field | Custom Field | custom_fields |
Kayako has three custom field scopes: conversation, user, and organization. Pylon does not make this distinction. Pre-create all fields in Kayako Admin before import. |
| Team | Team | teams |
Direct mapping. |
| User (agent) | Agent | agents |
Agents in Kayako require role assignment. Must exist before conversations can be assigned. |
| Knowledge Base Article | Help Center Article | articles |
Kayako Help Center uses a Category → Section → Article hierarchy. |
| Knowledge Base Collection | Help Center Section | sections |
Pylon Collections → Kayako Sections within Categories. |
| Attachment | Attachment | attachments |
Pylon attachment URLs are pre-signed and time-limited. Download to local staging immediately; do not defer. |
| Feature Request | ❌ No equivalent | — | Kayako has no native feature request tracking. Export fields to CSV and store key data (title, status, vote count, linked issues) in a Kayako organization or conversation custom field for reference. |
| Account Activity / Highlights | ❌ No equivalent | — | Pylon's Account Intelligence data (health scores, highlights, CRM sync status) has no Kayako counterpart. Archive to data warehouse before migration; this data cannot be reconstructed post-cutover. |
| Snooze state | ❌ No direct equivalent | — | Pylon Issues can be snoozed with a specific wake time. Kayako has no snooze concept. Use Pending status plus a Kayako monitor automation triggered by updated_at as a workaround. Wake times are lost. |
Status Mapping
Kayako Cloud's default conversation statuses are New, Open, Pending, and Completed. Custom statuses require Kayako Classic. Kayako uses status as the API field name on the cases resource.
| Pylon Status | Kayako Status | Downstream Impact |
|---|---|---|
open |
open |
Direct mapping. |
pending |
pending |
Direct mapping. |
on_hold |
pending |
No native "on hold" in Kayako Cloud. Map to Pending or create a custom status in Classic. Agents lose the visual distinction — document this change in your runbook. |
snoozed |
pending |
Wake time metadata is lost. Snoozed issue count: audit before migration to assess impact. |
closed |
completed |
Kayako uses "Completed" as its terminal state, not "Closed." |
Kayako's reply-to-Open status behavior is hardcoded in core code. Every inbound customer reply automatically moves a conversation to Open status, regardless of trigger or automation rules. This behavior cannot be overridden. If your post-migration workflow depends on conversations staying in Pending or Completed after a customer responds, redesign the workflow before cutover — not after.
API Constraints: Extraction from Pylon
Pylon's REST API lives at api.usepylon.com and uses Bearer token authentication (Authorization: Bearer {token}). Only Admin users can generate API tokens via the Pylon dashboard under Settings → API.
| Endpoint | Rate Limit | Page Size | Key Constraint |
|---|---|---|---|
GET /issues |
10 req/min | Up to 20,000 per call | Requires start_time and end_time (ISO 8601); max window is 30 days. Mandatory parameter — omitting it returns an error. |
GET /issues/{id}/messages |
20 req/min | Cursor-paginated | Must call per-issue to get full message history. Primary time constraint for large workspaces. |
GET /contacts |
60 req/min | Up to 1,000 | |
GET /accounts |
60 req/min | Up to 1,000 | |
GET /users |
60 req/min | Cursor-paginated | Agent/staff records. |
GET /knowledge-bases |
60 req/min | Cursor-paginated | Collections and articles nested under knowledge base. |
GET /tags |
60 req/min | Cursor-paginated | |
GET /custom-fields |
60 req/min | Cursor-paginated |
The issues endpoint is the bottleneck. At 10 requests per minute with a mandatory 30-day window, you must chunk your export into 30-day intervals. For a workspace with 2 years of history, that is a minimum of 24 API calls for the issue index alone — before fetching any messages.
Message extraction dominates pipeline runtime. Each issue requires at least one GET /issues/{id}/messages call. At 20 requests per minute with no retries or pagination overhead, extracting messages for 10,000 issues takes a minimum of 500 minutes (8.3 hours). In practice, expect 1.3–1.8× that figure after accounting for retries, backoff, and cursor pagination on issues with long thread histories.
Slack formatting is the hidden transformation cost. Pylon's API returns message bodies as Slack Block Kit JSON or raw Slack Markdown. This is not valid HTML. You must build a translation layer in your middleware before loading into Kayako. Pushing raw Slack markup directly to Kayako renders as literal characters (*bold*, <@U1234|alice>) — unreadable for agents.
# Pseudocode: Chunked issue extraction from Pylon
import datetime
import time
start = datetime.datetime(2023, 1, 1, tzinfo=datetime.timezone.utc)
end = datetime.datetime.now(datetime.timezone.utc)
chunk_days = 30
all_issues = []
request_count = 0
current = start
while current < end:
chunk_end = min(current + datetime.timedelta(days=chunk_days), end)
# Enforce 10 req/min: sleep 6 seconds between calls
if request_count > 0:
time.sleep(6)
issues = pylon_client.list_issues(
start_time=current.isoformat(),
end_time=chunk_end.isoformat(),
limit=20000
)
all_issues.extend(issues)
request_count += 1
current = chunk_endAPI Constraints: Loading into Kayako
Kayako exposes two API versions depending on your deployment target:
- Kayako Cloud: REST API at
https://{domain}.kayako.com/api/v1/, JSON responses, Basic Auth (email + password) or OAuth 2.0. Rate limits exist but are not publicly documented. - Kayako Classic (self-hosted): REST API at
https://{domain}/api/index.php?/, XML responses by default, API key + secret authentication with HMAC-SHA256 signature. No documented rate limits — throttle conservatively at 30–60 req/min to avoid server saturation.
Kayako Cloud rate limits are not publicly disclosed. The API returns HTTP 429 with a Retry-After header (value in seconds) when limits are exceeded. Implement exponential backoff starting at the Retry-After value. Do not hardcode a fixed sleep interval — limits appear to vary by endpoint and account tier based on empirical testing.
Kayako Cloud key endpoints for import:
| Action | Endpoint | Method | Required Fields | Notes |
|---|---|---|---|---|
| Create user | /api/v1/users |
POST | full_name, email |
Must create customer users before conversations. Duplicate emails return HTTP 422. |
| Create organization | /api/v1/organizations |
POST | name |
Map from Pylon Accounts. |
| Create conversation | /api/v1/conversations |
POST | subject, channel, requester_id, status |
channel must match a valid Kayako channel type. Use MAIL for historical imports. |
| Add reply | /api/v1/conversations/{id}/messages |
POST | body, author_id |
Import in chronological order — Kayako displays in creation order. |
| Add note | /api/v1/conversations/{id}/notes |
POST | body, author_id |
For internal notes. |
| Update custom fields | /api/v1/conversations/{id} |
PUT | custom_fields array |
Custom fields must be pre-created in Admin UI; reference by field ID, not name. |
| Upload attachment | /api/v1/conversations/{id}/messages/{msg_id}/attachments |
POST | file (multipart) |
Max tested file size: 12MB per attachment. HTTP 422 returned on size exceeded. |
Pagination on read: Kayako Cloud defaults to 10 results per page; use ?limit=100 for maximum throughput during verification. Pagination uses offset-based parameters (?page=2).
Kayako Cloud vs. Classic: Decision Criteria
| Factor | Kayako Cloud | Kayako Classic |
|---|---|---|
| Development status | Active | End-of-active-development |
| API format | JSON | XML |
| Authentication | OAuth 2.0 / Basic Auth | HMAC-SHA256 signed API key |
| Rate limits | Undisclosed (HTTP 429 + Retry-After) | None documented |
| Custom statuses | Limited | Full support |
| On-premise deployment | No | Yes |
| Timestamp control on import | Requires testing (see Step 7) | Direct DB access available as fallback |
Recommendation: Target Kayako Cloud unless you have a hard on-premise requirement. Kayako Classic is not receiving new feature development, and migrating from Classic to Cloud is a separate, subsequent project.
Step-by-Step Migration Process
Step 1: Audit and Pre-create Kayako Structure
Before moving any data:
- Map custom fields. List all Pylon custom fields (
GET /custom-fields) and create matching fields in Kayako under Administration → Custom Fields. Critically, Kayako separates custom fields by scope — conversation, user, and organization — while Pylon does not. A Pylon field attached to Issues maps to a Kayako conversation field; a field attached to Accounts maps to an organization field. Misclassifying scope means the field is invisible in the wrong context. - Create teams. Map Pylon Teams to Kayako Teams before importing conversations. Conversations assigned to non-existent teams will fail validation.
- Create agent accounts. Every Pylon User (agent) needs a corresponding Kayako agent account with an assigned role. Agents must exist before conversations can be assigned to them — the API returns HTTP 404 on
assigned_agent_idif the agent does not exist. - Set up Help Center structure. If migrating knowledge base content, create Kayako Help Center categories and sections that mirror your Pylon Knowledge Base and Collections hierarchy before importing articles.
Knowledge base article timestamps are not preserved via API. When importing articles into Kayako via the Help Center API, created_at and updated_at are overwritten with the migration timestamp. There is no API parameter to set historical article dates. Archive original dates in a custom field or in an external reference document before migration — they cannot be recovered post-import.
Step 2: Export Users, Organizations, and Contacts from Pylon
Extract in dependency order:
- Accounts (
GET /accounts) → Kayako Organizations - Contacts (
GET /contacts) → Kayako Users (customer type) - Users (
GET /users) → Kayako Agents
Build a persistent lookup table mapping Pylon entity IDs to Kayako entity IDs for every object. Store this as a file (JSON or SQLite) — not in memory — so the mapping survives pipeline restarts.
The email address problem: Pylon contacts are often identified exclusively by Slack user IDs (U0123ABCD). Kayako requires a valid email address as the unique identifier for Users. If you POST a user to Kayako without an email address, the API returns HTTP 422 (email_required). Contacts without email addresses must be resolved before import by cross-referencing your CRM or querying the Slack API (users.info method) using the Slack user ID. Contacts that cannot be resolved to an email address should be created with a placeholder (migrated-{slack_id}@placeholder.internal) and flagged for manual review post-migration.
Step 3: Export Issues and Messages from Pylon
This is the long pole of the pipeline. Extract issues in 30-day chunks, then fetch messages per issue.
For each issue, capture: title, description, status, priority, assignee (agent ID), team ID, tags, custom field values, account ID (→ Organization), contact ID (→ User), created_at, updated_at.
For each message, capture: body (HTML or plain text), author ID and type (agent vs. customer), message type (reply vs. internal note), attachment URLs, created_at timestamp.
Attachment URL expiry is a silent failure mode. Download all attachments immediately after extracting message data. Pylon's pre-signed attachment URLs have a time-limited validity window. If you defer the download step and the URL expires before you attempt the pull, the attachment is silently lost — the message body will contain a broken reference with no error in your extraction log.
Step 4: Transform and Load into Kayako
The transformation layer handles several non-trivial conversions:
Status mapping per the table in the Data Model section above.
User/Organization ID translation using the lookup table built in Step 2.
Custom field value mapping. Pylon custom fields are flat key-value pairs referenced by field name. Kayako custom fields must reference the numeric field ID assigned during pre-creation in Step 1. Build a field-name-to-field-ID lookup table alongside your entity ID map.
Channel assignment. Pylon Issues do not map to a single Kayako channel. For historical imports, use MAIL as the channel value — it is the most permissive channel type and does not trigger live chat session logic or social media webhooks.
Slack formatting translation. Pylon messages contain Slack Markdown (*bold*, _italic_) and Slack-specific constructs (<@U1234|username>, <!here>, <https://example.com|link text>). Kayako expects standard HTML for conversation message bodies. Pushing raw Slack syntax into Kayako results in unreadable agent-facing text.
// Slack Markdown → Kayako HTML (simplified examples)
// Input from Pylon API
const slackText = "Hey <@U1234|alice>, please review this *urgent* issue. See <https://example.com|this link>.";
// Required output for Kayako API
const kayakoHtml = "<p>Hey Alice, please review this <strong>urgent</strong> issue. See <a href=\"https://example.com\">this link</a>.</p>";
// User mention resolution requires the Pylon/Slack ID → agent name lookup table
// built during Step 2. Without it, mentions become "[unknown user]".Message ordering is mandatory. Import messages in strict chronological order by created_at. Kayako Conversations display messages in creation sequence, and out-of-order imports produce permanently scrambled thread histories that cannot be reordered post-import without deleting and recreating messages.
# Pseudocode: Transform Pylon Issue → Kayako Conversation payload
def transform_issue(pylon_issue, id_map, field_id_map):
return {
"subject": pylon_issue["title"],
"channel": "MAIL",
"requester_id": id_map["contacts"][pylon_issue["contact_id"]],
"assigned_agent_id": id_map["users"].get(pylon_issue["assignee_id"]),
"assigned_team_id": id_map["teams"].get(pylon_issue["team_id"]),
"status": STATUS_MAP[pylon_issue["state"]],
"tags": pylon_issue.get("tags", []),
"custom_fields": [
{"id": field_id_map[k], "value": v}
for k, v in pylon_issue.get("custom_fields", {}).items()
if k in field_id_map
],
}Step 5: Migrate Attachments
Pylon's pre-signed attachment URLs require a multi-step process:
- Download all attachments immediately after message extraction. Do not batch this step separately — URL expiry will silently break attachment recovery.
- Store files in a secure temporary staging volume with a manifest file linking Pylon message ID → local file path → Kayako message ID.
- Re-upload to Kayako using
multipart/form-dataPOST to/api/v1/conversations/{id}/messages/{msg_id}/attachments. - Record the Kayako File ID returned in the response. Update the manifest. Do not assume the upload succeeded — verify HTTP 201 for each file.
Inline images from Pylon will break after migration. If Pylon message bodies contain inline images hosted on Pylon's CDN (img src tags referencing Pylon-hosted URLs), those URLs will not resolve after your Pylon account is closed or suspended. You must: (1) download each inline image, (2) re-upload to Kayako via the attachments API, (3) rewrite the src attribute in the message HTML with the new Kayako-hosted URL. Failure to do this produces broken images in conversation history — permanently, with no recovery path post-cutover.
File size limit: Kayako Cloud rejects attachments over 12MB per file with HTTP 422. When this occurs, the error response body contains file_size_exceeded. Write explicit error-handling to catch HTTP 422 on attachment uploads, drop the oversized file, and append an inline text note to the conversation message body: [Attachment "{filename}" ({size}MB) exceeded Kayako's 12MB limit and was not migrated. Original file archived at {staging_path}.]. Log all dropped attachments to a separate report for post-migration review.
Step 6: Migrate Knowledge Base
Pylon's Knowledge Base API exposes knowledge bases, collections, and articles. Kayako's Help Center uses a three-level hierarchy for Cloud:
- Pylon Knowledge Base → Kayako Help Center Category
- Pylon Collection → Kayako Help Center Section (within a Category)
- Pylon Article → Kayako Help Center Article (within a Section)
Kayako Classic uses a two-level hierarchy (Category → Article) with no intermediate Section. When targeting Classic, you must either flatten the structure (combining Collection context into the Article title) or create placeholder categories per Collection.
Article body content from Pylon is typically HTML or Markdown. Verify rendering in Kayako's preview before bulk import — some HTML constructs that Pylon renders correctly are sanitized by Kayako's Help Center editor.
Step 7: Validate Timestamp Preservation
Before running a full migration, run a timestamp validation test:
- Create 10 test conversations via the Kayako API with explicit
created_atvalues (e.g., set to 2022-01-01T00:00:00Z). - Retrieve those conversations via
GET /api/v1/conversations/{id}and check the returnedcreated_atfield. - If Kayako stores the migration timestamp instead of the value you provided, implement the fallback: store the original Pylon
created_atvalue in a dedicated Kayako conversation custom field (e.g., "Original Created Date") and document this in your team's runbook.
This test takes under 30 minutes and prevents discovering the problem at scale after 20,000 conversations have been created with incorrect timestamps.
Do not skip timestamp validation. Timestamp overwriting is a known failure mode in Kayako Cloud imports. It cannot be corrected post-import without deleting and recreating all affected conversations — a full re-run. The test-first approach is not optional if historical date accuracy matters to your team.
Step 8: Execute Delta Sync for Zero-Downtime Cutover
You cannot freeze support operations for the duration of pipeline runtime. A production-grade migration requires:
- Initial Full Sync: Copy all historical Pylon data up to a specific cutoff timestamp (e.g., Sunday 00:00:00 UTC). Record this timestamp precisely.
- Validation: QA the data in Kayako (see Step 9). Check field mappings, attachment integrity, and timestamp accuracy on a 5–10% sample.
- Delta Sync: Query Pylon for issues with
updated_at > [Cutoff Timestamp]. This captures new Issues and Messages created or modified during the QA window. Apply the same transform-and-load pipeline. - Final Cutover: Update DNS (MX records for email), update email forwarding rules, update customer-facing Help Center links, update any embedded support widgets. Run one final delta sync to capture activity during the cutover window itself (typically minutes to hours depending on DNS propagation).
For a detailed treatment of delta sync methodology, see our guide on Zero-Downtime Help Desk Data Migration.
Step 9: Validate Migrated Data
After loading:
- Spot-check 5–10% of conversations for correct message ordering, attachment accessibility, and custom field values. Weight toward recent issues (high operational relevance) and oldest issues (most likely to have formatting anomalies).
- Verify user-organization associations. Kayako displays Organization context in the conversation sidebar. Broken associations mean agents lose account context during live support — test with actual agent accounts, not admin accounts.
- Confirm tag and custom field integrity. Export a sample from Kayako's API (
GET /api/v1/conversations?limit=100) and diff against source data programmatically. Manual spot-checking misses systematic mapping errors. - Test automation rules. Kayako triggers and monitors are not migrated — they must be rebuilt manually in Kayako Administration → Automations. Validate each rule fires correctly against imported conversations before going live.
- Audit dropped attachments. Review the attachment error log from Step 5. Confirm text notes were appended for all oversized files. Communicate dropped attachments to affected team leads before cutover.
Edge Cases and Failure Modes
Timestamp Preservation
The most common failure mode in help desk migrations is overwriting historical timestamps. Kayako Cloud's conversation creation API does not guarantee historical timestamp preservation via the created_at parameter. This was empirically observed when creating test conversations with created_at set to past dates — Kayako stored the request timestamp instead. Validate this behavior on your specific Kayako instance during Step 7 before running a full migration, since behavior may vary by account configuration or API version.
Pylon Slack Thread Context
Pylon Issues originating from Slack Connect channels contain conversational artifacts — emoji reactions, threaded sub-replies, channel mentions, Slack workflow outputs — that have no representation in Kayako's data model. This context is permanently stripped during migration. If your team relies on Slack thread history for case context, archive the raw Pylon JSON export (per-issue) alongside the Kayako import. Store the archive location in a Kayako conversation custom field (e.g., "Pylon Archive Reference") for retrieval.
Archived Conversations in Kayako
Kayako automatically archives conversations marked as Completed more than 30 days prior. If your Kayako instance has existing data and you import historical Pylon issues as Completed, they will be immediately archived. To retrieve archived conversations via API, append &archived=1 to the cases endpoint query. Document this for your agents — the standard Kayako UI does not display archived conversations by default.
Rate-Limit Math for Large Migrations
For a workspace with 20,000 issues averaging 8 messages per issue:
| Phase | Calculation | Estimated Runtime |
|---|---|---|
| Issue index export (Pylon) | ~24 calls (2 years ÷ 30-day chunks) @ 10 req/min | ~3 minutes |
| Message export (Pylon) | 20,000 issues × 1+ call @ 20 req/min | ~17 hours minimum; 22–30 hours realistic |
| User/Org creation (Kayako) | Depends on volume; adaptive backoff on 429s | 1–4 hours |
| Conversation creation (Kayako) | 20,000 conversations @ adaptive rate | 6–20 hours |
| Attachment upload (Kayako) | Variable by file count and size | 2–8 hours |
| Attachment inline image rewrite | Depends on message HTML complexity | 1–4 hours |
| Total pipeline runtime | 2–4 days | |
| End-to-end (planning + QA + delta sync) | 5–12 business days |
The 5-day floor assumes: fewer than 10,000 issues, minimal attachments, pre-validated field mapping, and no significant Kayako rate-limit throttling. The 12-day ceiling assumes: 20,000+ issues, heavy attachments, complex custom field structures, and one QA iteration requiring targeted re-imports.
What Cannot Be Migrated
Some Pylon data has no Kayako destination. For each item, the table below identifies what is lost, the downstream operational impact, and the best available workaround.
| Pylon Object | What Is Lost | Downstream Impact | Best Workaround |
|---|---|---|---|
| Triggers, macros, SLA policies | All automation logic | Automations are silent until rebuilt | Rebuild manually in Kayako Administration → Automations before cutover |
| Pylon AI Agent configurations | AI triage rules, response templates, escalation logic | No AI-assisted triage in Kayako | Kayako does not have native AI agent capabilities matching Pylon's; evaluate third-party integrations |
| Slack/Teams channel bindings | Channel-per-account routing | All new issues must be routed via email or Kayako Messenger | Reconfigure customer communication channels pre-cutover |
| Snooze metadata | Wake time, snooze reason, snooze-created-by | Snoozed issues migrate as Pending with no scheduled wake | Use Kayako monitor automation triggered on updated_at age as a partial substitute; wake times are unrecoverable |
| Feature Requests | Title, status, vote count, linked issues, requester list | No product feedback tracking | Export to CSV; store summary (title, vote count, status) in a Kayako organization custom field for account-level reference |
| Account Intelligence / Highlights | Health scores, CRM sync flags, activity highlights | Agents lose account-level risk visibility | Archive full JSON export to data warehouse before migration; link to account record via external URL in Kayako organization custom field |
| Custom Apps / Embedded Iframes | App configurations, embedded tools | Sidebar apps are non-functional | Audit all active apps; rebuild equivalent functionality as Kayako integrations or external tools |
| Webhooks and trigger automations | Endpoint URLs, payload configurations, trigger conditions | Connected systems stop receiving events | Export webhook configurations from Pylon before cutover; rebuild in Kayako Administration → Integrations |
When to Self-Serve vs. When to Get Help
Self-serve is viable when:
- Fewer than 3,000 issues with simple, flat custom fields (no conditional logic)
- Total attachment volume under 1GB
- No inline images embedded in message bodies
- An engineer available for 40–60 hours to build and debug the pipeline
- Historical timestamp accuracy is not a reporting requirement
A managed migration is justified when:
- 5,000+ issues or heavy attachment volumes (>1GB)
- Complex custom field mapping: multi-select dropdowns, conditional fields, fields with dependent logic
- Historical timestamp preservation is required and you cannot afford trial-and-error API testing
- Migration must run during active support operations (delta sync coordination)
- Knowledge base contains inline images requiring CDN rewrite
- Pylon's 10 req/min rate limit on issues is the bottleneck and you need pipeline optimization to minimize total runtime
The tightest constraints specific to Pylon-to-Kayako migrations are: Pylon's issue rate limit (10 req/min), Pylon's time-limited attachment URLs (must download immediately), and Kayako's undisclosed Cloud rate limits (require adaptive backoff). These three factors, combined with the Slack-to-HTML translation requirement, account for the majority of failures in DIY migrations.
Frequently Asked Questions
- Can I migrate from Pylon to Kayako without coding?
- No. There is no native migration path, CSV import tool, or middleware connector between Pylon and Kayako. You need a custom API-based ETL pipeline or a managed migration service. Middleware tools like Zapier cannot handle Pylon's nested Issue → Message → Thread structure.
- How long does a Pylon to Kayako migration take?
- Expect 5–12 business days end-to-end. Pipeline runtime for 20,000 issues is roughly 2–4 days due to Pylon's 10 requests/minute rate limit on issue exports. Add time for custom field mapping, validation, knowledge base migration, delta syncs, and automation rebuilds.
- Are Pylon issue timestamps preserved in Kayako?
- Not guaranteed. Kayako Cloud's conversation creation API may overwrite created_at timestamps with the current server time. Test with a small batch first. If timestamps are lost, store original dates in a custom conversation field as a fallback.
- What Pylon data cannot be migrated to Kayako?
- Feature Requests, Account Intelligence (health scores, highlights), AI Agent configurations, Slack/Teams channel bindings, snooze metadata, Custom Apps, and Pylon webhooks/triggers have no Kayako equivalent. Archive this data separately before migration.
- Should I migrate to Kayako Cloud or Kayako Classic?
- Kayako Cloud for most teams — it has active development, a JSON API, OAuth 2.0, and a modern Help Center. Kayako Classic is the self-hosted legacy product with no API rate limits and full database access, but it's end-of-active-development. Choose Classic only if you have hard on-premise requirements.