Manage the full conversation lifecycle: create, reply (as admin or contact), assign to teams, close, snooze, and tag. Conversations contain threaded "parts" including messages, notes, and assignments.
intercom-install-auth setupclient.admins.list())Conversations are created when a contact sends a message.
import { IntercomClient } from "intercom-client";
const client = new IntercomClient({
token: process.env.INTERCOM_ACCESS_TOKEN!,
});
// Create conversation from a contact
const conversation = await client.conversations.create({
from: {
type: "user",
id: "6657add46abd0167d9419c3a", // Contact ID
},
body: "Hi, I'm having trouble with my billing. Can you help?",
});
console.log(`Conversation ID: ${conversation.conversationId}`);
// Admin reply (visible to customer)
await client.conversations.reply({
conversationId: conversation.conversationId,
body: "Hi there! I'd be happy to help with billing. What's the issue?",
type: "admin",
adminId: "12345", // Your admin ID
});
// Admin note (internal, not visible to customer)
await client.conversations.reply({
conversationId: conversation.conversationId,
body: "Customer is on Enterprise plan, checking billing system...",
type: "note",
adminId: "12345",
});
// Contact reply
await client.conversations.reply({
conversationId: conversation.conversationId,
body: "I was charged twice for this month.",
type: "user",
intercomUserId: "6657add46abd0167d9419c3a",
});
// Assign to a specific admin
await client.conversations.assign({
conversationId: conversation.conversationId,
type: "admin",
adminId: "12345",
assigneeId: "67890", // Target admin ID
body: "Assigning to billing specialist",
});
// Assign to a team
await client.conversations.assign({
conversationId: conversation.conversationId,
type: "team",
adminId: "12345",
assigneeId: "team-billing-123",
body: "Routing to billing team",
});
// Auto-assign using assignment rules
// POST /conversations/{id}/run_assignment_rules
await fetch(`https://api.intercom.io/conversations/${conversation.conversationId}/run_assignment_rules`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.INTERCOM_ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
});
// Close a conversation (with optional closing message)
await client.conversations.close({
conversationId: conversation.conversationId,
adminId: "12345",
body: "Issue resolved! Let us know if you need anything else.",
});
// Snooze until a specific time
await client.conversations.snooze({
conversationId: conversation.conversationId,
adminId: "12345",
snoozedUntil: Math.floor(Date.now() / 1000) + 86400, // 24 hours from now
});
// Reopen a closed conversation
await client.conversations.open({
conversationId: conversation.conversationId,
adminId: "12345",
});
// Tag a conversation
await client.conversations.attachTag({
conversationId: conversation.conversationId,
tagId: "tag-billing-issue",
adminId: "12345",
});
// Remove a tag
await client.conversations.detachTag({
conversationId: conversation.conversationId,
tagId: "tag-billing-issue",
adminId: "12345",
});
const full = await client.conversations.find({
conversationId: conversation.conversationId,
});
console.log(`State: ${full.state}`); // "open", "closed", "snoozed"
console.log(`Assignee: ${full.adminAssigneeId}`);
console.log(`Parts: ${full.conversationParts.totalCount}`);
// Iterate conversation parts (messages, notes, assignments)
for (const part of full.conversationParts.conversationParts) {
console.log(` [${part.partType}] ${part.author.type}: ${part.body?.substring(0, 50)}`);
}
// Conversation parts include:
// - comment (admin/user messages)
// - note (internal notes)
// - assignment (team/admin assignments)
// - close/open (state changes)
// List all conversations
const conversations = await client.conversations.list();
// Search conversations
const searched = await client.conversations.search({
query: {
operator: "AND",
value: [
{ field: "state", operator: "=", value: "open" },
{ field: "admin_assignee_id", operator: "=", value: "12345" },
],
},
pagination: { per_page: 20 },
sort: { field: "updated_at", order: "descending" },
});
| State | Description | Transitions |
|---|---|---|
open |
Active, awaiting action | close, snooze |
closed |
Resolved | open |
snoozed |
Deferred until timestamp | open (auto or manual) |
| Part Type | Description | Who Creates |
|---|---|---|
comment |
Visible message | Admin or contact |
note |
Internal-only note | Admin |
assignment |
Reassignment record | System or admin |
close |
Conversation closed | Admin |
open |
Conversation reopened | Admin or contact |
| Error | HTTP Code | Cause | Solution |
|---|---|---|---|
not_found |
404 | Invalid conversation or admin ID | Verify IDs exist |
conversation_not_found |
404 | Conversation deleted | Handle gracefully |
admin_not_found |
404 | Admin ID invalid | Use client.admins.list() |
parameter_invalid |
422 | Missing body or type | Include required fields |
conversation_closed |
400 | Action on closed conversation | Reopen first |
For common errors and debugging, see intercom-common-errors.