Skip to content

How to Migrate from Gladly to Intercom: The Complete Technical Guide

How to migrate from Gladly to Intercom — object mapping, API limits, timeline-to-conversation splitting, and step-by-step architecture from migration engineers.

Nachi Nachi · · 24 min read
How to Migrate from Gladly to Intercom: The Complete Technical Guide
TALK TO AN ENGINEER

Planning a migration?

Get a free 30-min call with our engineers. We'll review your setup and map out a custom migration plan — no obligation.

Schedule a free call
  • 1,500+ migrations completed
  • Zero downtime guaranteed
  • Transparent, fixed pricing
  • Project success responsibility
  • Post-migration support included

How to Migrate from Gladly to Intercom: The Complete Technical Guide

Info

TL;DR — Gladly to Intercom Migration

Migrating from Gladly to Intercom is a high-complexity data-model translation project. Gladly stores all customer interactions in a single, lifelong Conversation Timeline with no ticket numbers. Intercom stores interactions as discrete Conversations, each hard-limited to 500 parts (Intercom API Reference: Conversations). A typical migration takes 2–4 weeks for 50,000–150,000 conversation items. The single biggest risk is silent data truncation — Gladly's API returns at most 100 conversations per customer and caps timeline items at 1,000 per conversation, flagged only by the Gladly-Limited-Data response header (Gladly API Docs: Rate Limits). If your extraction script ignores that header, you lose history with no error message. Gladly automations, routing rules, SLA configurations, and People Match rules cannot be migrated and must be rebuilt manually in Intercom. Teams with fewer than 5,000 conversation items and simple schemas can attempt a scripted DIY migration (100–160 engineer-hours). For anything larger — especially with voice history, GDPR data-residency requirements, or zero-downtime needs — a managed migration service is the safer path.

Written July 2025. Targets Gladly REST API and Intercom API v2.11.

What Is a Gladly to Intercom Migration?

A Gladly to Intercom migration is the process of extracting Customers, Conversations, Conversation Items, Agents, Teams, Topics, Tasks, and Answers from Gladly's person-centric data model and loading them into Intercom as Contacts, Companies, Conversations, Conversation Parts, Teammates, Tags, Tickets, and Articles. The goal is to preserve full customer interaction history so Intercom agents can see previous exchanges without gaps.

Teams typically migrate from Gladly to Intercom for three reasons:

  1. AI-first support architecture. Intercom's Fin AI agent resolves conversations autonomously using your knowledge base, custom actions, and workflows. For teams handling 10,000+ conversations per month, this reduces agent handle time measurably — a capability Gladly's AI (Sidekick) is still developing.
  2. Product-led growth integration. Intercom's CDP model (custom events, company associations, user segments, product tours) connects support data directly to product analytics and lifecycle campaigns. Gladly is optimized for high-touch, agent-driven support but lacks native product event tracking.
  3. Tickets as a structured back-office layer. Intercom's Tickets product gives teams defined states, custom attributes, and SLA tracking for trackable requests (bug reports, feature requests) separate from live conversations. Gladly uses Tasks for internal follow-up, but these lack the structured lifecycle of Intercom Tickets.

The non-trivial part is not extracting data — it is deciding what becomes an Intercom conversation, what becomes a ticket, and what must be preserved as context only.

The Core Challenge: Continuous Timelines vs. Discrete Conversations

The architectural mismatch between Gladly and Intercom is the hardest part of this migration.

Gladly's model is person-centric. Every customer has a single, lifelong Conversation Timeline that spans every channel — voice, email, chat, SMS, WhatsApp, Facebook Messenger, and Instagram. There are no ticket numbers. A customer who contacts support six times over two years has all six interactions in one continuous stream. Gladly's own documentation describes this as putting "Customers — not tickets — at the center" (Gladly: Customer Service Philosophy).

Intercom's model is conversation-centric. Each support interaction is a discrete Conversation object with a defined lifecycle: created → open → snoozed → closed. A customer who contacts support six times has six separate Conversations, each with its own ID, tags, assignee, and conversation parts (Intercom API Reference: Conversation Model).

This mismatch creates three practical problems:

  1. Long timelines must be split. A single Gladly Customer Timeline must be divided into multiple Intercom Conversations. Gladly does have Conversation objects within the unified timeline, and each maps to one Intercom Conversation. But if a single Gladly Conversation exceeds 500 items, it must be split further into linked Intercom Conversations.
  2. Unsupported channel types need normalization. Gladly treats voice calls, SMS, and Instagram Direct as equal nodes on a timeline. Intercom's conversation creation API only supports inapp, email, sms, whatsapp, and facebook as message types (Intercom API: Create Conversation). Voice calls, voicemails, and Instagram Direct have no native equivalent and must be stored as internal notes.
  3. Topic hierarchies flatten. Gladly topics can be nested. Intercom tags are flat. You must decide whether to flatten hierarchies or encode path strings (e.g., Billing > Refunds > Partial).

