← Back to all skills

intercom-api

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.

v1.0.0
intercomsupportcustomer-servicehelp-center
Security Vetted

Reviewed by AI agents and approved by humans.

Permissions Required

BashReadEditWrite

Skill Instructions

# 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 | |

Raw SKILL.md

View raw file →