Intercom migration deep dive
425 plugins, 2,810 skills, 200 agents for Claude Code. Open-source marketplace at tonsofskills.com with the ccpi CLI package manager.
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill intercom-migration-deep-diveAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
Use when migrating from Zendesk/Freshdesk/HelpScout to Intercom, bulk-importing contacts, or re-platforming to Intercom with the contacts, conversations, and articles APIs. Trigger with phrases like "migrate to intercom", "intercom migration", "import contacts to intercom", "switch to intercom", "zendesk to intercom", "intercom data import".
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
6.8 KB, as published. Nobody here has run it
Intercom Migration Deep Dive
Overview
Comprehensive guide for migrating to Intercom from other platforms (Zendesk, Freshdesk, HelpScout) or bulk-importing data. Covers contact import, company import, tags, Help Center articles, orchestration, and post-migration validation. The full runnable TypeScript for every phase lives in references/implementation.md; this file carries the workflow and the first-phase skeleton so you can follow it end to end, then drill into the reference for depth.
Prerequisites
- Intercom workspace with an access token exported as
INTERCOM_ACCESS_TOKEN - Source system data exported (CSV or API access)
- The
intercom-clientSDK installed (npm install intercom-client) - Feature flag infrastructure for gradual cutover
- Rollback strategy tested
Authentication
All scripts read the workspace access token from the environment — never hard-code it. Create the token in the Intercom Developer Hub (Settings → Developers → your app → Authentication), then:
export INTERCOM_ACCESS_TOKEN="your-workspace-access-token"
import { IntercomClient, IntercomError } from "intercom-client";
const client = new IntercomClient({ token: process.env.INTERCOM_ACCESS_TOKEN! });
Migration Types
| Type | Complexity | Duration | Risk |
|---|---|---|---|
| Contact import | Low | Hours | Low |
| Zendesk/Freshdesk migration | Medium | 1-2 weeks | Medium |
| Full re-platform (with history) | High | 2-4 weeks | High |
| Help Center migration | Medium | Days | Low |
Instructions
Run the phases in dependency order. Each phase is a standalone function in references/implementation.md; the orchestrator in Step 5 chains them.
- Contacts (Step 1) — idempotent: search by
external_id/email, then update or create. Stampmigrated_from+migration_datecustom attributes so rollback can find migrated records. Skeleton below. - Companies (Step 2) — import before attaching contacts; contacts reference companies.
- Tags (Step 3) — create each tag, apply to its contacts, skip missing (404) contacts instead of aborting.
- Articles (Step 4) — group into Help Center collections by category, creating each collection once.
- Orchestrate (Step 5) —
executeMigration(plan)runs companies → contacts → tags → articles with per-phase progress logging. - Validate (Step 6) —
validateMigration(expectedCounts)compares live counts against source counts (95% threshold for contacts/articles).
Contact-import skeleton (full body in the reference):
async function importContacts(contacts: SourceContact[]) {
const stats = { created: 0, updated: 0, failed: 0, errors: [] as any[] };
for (const contact of contacts) {
const existing = await client.contacts.search({
query: { operator: "OR", value: [
{ field: "external_id", operator: "=", value: contact.id },
{ field: "email", operator: "=", value: contact.email },
] },
});
if (existing.data.length > 0) {
await client.contacts.update({ contactId: existing.data[0].id, /* ...attrs */ });
stats.updated++;
} else {
await client.contacts.create({ role: "user", externalId: contact.id, /* ...attrs */ });
stats.created++;
}
}
return stats;
}
See references/implementation.md for the complete error handling, rate limiting, company/tag/article functions, orchestrator, and validation code.
Output
- Contact import returns
{ created, updated, failed, errors[] }— a reconciliation record whereerrors[]carries per-contact{ contact_id, email, error }for every failure. - Orchestrator (
executeMigration) prints a per-phase progress log and a finalMigration complete in N minutesline plus the first 10 failed contacts. - Validation (
validateMigration) returns{ passed, checks[] }where each check is{ name, expected, actual, passed }, and prints a PASSED/FAILED summary with anOK/FAILline per resource.
Error Handling
| Issue | Cause | Solution |
|---|---|---|
| 409 Conflict | Duplicate external_id/email | Search before create |
| 429 Rate Limited | Too fast | Add delays between batches |
| 422 Validation | Bad email/data format | Validate data before import |
| Partial migration | Script crashed | Use idempotent operations, re-run |
| Missing conversations | API doesn't support bulk import | Contact Intercom support for import |
Rollback: keep the source system active during migration; only decommission
after validation plus a 2-week parallel run. To reverse, search by
custom_attributes.migration_date and delete migrated contacts in batches — see
the Rollback Procedure in
references/implementation.md.
Examples
- Bulk contact import from Zendesk — export contacts to
SourceContact[], runimportContacts()(Step 1), then reconcile against the returnederrors[]. Full function: references/implementation.md. - Full re-platform with history — build a
MigrationPlan(contacts, companies, tags, articles) and runexecuteMigration(plan)(Step 5), thenvalidateMigration(expectedCounts)(Step 6). Full orchestrator + validation: references/implementation.md. - Help Center article migration — map categories to collections and run
migrateArticles(articles, authorId)(Step 4): references/implementation.md.
Resources
- Full implementation walkthrough — all six phases, rollback, and validation in runnable TypeScript
- Contacts API
- Companies API
- Articles API
- Import Contacts Guide
- Tags API