How Do Gladly Objects Map to Intercom?

Start from customer profiles, conversations, messages, topics, tasks, and answers. Only map into Intercom companies or tickets when the source data actually carries those semantics. Refer to our help desk data migration playbook for a broader mapping strategy.

Object Mapping Table

Gladly Object Intercom Object Notes / Caveats
Customer Contact (User or Lead) Gladly merges profiles automatically. Intercom deduplicates on external_id or email (Intercom: Contacts). Role (user vs lead) must be assigned during import. Gladly allows multiple emails/phones per customer.
Conversation Conversation Gladly Conversations exist within a customer timeline. Each maps to a discrete Intercom Conversation.
Conversation Item (Email) Conversation Part (comment) Each email becomes a conversation part. HTML is not supported in the initial conversation body — only in reply parts (verified against Intercom API v2.11; check the Create Conversation endpoint docs for current behavior).
Conversation Item (Chat) Conversation Part (comment) Direct mapping.
Conversation Item (SMS) Conversation Part (comment) SMS content migrates as text. Channel metadata (carrier, delivery status) is lost.
Conversation Item (Phone Call) Conversation Part (note) No native equivalent. Migrate as internal notes with call metadata (duration, recording URL).
Conversation Item (Voicemail) Conversation Part (note) Same as phone calls — recording URLs preserved as attachment links in S3/GCS.
Conversation Item (Instagram Direct) Conversation Part (note) Intercom does not support Instagram Direct as a create-conversation message type. Store as notes.
Conversation Item (Note) Conversation Part (note) Direct mapping for internal notes.
Topic Tag Gladly Topics map to Intercom Tags. Create tags before importing conversations. Flatten nested hierarchies.
Task Ticket Gladly Tasks (due date, assignee, description) map best to Intercom Tickets with custom ticket types.
Answer (Public) Article Gladly Answers map to Intercom Articles. Sections map to Collections. Audiences map to Help Center audiences.
Agent Teammate / Admin Agent profiles must exist in Intercom before conversation import for proper attribution. Map by email address.
Team Team Direct mapping. Create teams in Intercom before import.
Inbox Team Inbox Map Gladly Inboxes to Intercom team inboxes or views.
Custom Attributes Custom Data Attributes Create CDAs via the Data Attributes API before importing records.

What Has No Clean Equivalent in Intercom

  • People Match rules. Gladly's identity resolution logic (matching customers across channels by email, phone, social) has no API-portable equivalent. Intercom identifies contacts by external_id, email, or Intercom ID.
  • Routing rules and SLA policies. Must be rebuilt as Intercom Workflows and SLA rules manually. Budget 1–2 days depending on rule complexity.
  • Voice/SMS channel metadata. Intercom has no native voice channel. Call recordings, durations, and IVR paths are preserved only as note text or attachment URLs.
  • Sidekick (AI) configuration. Guides, Journeys, and AI training data cannot be exported or transferred.
  • Conversation status granularity. Gladly statuses (OPEN, CLOSED, WAITING) must be mapped to Intercom's three states: open, closed, or snoozed. Map WAITING to snoozed with a calculated timestamp.
  • Webhooks. Gladly webhooks (conversation events, customer events) that feed downstream systems (CRMs, analytics pipelines, Slack alerts) need to be re-pointed to Intercom's webhook infrastructure or rebuilt as Intercom Workflow triggers.

Field-Level Transformations

  • Timestamps: Gladly exports ISO 8601. Intercom's API expects Unix timestamps (seconds since epoch) for historical imports. Convert during the transform phase: int(datetime.fromisoformat(gladly_ts).timestamp()).
  • Custom Attributes: Pre-create Intercom CDAs with the correct type — string, integer, float, boolean, date, or options — before loading contact data.
  • Identity Strategy: Intercom's CSV imports match contacts in this order: Intercom ID → user_id → email. If you mix email and user_id inconsistently, you will create duplicates. Intercom also supports CSV bulk imports for contacts as an alternative to API-only loading — useful for the initial contact seed if you have clean, deduplicated customer data.

API Rate Limits and Export Constraints

Rate limits are the primary throughput constraint. Gladly is the bottleneck.

Gladly Extraction Limits

Endpoint Type Rate Limit Notes Source
Standard REST API 10 requests/second Rolling window Gladly API: Rate Limits
Reporting API 10 requests/minute 2 concurrent requests max across the organization Gladly API: Reporting
List Customer Profiles Max 50 per response Paginated Gladly API: Customers
List Customer Conversations Max 100 per response Not paginated — truncated silently Gladly API: Conversations
Conversation Timeline Items Max 1,000 per conversation Truncated silently Gladly API: Conversation Items
Customer Tasks Max 2,000 per response Gladly API: Tasks

