intercom-data-handling
'Implement Intercom data handling for GDPR, contact export, data retention,
Allowed Tools
Provided by Plugin
intercom-pack
Claude Code skill pack for Intercom (24 skills)
Installation
This skill is included in the intercom-pack plugin:
/plugin install intercom-pack@claude-code-plugins-plus
Click to copy
Instructions
Intercom Data Handling
Overview
Handle sensitive contact data in Intercom integrations with GDPR/CCPA compliance:
data export via the Data Export API, contact deletion with an audit trail, PII
redaction in logs, and data retention policies. This skill gives you a lean map of
the five workflows here; the full copy-ready TypeScript lives in
references/implementation.md and worked usage in
Prerequisites
- Understanding of GDPR/CCPA requirements
intercom-clientSDK installed- Database for audit logging
- Familiarity with Intercom's contact and conversation data model
Authentication
Every call authenticates with an Intercom access token via a Bearer header. Store
it as INTERCOMACCESSTOKEN in the environment — never hardcode it and never log
it:
import { IntercomClient } from "intercom-client";
const client = new IntercomClient({
token: process.env.INTERCOM_ACCESS_TOKEN!,
});
// Raw REST calls use: Authorization: `Bearer ${process.env.INTERCOM_ACCESS_TOKEN}`
Grant the token the minimum scopes needed (read contacts/conversations for export,
write/delete for erasure). Rotate it if it ever appears in a log or a diff.
Data Classification for Intercom
| Category | Intercom Fields | Handling |
|---|---|---|
| PII | email, name, phone, location |
Encrypt at rest, redact in logs |
| Identifiers | id, externalid, userid |
Use for lookups, no display |
| Conversation content | body, conversation_parts |
May contain PII, scan before logging |
| Custom attributes | User-defined | Depends on content |
| System metadata | createdat, updatedat, role |
Standard handling |
Instructions
The five workflows below compose into a compliant Intercom data lifecycle. Follow
the summary here, then open references/implementation.md
for the complete function bodies.
- DSAR export —
exportContactData(contactId)gathers the contact profile,
all conversations (with parts), tags, segments, and data events into one bundle.
This is the "give me all my data" request.
- Right to deletion (Article 17) —
deleteContactData(contactId)exports for
the audit trail first, then deletes from Intercom and every local cache, and
records a PII-free audit entry (email is hashed, not stored).
- Bulk data export —
bulkExportMessages(start, end)kicks off the async
/export/messages/data job; checkExportStatus(jobId) polls until a CSV
download_url is returned.
- PII redaction in logs —
redactIntercomData(data)masks a fixed
PIIFIELDS set (including nested customattributes.*) before anything is
logged.
- Retention enforcement —
enforceRetention()sweeps cached records past
their RETENTION window on a daily cron, and never touches the 7-year audit log.
Data minimization underpins all five: sync only the fields you need so the erasure
and breach surface stays small (see references/examples.md).
Here is the entry-point skeleton — the export that DSAR and deletion both build on:
const contact = await client.contacts.find({ contactId });
const convList = await client.conversations.search({
query: { field: "contact_ids", operator: "=", value: contactId },
});
// ...gather tags, segments, events → return one bundle
Output
Each workflow returns a structured, PII-aware result:
- DSAR export → an object with
contact,conversations[],tags[],
segments[], and events[] — the full data bundle to hand to the requester.
- Deletion →
{ deleted: true, auditRecord }whereauditRecordholds the
action, hashed email, timestamp, purged data sources, and conversation count —
proof of erasure that contains no raw PII.
- Bulk export → a
job_identifier, then a{ status, downloadUrl }once the
CSV is ready.
- Redaction → the same object shape with PII fields replaced by
[REDACTED]. - Retention →
{ deleted: { [cacheType]: count } }per swept cache type.
Error Handling
| Issue | Cause | Solution |
|---|---|---|
| Export job stuck in "pending" | Large dataset | Poll every 30s, timeout at 1h |
| Deletion returns 404 | Already deleted | Log and continue (idempotent) |
| PII in conversation bodies | User-submitted content | Scan with regex, redact in logs |
| Audit log gap | Failed write | Use write-ahead log or queue |
Examples
Full worked examples — fulfilling a DSAR, honoring a deletion request, polling a
bulk export to completion, and redacting before logging — are in
references/examples.md. The shortest one:
// A user asks for all their data — export the whole bundle to JSON.
const bundle = await exportContactData("5f3c9b2e8a1d4e0012ab34cd");
await fs.writeFile(`dsar/${bundle.contact.id}.json`, JSON.stringify(bundle, null, 2));
Resources
- Full implementation walkthrough — all five workflows, copy-ready
- Worked examples — end-to-end usage + data minimization
- Data Export API
- Contacts API
- Intercom Privacy
Next Steps
For enterprise access control and permission scoping on top of these data
workflows, see the intercom-enterprise-rbac skill in this pack.