Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
329 changes: 329 additions & 0 deletions skills/intercom-api/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,329 @@
---
name: intercom-api
description: "Perform write operations on Intercom conversations and Help Center articles via REST API. Use when you need to reply, add notes, assign, close, snooze, or reopen conversations, or create/update Help Center articles. Trigger when: user says 'reply to intercom', 'close conversation', 'add note', 'update help article', 'assign conversation', or any Intercom write operation."
tags:
- intercom
- support
- customer-service
- help-center
version: "1.0.0"
allowed-tools:
- Bash
- Read
- Edit
- Write
---

# Intercom API (Write Operations)

Perform write operations on Intercom conversations and Help Center via REST API using curl.

## Authentication

Store your Intercom Personal Access Token as an environment variable. The `Intercom-Version: 2.11` header is **required** on all requests.

```bash
# Set your token (add to ~/.zshenv, ~/.bashrc, or ~/.zshrc)
export INTERCOM_ACCESS_TOKEN="your-token-here"

# Test authentication
curl -s https://api.intercom.io/me \
-H "Authorization: Bearer $INTERCOM_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Intercom-Version: 2.11" \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d['name'], d['email'])"
```

## Conversation Write Operations

All conversation actions use `$CONVERSATION_ID`. Find this from the Intercom URL or search API.

### Reply to Conversation (Customer-Visible)

Sends a reply that the customer can see.

```bash
CONVERSATION_ID="12345678"
ADMIN_ID="YOUR_ADMIN_ID"

curl -s -X POST "https://api.intercom.io/conversations/$CONVERSATION_ID/reply" \
-H "Authorization: Bearer $INTERCOM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Intercom-Version: 2.11" \
-d "{
\"message_type\": \"comment\",
\"type\": \"admin\",
\"admin_id\": \"$ADMIN_ID\",
\"body\": \"Your reply text here.\"
}" | python3 -c "import sys,json; d=json.load(sys.stdin); print('Reply sent:', d.get('id', d))"
```

### Add Internal Note

Adds a note visible only to admins (not the customer). Notes support HTML.

```bash
CONVERSATION_ID="12345678"
ADMIN_ID="YOUR_ADMIN_ID"

curl -s -X POST "https://api.intercom.io/conversations/$CONVERSATION_ID/reply" \
-H "Authorization: Bearer $INTERCOM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Intercom-Version: 2.11" \
-d "{
\"message_type\": \"note\",
\"type\": \"admin\",
\"admin_id\": \"$ADMIN_ID\",
\"body\": \"<p>Investigation notes here.</p><p>Root cause: ...</p>\"
}" | python3 -c "import sys,json; d=json.load(sys.stdin); print('Note added:', d.get('id', d))"
```

### Assign Conversation

```bash
CONVERSATION_ID="12345678"
ADMIN_ID="YOUR_ADMIN_ID" # Admin performing the assignment
ASSIGNEE_ID="TARGET_ADMIN_ID" # Who to assign to

curl -s -X POST "https://api.intercom.io/conversations/$CONVERSATION_ID/parts" \
-H "Authorization: Bearer $INTERCOM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Intercom-Version: 2.11" \
-d "{
\"message_type\": \"assignment\",
\"type\": \"admin\",
\"admin_id\": \"$ADMIN_ID\",
\"assignee_id\": \"$ASSIGNEE_ID\",
\"body\": \"Assigning to support team for follow-up.\"
}" | python3 -c "import sys,json; d=json.load(sys.stdin); print('Assigned:', d.get('conversation_parts', {}).get('conversation_parts', [{}])[0].get('id', d))"
```

### Close Conversation

```bash
CONVERSATION_ID="12345678"
ADMIN_ID="YOUR_ADMIN_ID"

curl -s -X POST "https://api.intercom.io/conversations/$CONVERSATION_ID/parts" \
-H "Authorization: Bearer $INTERCOM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Intercom-Version: 2.11" \
-d "{
\"message_type\": \"close\",
\"type\": \"admin\",
\"admin_id\": \"$ADMIN_ID\"
}" | python3 -c "import sys,json; d=json.load(sys.stdin); print('Closed. State:', d.get('state', d))"
```

### Snooze Conversation

Snooze until a Unix timestamp.

```bash
CONVERSATION_ID="12345678"
ADMIN_ID="YOUR_ADMIN_ID"
# macOS: $(date -v+1d +%s) Linux: $(date -d '+1 day' +%s)
SNOOZE_UNTIL=$(date -v+1d +%s)

curl -s -X POST "https://api.intercom.io/conversations/$CONVERSATION_ID/parts" \
-H "Authorization: Bearer $INTERCOM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Intercom-Version: 2.11" \
-d "{
\"message_type\": \"snoozed\",
\"type\": \"admin\",
\"admin_id\": \"$ADMIN_ID\",
\"snoozed_until\": $SNOOZE_UNTIL
}" | python3 -c "import sys,json; d=json.load(sys.stdin); print('Snoozed until:', d.get('snoozed_until', d))"
```

### Open (Reopen) Conversation

```bash
CONVERSATION_ID="12345678"
ADMIN_ID="YOUR_ADMIN_ID"

curl -s -X POST "https://api.intercom.io/conversations/$CONVERSATION_ID/parts" \
-H "Authorization: Bearer $INTERCOM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Intercom-Version: 2.11" \
-d "{
\"message_type\": \"open\",
\"type\": \"admin\",
\"admin_id\": \"$ADMIN_ID\"
}" | python3 -c "import sys,json; d=json.load(sys.stdin); print('Opened. State:', d.get('state', d))"
```

## Tracker Tickets