Gladly's API has two data-truncation behaviors that cause silent data loss if unhandled:

  1. Conversation list cap. GET /api/v1/customers/{customerId}/conversations returns at most 100 conversations per customer and is not paginated. If a customer has more than 100 conversations, the Gladly-Limited-Data response header is set to true. For high-volume customers (loyalty programs, VIP accounts), 100+ conversations are common.

  2. Timeline item cap. The conversation timeline endpoint returns at most 1,000 items per conversation. If exceeded, the Gladly-Limited-Data header flags the truncation. For enterprise customers with multi-year histories, this is a real risk.

Your extraction script must check this header on every API response. Gladly's API uses Basic Auth with an API token — Authorization: Basic base64(email:token) on every request. There is no OAuth flow.

Gladly Export API

For full-history migrations, Gladly's Export API is often safer than REST-based crawling. It outputs JSONL files — agents.jsonl, customers.jsonl, topics.jsonl, and conversation_items.jsonl — bypassing the per-request truncation limits of the REST endpoints.

The Export API has its own constraints:

  • Default schedule is daily. Hourly or one-time schedules require a Gladly support change.
  • Job metadata and files are retained for only 14 days.
  • One-time exports covering more than six months may incur a service fee from Gladly (confirm with your Gladly account manager — pricing is not published).
  • Some records are excluded: undelivered email messages with invalid recipients and certain EMAIL/SMS auto-replies sent by rules.

Practical recommendation: Use the Export API for the bulk historical load. Use REST for targeted lookups, recent deltas, and the final sync during cutover.

Intercom Load Constraints

Constraint Limit Source
Private App API calls 10,000 requests/minute per app Intercom API: Rate Limiting
Workspace total 25,000 requests/minute Intercom API: Rate Limiting
Conversation parts 500 parts maximum per conversation Intercom API: Conversations

Intercom's rate limits are applied in 10-second windows (~1,666 calls per window for private apps). Each Gladly Conversation Item requires at minimum one API call (create conversation or reply). A customer with 50 conversation items across 3 conversations requires approximately 53 API calls (3 create + 50 reply).

Throughput math: At 10,000 calls/minute with no errors, you can import roughly 10,000 conversation parts per minute. In practice, expect 60–70% of theoretical throughput due to retries, 429 responses, and variable latency — roughly 400,000 parts per hour.

Intercom's Conversations API accepts a created_at timestamp field specifically for historical migration. The documentation states this field is "only recommended for migrating past conversations from another source into Intercom." Important: this feature may be gated by Intercom plan level. Test this in a sandbox workspace first and confirm with your Intercom account manager that your plan (Starter, Pro, or Premium) supports historical timestamp imports. Behavior has varied between plans historically.

Warning

Hard limit: 500 parts per Intercom Conversation. If a Gladly Conversation has more than 500 timeline items, you must split it into multiple Intercom Conversations and link them via tags or a shared custom attribute (e.g., gladly_original_conversation_id). Design your splitter to cap at ~450 parts so the live team has room to continue the thread after cutover. The 450 figure is an implementation choice, not an Intercom requirement — but it avoids hitting the ceiling during the first post-migration week.

Migration Approaches Compared

Custom API Scripts (DIY)

How it works: Build Python or Node.js ETL scripts that extract from Gladly's REST or Export API and load into Intercom's REST API.

When to use it: Teams with fewer than 5,000 conversation items, simple schemas, and a dedicated engineer available for 100–160 hours.

Estimated cost: $0 in tooling, but 100–160 hours of senior backend engineering time. At a loaded cost of $100–$150/hour, that is $10,000–$24,000 in opportunity cost.

Pros: Full control over mapping logic, no vendor dependency, handles edge cases you define.

Cons: High engineering investment. You own all error handling, retries, and the Gladly-Limited-Data truncation detection. Easy to miss edge cases on the first pass.

Third-Party Migration Tool

How it works: Wizard-based tool (e.g., Help Desk Migration) that connects to both platforms via API and maps standard objects automatically.

When to use it: Teams with standard schemas, no custom timeline-splitting requirements, and moderate volumes (10,000–100,000 records).

Estimated cost: Typically $1,000–$10,000 depending on record volume and add-ons (delta sync, custom field mapping). Verify current pricing directly with the vendor.

Pros: Lower engineering effort, pre-built mapping for common objects, test migration before full run.

Cons: Limited control over how Gladly's continuous timeline is split into Intercom conversations. May not handle voice/SMS items, Gladly-Limited-Data truncation, or custom field transformations. Verify Gladly is listed as a supported source before committing.

Managed Migration Service

How it works: A dedicated engineering team handles extraction, transformation (including timeline splitting), loading, validation, and delta sync.

When to use it: Teams with 50,000+ conversation items, voice/SMS history, custom attributes, or zero-downtime requirements.

Estimated cost: $5,000–$30,000+ depending on data volume, complexity, and SLA requirements.

Pros: Timeline-to-conversation splitting handled programmatically, truncation detection built-in, delta sync during cutover, validation included.

