Custom Channel Integration

Custom Channel Integration enables a two-way, event-driven connection between your product and Intercom. This allows you to embed Fin anywhere in your app by implementing it as a custom Intercom channel.

Using Fin over API gives your customer-facing app full control over the front-end experience, while Intercom handles conversation logic through an API triggered workflow.

Closed Beta

This feature is currently in closed beta. If you'd like early access, please reach out to your account manager or our support team for further information.


Overview

The integration flow operates over two sides:

  • Inbound Events: Your application sends events to Intercom (via Custom Channel Events API)
  • Outbound Events: Intercom sends events to your app (reflecting Fin's responses, buttons, resolutions, etc.)

This model allows your app to:

  • Trigger a workflow to start a conversation
  • Display Fin's responses, quick replies, and feedback states, as well as other deterministic workflow steps
  • Handover to human support when needed

Example

Assume a simple Intercom workflow is configured to allow your application to interact with Fin over API:

Setup page

Once your application is integrated as a Custom Channel, you can interact with Fin by exchanging events as illustrated below:

User conversation example

In this example:

  • The user starts the conversation, triggering the workflow with a new_conversation event.
  • Fin responds with a new_message, shows a typing animation, and offers quick reply buttons.
  • The user selects an option, and your app notifies Intercom via quick_reply_selected.
  • Based on user input and workflow logic, Fin sends resolution updates or ends the flow.

Inbound Events (Your App → Intercom)

Inbound events must be notified from your application to Intercom through the Custom Channel Events API.

Event typePurpose
new_conversationNotifies Intercom of a new conversation, triggering the API driven workflow
new_messageNotifies Intercom that the user sent a new message
quick_reply_selectedNotifies Intercom that the user selected a quick reply button
attribute_collectedNotifies Intercom that an attribute value was collected from the user

Outbound Events (Intercom → Your App)

Outbound events are notified from Intercom to your application.

Event TypePurpose
new_messageSent when Fin or a workflow step sends a message to your user
typingIndicates Fin is generating a response
quick_reply_optionsSends a list of buttons for the user to select
resolution_state_updatedNotifies your application changes in resolution states
user_became_idleIndicates the user became idle based on configured timeout
attribute_collectorRequests your app to collect a user attribute
new_noteSends an internal-only message from the workflow
conversation_tags_updatedCommunicates updated conversation tags
workflow_finishedIndicates the workflow ended and/or was handed off to a human

Your application must expose an endpoint to receive these POST events from Intercom. Each event includes at least:

{
  "event_type": "<event type>",
  "conversation_id": "<Intercom's conversation ID>",
  "external_conversation_id": "<external conversation ID>"
}

Details & Examples

new_message

New messages are expected to be rendered to your users.

{
  "event_type": "new_message",
  "conversation_id": "intercom_abc123",
  "external_conversation_id": "external_abc123",
  "text": "You have up to 40 days.",
  "html": "<p>You have up to 40 days.</p>"
}

✏️ typing

You may choose to use the typing event to provide feedback to your user when Fin is "thinking", like a typing animation.

{
  "event_type": "typing",
  "conversation_id": "intercom_abc123",
  "external_conversation_id": "external_abc123"
}

🎯 quick_reply_options

This event provides a set of buttons (quick replies) for the user to choose from. Whether your application sends a follow-up quick_reply_selected event depends on how the user responds:

  • When interacting with Fin, users are not required to select a button — they can simply type a message instead. Fin is capable of interpreting both positive and negative feedback from free-text responses.
  • However, when quick reply buttons are explicitly configured in the workflow, the expected behavior is for the user to select one, and for your application to send a quick_reply_selected event in response.
{
  "event_type": "quick_reply_options",
  "conversation_id": "intercom_abc123",
  "external_conversation_id": "external_abc123",
  "quick_reply_options": [
    { "id": "1", "text": "That helped" },
    { "id": "2", "text": "Talk to a Person" }
  ]
}

resolution_state_updated

Whenever Fin responds to a user question, it initially assumes the issue is resolved (soft_resolution). Fin then actively seeks to validate this through one of the following:

  • Asking follow-up confirmation questions
  • Interpreting implicit feedback from the user's next message
  • Collecting CSAT scores

Depending on the user's response or behavior, the state may change to:

  1. hard_resolution — positive confirmation from the user and no follow-up question
  2. routed_to_team — the user asks to speak to a person
  3. abandoned_negative_feedback — the user leaves after giving negative feedback

Please note, resolutions are only assumed if Fin is able to come up with an answer to a valid user question. Greeting messages and disambiguation messages from Fin are not counted as answers, and, therefore, not assumed as resolutions either.

{
  "event_type": "resolution_state_updated",
  "conversation_id": "intercom_abc123",
  "external_conversation_id": "external_abc123",
  "state": "soft_resolution" // or "hard_resolution", "routed_to_team", "abandoned_negative_feedback"
}

💤 user_became_idle

The "Let Fin Answer" step allows you to define how long a user can be inactive before being marked idle. When this happens, Intercom sends a user_became_idle event to your app. You can choose to use this to update the UI (e.g., disable the composer) or ignore it.

{
  "event_type": "user_became_idle",
  "conversation_id": "intercom_abc123",
  "external_conversation_id": "external_abc123"
}

📥 attribute_collector

Aside from Fin, you can also configure deterministic steps in your workflow, such as attribute collectors to collect information from your users. Intercom will send events about attribute values it requests your application to collect with your users, expecting to receive a corresponding attribute_collected event notification as a response.

{
  "event_type": "attribute_collector",
  "conversation_id": "intercom_abc123",
  "external_conversation_id": "external_abc123",
  "attributes": [
    {
      "id": "reason_for_return",
      "type": "string",
      "label": "Reason for return"
    }
  ]
}

📝 new_note

Aside from Fin, you can also configure deterministic steps in your workflow, such as internal notes to your teammates. These should not be rendered to your users, but your application may choose to use this for your own teammate inbox experience.

{
  "event_type": "new_note",
  "conversation_id": "intercom_abc123",
  "external_conversation_id": "external_abc123",
  "text": "Logged internal note"
}

🏷 conversation_tags_updated

Aside from Fin, you can also configure deterministic steps in your workflow, such as adding tags to conversations. These should not be rendered to your users, but your application may choose to use this to organise and track conversations.

{
  "event_type": "conversation_tags_updated",
  "conversation_id": "intercom_abc123",
  "external_conversation_id": "external_abc123",
  "tags_added": ["resolved"],
  "tags_removed": []
}

📤 workflow_finished

This event is sent once a workflow execution reaches its end, whether resolved or handed off to a teammate.

{
  "event_type": "workflow_finished",
  "conversation_id": "intercom_abc123",
  "external_conversation_id": "external_abc123"
}