Create tracker tickets to group related customer issues.

```bash
python3 - <<'PYEOF'
import subprocess, json, os

token = os.environ["INTERCOM_ACCESS_TOKEN"]

payload = json.dumps({
"ticket_type_id": "YOUR_TICKET_TYPE_ID",
"ticket_attributes": {
"_default_title_": "Short bug title",
"_default_description_": "Description of the issue and any linked references"
},
"contacts": []
})

result = subprocess.run([
"curl", "-s", "-X", "POST", "https://api.intercom.io/tickets",
"-H", f"Authorization: Bearer {token}",
"-H", "Content-Type: application/json",
"-H", "Accept: application/json",
"-H", "Intercom-Version: 2.11",
"-d", payload
], capture_output=True, text=True)

d = json.loads(result.stdout)
print("Ticket ID:", d.get("ticket_id"))
print("Internal ID:", d.get("id"))
PYEOF
```

Use `python3` heredoc pattern (not inline curl) to avoid shell escaping issues with apostrophes in the description.

**Note:** Linking tracker tickets to conversations is UI-only. The REST API linking endpoints silently fail. Use the Intercom UI to link tickets to conversations.

## Help Center Management

### List All Articles

```bash
curl -s "https://api.intercom.io/articles" \
-H "Authorization: Bearer $INTERCOM_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Intercom-Version: 2.11" \
| python3 -c "
import sys, json
d = json.load(sys.stdin)
for a in d.get('data', []):
print(f\"{a['id']:10} {a.get('state',''):10} {a.get('title','')[:60]}\")
print(f'\nTotal: {len(d.get(\"data\", []))}')
"
```

### Get Article Details

```bash
ARTICLE_ID="12345"

curl -s "https://api.intercom.io/articles/$ARTICLE_ID" \
-H "Authorization: Bearer $INTERCOM_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Intercom-Version: 2.11" \
| python3 -c "
import sys, json
d = json.load(sys.stdin)
print('Title:', d.get('title'))
print('State:', d.get('state'))
print('URL:', d.get('url'))
print()
print('Body (truncated):')
print(d.get('body', '')[:500])
"
```

### Create Article

```bash
AUTHOR_ID="YOUR_ADMIN_ID"
PARENT_ID="YOUR_COLLECTION_ID"

curl -s -X POST "https://api.intercom.io/articles" \
-H "Authorization: Bearer $INTERCOM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Intercom-Version: 2.11" \
-d "{
\"title\": \"Article Title\",
\"description\": \"Short description shown in search results\",
\"body\": \"<h2>Overview</h2><p>Content here...</p>\",
\"author_id\": $AUTHOR_ID,
\"state\": \"draft\",
\"parent_id\": $PARENT_ID,
\"parent_type\": \"collection\"
}" | python3 -c "import sys,json; d=json.load(sys.stdin); print('Created:', d.get('id'), d.get('title'), d.get('url'))"
```

States: `"draft"` (default) or `"published"`. Parent types: `"collection"` or `"section"`.

### Update Article

```bash
ARTICLE_ID="12345"

curl -s -X PUT "https://api.intercom.io/articles/$ARTICLE_ID" \
-H "Authorization: Bearer $INTERCOM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Intercom-Version: 2.11" \
-d "{
\"title\": \"Updated Title\",
\"body\": \"<h2>Overview</h2><p>Updated content...</p>\",
\"state\": \"published\"
}" | python3 -c "import sys,json; d=json.load(sys.stdin); print('Updated:', d.get('id'), d.get('title'), d.get('state'))"
```

### List Collections

```bash
curl -s "https://api.intercom.io/help_center/collections" \
-H "Authorization: Bearer $INTERCOM_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Intercom-Version: 2.11" \
| python3 -c "
import sys, json
d = json.load(sys.stdin)
for c in d.get('data', []):
print(f\"{c['id']:10} {c.get('name','')}\")
"
```

## Help Center Editing Workflow

1. **List articles** to find the one to edit
2. **Get article details** to read current content
3. **Draft updated content** - body must be valid HTML (`<h2>`, `<p>`, `<ul><li>`, `<strong>`, `<a href>`)
4. **Update as draft** first (`"state": "draft"`)
5. **Confirm with user** before publishing
6. **Publish** by updating `"state": "published"`

## Error Handling

| Status | Meaning | Fix |
|--------|---------|-----|
| 401 | Invalid token | Check `INTERCOM_ACCESS_TOKEN` is set and valid |
| 403 | Insufficient permissions | Token needs write scopes |
| 404 | Resource not found | Verify the ID |
| 422 | Invalid request body | Check required fields and types |
| 429 | Rate limited | Wait and retry; Intercom limit is 1000/min |

## Quick Reference

| Operation | Endpoint | Method | Key Field |
|-----------|----------|--------|-----------|
| Reply (visible) | `/conversations/{id}/reply` | POST | `message_type: "comment"` |
| Internal note | `/conversations/{id}/reply` | POST | `message_type: "note"` |
| Assign | `/conversations/{id}/parts` | POST | `message_type: "assignment"` |
| Close | `/conversations/{id}/parts` | POST | `message_type: "close"` |
| Snooze | `/conversations/{id}/parts` | POST | `message_type: "snoozed"` |
| Open/reopen | `/conversations/{id}/parts` | POST | `message_type: "open"` |
| List articles | `/articles` | GET | |
| Get article | `/articles/{id}` | GET | |
| Create article | `/articles` | POST | `state: "draft"/"published"` |
| Update article | `/articles/{id}` | PUT | |
| List collections | `/help_center/collections` | GET | |
Loading