Cons: Higher cost than DIY. Requires vendor coordination.

Criteria DIY Scripts Third-Party Tool Managed Service
Engineering hours 100–160 20–40 0–10
Estimated cost $10K–$24K (opportunity) $1K–$10K (licensing) $5K–$30K+ (service)
Timeline splitting Manual logic Limited Automated
Truncation handling Manual Unknown Built-in
Voice/SMS migration Manual Likely unsupported Supported
Delta sync Manual Paid add-on Included
Best for <5K items 10K–100K standard 50K+ or complex

Step-by-Step Migration Architecture

The correct order-of-operations prevents broken relationships. Skip a step or reorder and you create orphaned conversations or duplicate contacts.

Step 1: Export Gladly History

For historical loads, use Gladly's Export API to pull customers.jsonl, conversation_items.jsonl, topics.jsonl, and agents.jsonl. This avoids REST truncation limits. Reserve REST for targeted lookups and the final delta sync during cutover.

If you use REST (for smaller datasets or deltas), check the Gladly-Limited-Data header on every response:

import requests
import base64
 
GLADLY_DOMAIN = "yourorg.gladly.com"
auth = base64.b64encode(b"email@company.com:api-token").decode()
 
def get_customer_conversations(customer_id):
    resp = requests.get(
        f"https://{GLADLY_DOMAIN}/api/v1/customers/{customer_id}/conversations",
        headers={"Authorization": f"Basic {auth}"}
    )
    resp.raise_for_status()
    # CRITICAL: Check for truncation
    if resp.headers.get("Gladly-Limited-Data") == "true":
        log_warning(f"Customer {customer_id}: >100 conversations, data truncated")
        # Fallback: use Export API data for this customer
        return get_from_export_api(customer_id)
    return resp.json()

Step 2: Create the Intercom Schema

Pre-create all structural elements in Intercom before loading data:

  • Custom Data Attributes (via the Data Attributes API) — with correct types
  • Ticket types and ticket attributes — if migrating Gladly Tasks as Tickets
  • Tags (from Gladly Topics) — via POST /tags
  • Article Collections and Sections — for knowledge base migration (see Step 6)
  • Teams and Teammate accounts — agents must exist for admin_id attribution

Do this before loading any conversations. If teammates do not exist when you POST admin-authored notes, attribution will fail.

Step 3: Load Contacts

Push Gladly Customer records to Intercom using POST /contacts. Choose one consistent identity key — either email or a stable external_id — and do not change it mid-project.

For large contact sets (10,000+), consider using Intercom's CSV import as the initial seed, then supplement with API calls for custom attributes and edge cases.

import time
 
def create_intercom_contact(customer):
    resp = requests.post(
        "https://api.intercom.io/contacts",
        headers={
            "Authorization": "Bearer <token>",
            "Content-Type": "application/json",
            "Intercom-Version": "2.11"
        },
        json={
            "role": "user",
            "external_id": customer["gladly_id"],
            "email": customer["emails"][0],
            "name": customer["name"],
            "custom_attributes": {
                "gladly_customer_id": customer["gladly_id"]
            }
        }
    )
    if resp.status_code == 409:
        # Duplicate contact — look up existing and update
        existing = lookup_contact_by_external_id(customer["gladly_id"])
        return existing["id"]
    if resp.status_code == 429:
        retry_after = int(resp.headers.get("Retry-After", 1))
        time.sleep(retry_after)
        return create_intercom_contact(customer)  # Retry
    resp.raise_for_status()
    return resp.json()["id"]  # Store for conversation linking

Store the returned Intercom id in a mapping table alongside the Gladly customerId. You need this to associate conversations correctly.

Step 4: Transform and Split Conversations

This is the hardest step. For each Gladly Customer:

  1. Group items by Gladly Conversation ID. Each Gladly Conversation maps to one Intercom Conversation.
  2. Sort items ascending by timestamp within each conversation.
  3. Check for truncation. If Gladly-Limited-Data was flagged during extraction, verify you have the complete dataset from the Export API.
  4. Split any conversation with >450 items into multiple Intercom Conversations. Tag overflow conversations with a shared gladly_original_conversation_id custom attribute and a gladly_continuation: true flag.
  5. Normalize unsupported channels. Map voice calls, voicemails, and Instagram Direct items to internal notes with explicit channel markers.
def split_conversation(items, max_parts=450):
    """Leave buffer below Intercom's 500-part hard limit.
    For active/open conversations, use max_parts=400 to give agents more headroom."""
    chunks = []
    for i in range(0, len(items), max_parts):
        chunks.append(items[i:i + max_parts])
    return chunks

Step 5: Load Conversations into Intercom

For each group of items:

  1. Create the conversation with POST /conversations, setting created_at to the original Gladly timestamp (Unix seconds). The first item's content becomes the conversation body — plain text only. HTML is not supported in the initial message.
  2. Add subsequent items as replies via POST /conversations/{id}/reply with message_type: "comment" and the correct author type (user or admin).
  3. Add internal notes (including migrated voice calls) via POST /conversations/{id}/reply with message_type: "note".
  4. Close completed conversations via POST /conversations/{id}/parts with message_type: "close".
  5. Attach tags mapped from the original Gladly Topics.

Implement exponential backoff with jitter on 429 responses. Treat rate limiting as normal operational behavior, not an error condition.

import random
 
def reply_with_backoff(conversation_id, payload, max_retries=5):
    for attempt in range(max_retries):
        resp = requests.post(
            f"https://api.intercom.io/conversations/{conversation_id}/reply",
            headers={
                "Authorization": "Bearer <token>",
                "Content-Type": "application/json",
                "Intercom-Version": "2.11"
            },
            json=payload
        )
        if resp.status_code == 429:
            wait = (2 ** attempt) + random.uniform(0, 1)
            time.sleep(wait)
            continue
        if resp.status_code >= 500:
            time.sleep(2 ** attempt)
            continue
        resp.raise_for_status()
        return resp.json()
    raise Exception(f"Failed after {max_retries} retries for conversation {conversation_id}")
 
for conv_id, items in group_by(gladly_items, 'conversationId'):
    ordered = sort_by(items, 'timestamp')
    chunks = split_conversation(ordered, max_parts=450)
 
    for idx, chunk in enumerate(chunks, start=1):
        first = chunk[0]
        intercom_conv = create_conversation(
            contact_id=contact_map[first['customerId']],
            body=render_body(first),
            created_at=to_unix(first['timestamp'])
        )
 
        for item in chunk[1:]:
            reply_with_backoff(
                intercom_conv['id'],
                {
                    "type": map_author_type(item),
                    "admin_id": agent_map.get(item.get('agentId')),
                    "body": render_body(item),
                    "message_type": "note" if item['channel'] in ['PHONE', 'VOICEMAIL', 'INSTAGRAM'] else "comment",
                    "created_at": to_unix(item['timestamp']),
                    "attachment_urls": rehost_attachments(item.get('attachments', []))
                }
            )
 
        tag_conversation(intercom_conv['id'], map_topics(chunk))
        record_idempotency(conv_id, idx, intercom_conv['id'])

Step 6: Migrate Answers to Articles

Extract Gladly Public Answers via the Help Center API (/api/v1/orgs/{orgId}/help-center/{helpCenterId}/answer-titles, returns up to 1,000 answers). Create corresponding Intercom Articles via the Articles API.

Mapping details:

  • Gladly Sections → Intercom Collections. Create Collections first via POST /help_center/collections, then reference the collection_id when creating articles.
  • Gladly Answer body formatting. Gladly Answers use HTML. Intercom Articles also accept HTML, but rendering differences exist — test formatting on 5–10 representative articles before the bulk load.
  • Gladly Audiences → Intercom Help Center segmentation. If you operate multiple brands via Gladly Audiences, you need separate Intercom Help Centers or filtered Collections per brand.
  • URL redirects. If your Gladly Help Center is public-facing, set up 301 redirects from old Gladly Answer URLs to new Intercom Article URLs. Without this, inbound links and search engine rankings break. Maintain a redirect map: {gladly_answer_url → intercom_article_url}.

Article tags are not managed through Intercom's Articles API — tag handling needs its own pass via the Tags API.

Step 7: Validate

See the validation section below. Do not cut over until record counts, field-level spot checks, and agent UAT all pass.

How Long Does a Gladly to Intercom Migration Take?

A Gladly to Intercom migration takes 2–4 weeks for a typical mid-market team (20–50 agents, 50,000–150,000 conversation items). Enterprise migrations with voice history, multi-brand Audiences, and 500,000+ items can take 4–6 weeks. The schedule is driven less by API throughput and more by mapping decisions, long-thread handling, UAT, and cutover discipline.

Phase Duration Exit Criteria
Planning and mapping 2–3 days Final object map, cutover model, field list, GDPR assessment
Intercom workspace setup 1–2 days Teams, inboxes, custom attributes, tags created
Script development or tool config 3–5 days API credentials, sandbox access confirmed
Test migration (10% sample) 1–2 days Complex high-volume customers validated in sandbox
Validation and adjustment 1–2 days Stakeholder review complete
Full historical load 1–3 days Record counts and spot checks pass
Delta sync and cutover 1 day Gladly set to read-only, routing switched to Intercom
Post-go-live monitoring 3–5 days Agent feedback collected, reconciliation complete

Risk Register

Risk Likelihood Impact Mitigation
Silent data truncation (Gladly-Limited-Data) High for >100 convos/customer Data loss Check header on every response; use Export API for bulk
Conversation part limit exceeded (>500) Medium Partial history loss Pre-split at ~450 parts during transform
Timestamp rejection on created_at Low–Medium Wrong conversation dates Test in sandbox; verify plan supports historical timestamps
Attachment URL expiration Medium Broken attachments Download all to S3/GCS before loading into Intercom
Agent ID mismatch Low Misattributed conversations Pre-create all teammates; build ID mapping table
Duplicate contacts Medium Inconsistent customer records Lock identity strategy before first load; handle 409s as lookups
GDPR data-residency violation Low–Medium Regulatory exposure Verify Gladly and Intercom hosting regions match; see GDPR section below
Intercom plan feature gating Low created_at or API features unavailable Confirm plan-level feature access with Intercom before development

Rollback Plan

Intercom has no one-click "undo import" feature. Plan for this:

  1. Tag all migrated records with a migration_batch identifier (e.g., migration_batch_2025_07_15) during import.
  2. If rollback is needed, use the Intercom API to bulk-delete conversations and contacts by tag. Note: the Search Conversations API has its own pagination limits — plan for multiple passes if deleting 100,000+ records.
  3. Keep Gladly in read-only mode (not decommissioned) until post-go-live validation is complete — typically 5–7 business days.

GDPR, Data Residency, and Compliance Considerations

Migrating customer PII between platforms triggers data-protection obligations. Address these before writing any extraction code:

  • Data residency. Gladly hosts data in AWS US regions. Intercom offers US, EU, and AU hosting (Intercom: Data Hosting). If your Gladly instance holds EU customer data and your Intercom workspace is US-hosted, the migration constitutes a cross-border data transfer under GDPR. You may need Standard Contractual Clauses (SCCs) or a Transfer Impact Assessment (TIA).
  • Data Processing Agreements (DPAs). Ensure DPAs are in place with both Gladly (as data exporter) and Intercom (as data importer) before migration. Both platforms offer DPAs on request.
  • Data minimization. Migration is an opportunity to exclude data you no longer need. Consider excluding conversations older than your retention policy, closed CSAT-only records, or PII for customers who have exercised deletion rights.
  • Right to erasure compliance. If you have pending GDPR erasure requests in Gladly, process them before migration — do not migrate data that should have been deleted.
  • Encryption in transit. Both Gladly and Intercom APIs use TLS 1.2+. If you stage data in intermediate storage (S3, GCS), ensure encryption at rest is enabled.

What Do Customers and Agents Notice?

If executed correctly, customers notice nothing. The migration happens on the backend. No emails are sent, no conversations are reopened in a customer-facing way.

The key risks to customer experience:

  • History gaps. If conversation history is truncated or not fully migrated, agents lose context and customers get asked to repeat themselves.
  • Duplicate contacts. If Gladly records are not deduplicated before import, customers may see inconsistent interactions or receive duplicate messages.
  • Workflow interruption. If routing rules and SLAs are not rebuilt before go-live, first-response times may spike during the first 24–48 hours.

The biggest adjustment for agents is the shift from Gladly's single-timeline view to Intercom's discrete conversation model. Agents accustomed to scrolling through one continuous profile will need to search across individual conversations to find a customer's full history.

Change management checklist:

  • Brief agents on Intercom's conversation-centric model 1–2 weeks before cutover.
  • Create a mapping document: Gladly Topics → Intercom Tags, Gladly Inboxes → Intercom Team Inboxes.
  • Train agents on the splitting logic used during migration (e.g., "Each Gladly Conversation became a separate Intercom Conversation. Any single conversation with 450+ items was split into multiple linked records with a shared gladly_original_conversation_id attribute").
  • Schedule a 30-minute live training session on cutover day.
  • Assign a migration liaison (senior agent) to handle escalations during the first week.

For a zero-downtime approach to the cutover itself, see our guide on zero-downtime help desk migrations.

Edge Cases and Known Limitations

Voice, SMS, and Instagram Direct

Gladly natively handles voice calls with recording, IVR routing, and voicemail. Intercom has no native voice channel. Voice items should be migrated as internal notes with structured metadata:

{
  "message_type": "note",
  "type": "admin",
  "admin_id": "<admin_id>",
  "body": "[Migrated Voice Call] Duration: 4m 32s | Agent: Jane Smith | Recording: <s3_url> | Original Channel: PHONE | IVR Path: Support > Billing"
}

SMS content migrates as text-based conversation parts, but channel metadata (carrier, delivery receipts) is lost. Instagram Direct has no native Intercom message type and must also be stored as notes.

The 500-Part Hard Limit in Practice

Intercom rejects any attempt to add a 501st part. But the risk extends beyond migration day. If an active Gladly conversation has 490 items at the time of migration and you load all 490 into one Intercom conversation, agents will hit the limit almost immediately after go-live. Your transformation script should forcefully split any active conversation nearing 400 parts to give agents headroom.

Retrieving a conversation later via the Intercom API (GET /conversations/{id}) returns only the 500 most recent parts. You cannot rely on a single GET response as proof that a very long thread imported fully. To verify import completeness, maintain your own import ledger with part counts per conversation.

Merged Customer Profiles

Gladly supports customer profile merging. If a customer was merged, requests to the original customer ID return a 301 redirect with the new ID in the Location header. Your extraction script must follow these redirects or you will miss merged customer history. Merged profiles can also cause history to appear out of order — review ordering before cutover.

def get_customer(customer_id):
    resp = requests.get(
        f"https://{GLADLY_DOMAIN}/api/v1/customers/{customer_id}",
        headers={"Authorization": f"Basic {auth}"},
        allow_redirects=True  # Follow 301 for merged profiles
    )
    if resp.history:  # Redirect occurred
        log_info(f"Customer {customer_id} merged into {resp.url.split('/')[-1]}")
    return resp.json()

Duplicate Contacts

Gladly allows multiple emails and phone numbers per customer profile. Intercom deduplicates contacts on external_id first, then email. Before importing, deduplicate Gladly customer records and decide which email becomes the primary identifier in Intercom. Failing to do this creates duplicate contacts — one of the most common sources of post-migration complaints.

Attachments and Inline Images

Gladly conversation items can include attachments and inline images. Download all attachment files to cloud storage (S3 or GCS) before the load phase. If you pass Gladly CDN URLs directly to Intercom, the images will break when your Gladly contract expires and the instance is decommissioned.

Intercom's conversation creation endpoint accepts up to 10 image attachment URLs per API call. Non-image files (PDFs, CSVs) may need to be linked as URLs in the message body.

Multi-Brand (Audiences)

Gladly uses Audiences to segment content for different brands. If you operate multiple brands, you need separate Intercom Help Centers or Collections per brand, with articles mapped accordingly. Plan the URL redirect strategy per brand — each brand's existing Help Center URLs need individual 301 redirect mappings.

Intercom Data Retention and Archival

Intercom does not automatically archive or delete old conversations, but your Intercom plan may impose data retention limits. If you are migrating 5+ years of history, confirm with Intercom that your plan supports the volume without additional storage fees. Intercom's reporting and search indices may also perform differently with very large historical datasets — test search performance in your sandbox after loading historical data.

What Data Cannot Be Migrated from Gladly to Intercom?

Be explicit with stakeholders about what does not transfer:

  • Automations and routing rules. Must be rebuilt as Intercom Workflows. Budget 1–2 days depending on complexity.
  • People Match configuration. Gladly's identity resolution rules are not exportable.
  • Sidekick (AI) training data. Guides, Journeys, and AI configuration do not export.
  • Voice call recordings as native channels. Recording files can be referenced via URL in notes, but Intercom has no voice player.
  • CSAT survey responses tied to conversations. Can be migrated as custom attributes on conversations, but the integration with CSAT providers (Delighted, SurveyMonkey, etc.) must be re-established.
  • Real-time analytics and dashboards. Gladly reporting data does not transfer. Intercom Reporting starts fresh from go-live.
  • Conversation items beyond API caps. Items beyond the 1,000-item REST limit per conversation require the Export API or bulk export jobs.
  • Instagram Direct channel metadata. No native Intercom equivalent.
  • Nested topic hierarchies. Intercom tags are flat. Nest levels are lost unless you encode them as path strings (e.g., Billing > Refunds > Partial).
  • Gladly webhooks. Must be rebuilt as Intercom webhook subscriptions or Workflow triggers.

Validation and Testing

Validation is not optional. A migration without validation is data dumping.

Record-Count Reconciliation

Object Gladly Count (source) Intercom Count (target) Match?
Customers → Contacts Count via Reporting API or Export Count via Search Contacts API Must match
Conversations Count via customer conversation lists Count via Search Conversations API Must match (may exceed source if splits occurred)
Conversation Items → Parts Sum of all timeline items Sum of all conversation parts from import ledger Must match (±1% for splits)
Topics → Tags Count via Topics API Count via Tags API Must match
Answers → Articles Count via Public Answers API Count via Articles API Must match

Do not rely on top-level record counts alone. A successful export might show 100,000 customers and Intercom might show 100,000 contacts, but that does not mean timeline data is intact.

Note on Intercom Search API constraints: The Search Conversations API returns paginated results and is subject to rate limits. For workspaces with 500,000+ conversations, full verification via API can take hours. Plan your validation script to run overnight if needed, and maintain your own import ledger as the primary reconciliation source.

Specific Audit Checks

  • Truncation Audit: Query your extraction logs for the Gladly-Limited-Data header. Ensure every flagged record triggered a successful fallback to the Export API or paginated sub-query.
  • Part Limit Audit: Query your transformation logs for any timeline chunk containing exactly 500 items. This is a red flag that your splitting logic failed and Intercom rejected subsequent messages.
  • Attachment Sampling: Randomly sample 100 historical conversations that contained attachments. Click the links to verify they resolve to your cloud storage (S3/GCS), not Gladly's CDN.
  • Split-Conversation Audit: Query Intercom for all conversations tagged gladly_continuation: true. Verify each has a corresponding parent conversation with a matching gladly_original_conversation_id.

Field-Level Spot Checks

Sample 50–100 records across different customer segments (high-volume, low-volume, multi-channel). For each:

  1. Verify conversation count matches (accounting for any splits).
  2. Verify first and last message timestamps match.
  3. Verify agent attribution on replies.
  4. Verify tags/topics are correctly mapped.
  5. Verify attachments are accessible via S3/GCS URLs.

Agent UAT

Have 3–5 agents search for known customers and verify:

  • Can they find the customer's full history?
  • Are conversations in the correct chronological order?
  • Are internal notes present and attributed to the correct agent?
  • Do knowledge base articles (Answers → Articles) render correctly?
  • Do Help Center URLs redirect correctly from old Gladly paths?

For a comprehensive QA framework, see our help desk data migration QA checklist.

Build In-House or Use a Managed Service?

When in-house is the right call

  • Fewer than 5,000 total conversation items
  • No voice, SMS, or Instagram Direct history to migrate
  • No customers with >100 conversations (no Gladly-Limited-Data truncation risk)
  • A backend engineer available for 100–160 hours with no competing priorities
  • You have done an API-to-API migration before
  • No cross-border data-residency concerns

When in-house is not the right call

  • 50,000+ conversation items
  • Voice recordings, SMS, or WhatsApp history that needs preservation
  • High-value customers with long timelines hitting Gladly's API truncation limits
  • Zero-downtime requirement with delta sync
  • Cross-region GDPR data transfer requirements
  • No engineer available for 3+ weeks of dedicated migration work
  • The cost of a failed migration (re-migration, agent downtime, customer complaints) exceeds the cost of a managed service

The hidden cost of DIY is not the initial build — it is the debugging. Missed Gladly-Limited-Data headers, conversations that silently exceed 500 parts, timestamp mismatches, duplicate contacts from multi-email customers — these issues surface during validation and require 2–3x the expected effort to resolve.

Building a script to hit an API is straightforward. Building a deterministic algorithm to split continuous omnichannel timelines into discrete conversations under a 500-part ceiling without losing historical attribution is a different class of engineering problem.

Frequently Asked Questions

How long does a Gladly to Intercom migration take?
A Gladly to Intercom migration takes 2–4 weeks for a typical mid-market team with 50,000–150,000 conversation items. This includes planning, schema mapping, test migration, full migration, delta sync, and post-go-live validation. Enterprise migrations with voice history and 500,000+ items can take 4–6 weeks.
What is the biggest risk in a Gladly to Intercom migration?
Silent data truncation. Gladly's API returns at most 100 conversations per customer and 1,000 items per conversation. If your extraction script does not check the Gladly-Limited-Data response header, you will lose customer history without any error message. This is the most common cause of post-migration data loss.
What data cannot be migrated from Gladly to Intercom?
Gladly automations, routing rules, People Match configuration, Sidekick AI training data, SLA policies, and real-time analytics cannot be migrated and must be rebuilt manually in Intercom. Voice call recordings can be preserved as linked URLs in internal notes but not as native Intercom voice interactions.
Can Gladly conversation history be preserved in Intercom?
Yes, but it requires transformation. Gladly's continuous customer timelines must be split into discrete Intercom Conversations, each with a maximum of 500 parts. Intercom's Create Conversation endpoint accepts a created_at timestamp for historical imports. Voice and SMS items migrate as internal notes since Intercom has no native voice channel.
How much does a Gladly to Intercom migration cost?
DIY API scripting costs 100–160 engineer-hours ($15,000–$30,000 at loaded engineering rates). Third-party migration tools typically charge $2,000–$8,000 for 50K–150K records. Managed migration services range from $5,000–$20,000 depending on volume, complexity, and whether voice/SMS history is included.

More from our Blog

Help Desk Data Migration Playbook: What Data to Move and What to Leave Behind
Help Desk

Help Desk Data Migration Playbook: What Data to Move and What to Leave Behind

This definitive playbook answers the single most critical question: "What data do we actually need to move?". This strategic guide helps you declutter and decide what's precious and what's junk. We provide a clear breakdown of the non-negotiable Tier 1 data, like tickets , knowledge bases , and user profiles, versus the Tier 2 data that provides rich context, like automations and organizations. Use this as your strategic checklist to avoid common mistakes and ensure a flawless, functional new help desk.

Raaj Raaj · · 7 min read
Intercom Migration Checklist
Checklist/Intercom

Intercom Migration Checklist

Moving your support to Intercom? Use our step-by-step Intercom migration checklist to map data attributes, preserve ticket history, and ensure a seamless API-driven transition.

Tejas Mondeeri Tejas Mondeeri · · 9 min read