# How to Integrate Retool with Intercom

- Tool: Retool
- Difficulty: Intermediate
- Time required: 25 minutes
- Last updated: April 2026

## TL;DR

Connect Retool to Intercom using a REST API Resource with Bearer token authentication using your Intercom access token. Build a unified customer support 360 dashboard that searches conversations, manages user profiles, sends messages, and combines Intercom's customer support data with internal records from your database — all in a single Retool interface.

## Build a Customer Support 360 Dashboard with Intercom and Retool

Intercom is the primary customer communication channel for many SaaS companies — conversations, email sequences, product tours, and help center content all flow through it. Support and success teams often need to view Intercom conversation history alongside internal data: subscription tier, recent orders, feature usage, or account health metrics stored in internal databases. Retool bridges this gap by combining Intercom's API with other data sources in a unified internal tool.

With a Retool-Intercom integration, you can build a customer 360 panel that shows all Intercom conversations for a selected user alongside their subscription data from Stripe, their recent activity from your PostgreSQL database, and their support history from your ticketing system. You can build a conversation management dashboard that surfaces conversations by status, tag, and assignee with bulk action capabilities. Or you can create an escalation workflow panel that identifies conversations needing attention based on response time and customer tier, combining Intercom's conversation data with CRM priority scoring.

Intercom's API covers the full breadth of its platform: conversations (including message history and state management), contacts (users and leads), companies, tags, teams, and data events. Building read-only reporting and enrichment views is straightforward with the Bearer token API access, and write operations (replying to conversations, applying tags, updating contact properties) are equally well-supported.

## Before you start

- An Intercom account with workspace admin access
- An Intercom app created in the Developer Hub (https://app.intercom.com/a/developer-signup) with an access token
- A Retool account with permission to create Resources
- Basic familiarity with Intercom's data model (conversations, contacts, companies, teams)
- Understanding of REST API Bearer token authentication

## Step-by-step guide

### 1. Create an Intercom Developer Hub app and obtain an access token

Before configuring Retool, create an Intercom app to obtain API credentials. Navigate to the Intercom Developer Hub at https://developers.intercom.com and click 'New App'. Fill in your app name (e.g., 'Retool Dashboard') and select the workspace you want to access. After creating the app, you are taken to the app's configuration page. Click on 'Authentication' in the left sidebar. You will see an 'Access Token' section. For the Retool integration, click 'Use Access Token' — this gives you a workspace-scoped token that works immediately without OAuth configuration. Copy the access token. The token provides access to all Intercom API endpoints for your workspace — it is equivalent to a service account with full API access. For production integrations, consider creating a more constrained token by configuring OAuth scopes, but for internal tool dashboards the workspace access token is sufficient. Store the token securely — it does not expire but can be rotated from the Developer Hub if compromised. Note: if your Intercom workspace uses multiple regions, verify the API base URL: EU workspaces use https://api.eu.intercom.io and AU workspaces use https://api.au.intercom.io rather than the default https://api.intercom.io.

**Expected result:** You have an Intercom Developer Hub app with an access token copied and ready for Retool configuration.

### 2. Create the Intercom REST API Resource in Retool

In Retool, click the Resources tab in the left sidebar and click Add Resource. Select REST API from the resource type list. Name the resource 'Intercom API'. In the Base URL field, enter the correct base URL for your Intercom workspace region: https://api.intercom.io for US workspaces, https://api.eu.intercom.io for EU workspaces, or https://api.au.intercom.io for Australian workspaces. Scroll to the Authentication section and select Bearer Token from the authentication dropdown. Paste your Intercom access token in the Bearer Token field. Alternatively, add it to Retool Configuration Variables first (Settings → Configuration Variables → Add Variable, name it INTERCOM_ACCESS_TOKEN and mark it as a secret), then reference it as {{ retoolContext.configVars.INTERCOM_ACCESS_TOKEN }} in the Bearer Token field. Scroll to the Headers section and add two default headers that Intercom requires: set Accept to application/json, and set Intercom-Version to 2.10 (or the current API version — check Intercom's developer documentation for the latest stable version). The Intercom-Version header tells the API which version to use; without it, responses may use an older deprecated format. Click Save Changes. The resource is now ready for queries.

**Expected result:** An Intercom API resource appears in your Retool Resources list with the correct regional base URL, Bearer token authentication, and Intercom-Version header configured.

### 3. Query Intercom conversations and contacts

Create the foundational queries for the customer support dashboard. In a Retool app, open the Code panel and click + to add a new query. Select your Intercom API resource. Name the first query 'searchConversations'. Intercom provides a powerful search endpoint at /conversations/search — set Method to POST and Path to /conversations/search. The request body contains a 'query' object specifying filter conditions. A basic open conversations query uses: { 'query': { 'operator': 'AND', 'value': [{ 'field': 'state', 'operator': '=', 'value': 'open' }] }, 'pagination': { 'per_page': 25 } }. Bind the filter conditions to UI components (Select for status, Text Input for email search). Create a second query named 'searchContacts' with Method POST, Path /contacts/search. Use a query body that searches by email: { 'query': { 'operator': 'AND', 'value': [{ 'field': 'email', 'operator': '=', 'value': emailSearch.value }] } }. Create a third query named 'getConversationDetail' with Method GET and Path /conversations/{{ conversationsTable.selectedRow.id }}. Add a JavaScript transformer to the searchConversations query that extracts the key fields from the response: id, created_at, updated_at, title (or first message preview), assignee name, state, and tag list.

```
// Transformer: normalize Intercom conversations for Table display
const conversations = data.conversations || [];
return conversations.map(conv => ({
  id: conv.id,
  contact_name: conv.source?.author?.name || conv.contacts?.contacts?.[0]?.name || 'Unknown',
  contact_email: conv.contacts?.contacts?.[0]?.email || '',
  subject: conv.title || (conv.source?.body || '').replace(/<[^>]+>/g, '').substring(0, 80),
  state: conv.state,
  assignee: conv.assignee?.name || 'Unassigned',
  team: conv.team_assignee?.name || '',
  tags: (conv.tags?.tags || []).map(t => t.name).join(', '),
  created: new Date(conv.created_at * 1000).toLocaleDateString(),
  updated: new Date(conv.updated_at * 1000).toLocaleDateString(),
  waiting_since: conv.waiting_since
    ? Math.floor((Date.now() - conv.waiting_since * 1000) / 3600000) + 'h'
    : ''
}));
```

**Expected result:** The searchConversations query returns a normalized list of Intercom conversations with contact names, assignees, and states formatted for display in a Retool Table.

### 4. Build the customer 360 support dashboard UI

Assemble the dashboard interface. Drag a Text Input component to the top of the canvas for email search (name it 'emailSearch'). Drag a Button labeled 'Search Customer' that triggers both the searchContacts and searchConversations queries. Below the search bar, create a two-column layout using Container components: left side for the conversation list, right side for customer and conversation detail. In the left Container, drag a Table component and set its Data to {{ searchConversations.data }}. Configure columns: contact_name, subject (truncated), state (as a Tag with color: open=green, closed=grey), assignee, waiting_since. Add a row selection event that triggers the getConversationDetail query. In the right Container, create sub-sections: a Contact Info section showing the contact's name, email, and plan from searchContacts data; a Conversation Detail section showing the full conversation message thread from getConversationDetail; and an Actions panel with three buttons: 'Reply', 'Close Conversation', and 'Apply Tag'. Create a 'replyToConversation' query with Method POST, Path /conversations/{{ conversationsTable.selectedRow.id }}/reply, and a JSON body with type 'admin', message_type 'comment', and body bound to a Multiline Text Input. Create a 'closeConversation' query with Method POST, Path /conversations/{{ conversationsTable.selectedRow.id }}/parts, body type JSON, body { type: 'admin', message_type: 'close' }. Add confirmation modals to destructive actions.

```
// Query body: Reply to an Intercom conversation
// Method: POST
// Path: /conversations/{{ conversationsTable.selectedRow.id }}/reply
{
  "type": "admin",
  "message_type": "comment",
  "body": {{ JSON.stringify(replyTextInput.value) }},
  "admin_id": {{ JSON.stringify(retoolContext.currentUser.email) }}
}
```

**Expected result:** A customer 360 dashboard displays Intercom conversations on the left with a contact detail and conversation thread panel on the right, including reply and conversation management actions.

### 5. Combine Intercom data with internal database records

The most powerful pattern in a Retool-Intercom integration is combining conversation data with internal records. Add a second Resource in Retool — for example, a PostgreSQL database containing your customer records, subscription data, or order history. Create a companion query named 'getCustomerFromDB' that uses the email address from the selected Intercom contact to look up the internal customer record: SELECT c.id, c.plan, c.mrr, c.trial_end, c.created_at, c.account_manager FROM customers c WHERE c.email = '{{ searchContacts.data.data?.[0]?.email }}'. Create additional queries for related data: recent orders, feature usage events, or subscription history. Display these results in the right Container's detail panels below the Intercom conversation thread. Use a JavaScript query named 'buildCustomerProfile' to merge the Intercom contact data with the database record into a unified view: combine Intercom's last_seen, browser, location data with the database's plan, MRR, and account manager fields. Display the merged profile in Statistic components at the top of the detail panel. For complex multi-source customer 360 integrations combining Intercom conversations with Stripe billing data, product usage analytics, and CRM records in a unified view, RapidDev's team can help architect and build your complete Retool support operations platform.

```
// JavaScript query: merge Intercom contact with internal DB record
const intercomContact = searchContacts.data.data?.[0] || {};
const dbCustomer = getCustomerFromDB.data?.[0] || {};

return {
  // Intercom fields
  intercom_id: intercomContact.id,
  name: intercomContact.name || 'Unknown',
  email: intercomContact.email || '',
  last_seen: intercomContact.last_seen_at
    ? new Date(intercomContact.last_seen_at * 1000).toLocaleDateString()
    : 'Never',
  conversation_count: intercomContact.conversation_count || 0,
  
  // Internal DB fields
  plan: dbCustomer.plan || 'Unknown',
  mrr: dbCustomer.mrr ? '$' + dbCustomer.mrr : 'N/A',
  account_manager: dbCustomer.account_manager || 'Unassigned',
  customer_since: dbCustomer.created_at
    ? new Date(dbCustomer.created_at).toLocaleDateString()
    : 'Unknown',
  trial_end: dbCustomer.trial_end
    ? new Date(dbCustomer.trial_end).toLocaleDateString()
    : 'N/A'
};
```

**Expected result:** The support dashboard shows a fully merged customer profile combining Intercom conversation history, contact properties, and internal database records — giving support agents complete customer context without leaving Retool.

## Best practices

- Store your Intercom access token in Retool Configuration Variables as a secret (Settings → Configuration Variables) rather than directly in the Bearer Token field to enable rotation without resource reconfiguration
- Always include the Intercom-Version header in your REST API Resource configuration to ensure consistent API behavior — specify the current stable version number and update it consciously during Intercom API version upgrades
- Verify your Intercom workspace region before configuring the resource base URL — EU and AU workspaces use different API endpoints and authentication will fail silently if the wrong regional URL is used
- Use the /conversations/search endpoint with targeted filter queries rather than loading all conversations and filtering client-side — this dramatically reduces payload size and respects Intercom's rate limits
- Cache the getAdminProfile query result and store the admin ID in a Retool state variable — you need this ID for reply requests and triggering it repeatedly on every conversation selection is wasteful
- Add query caching (30-60 seconds) to conversation list queries when multiple support agents use the dashboard simultaneously — conversation data changes frequently but not every second, so short caching significantly reduces API pressure
- Use Retool Workflows for batch operations like bulk tagging conversations or sending outreach messages to contact segments — in-app JavaScript loops for bulk API calls can hit Intercom rate limits and fail without clear error messaging

## Use cases

### Build a unified customer 360 view combining Intercom with internal data

Create a Retool panel where support agents search for a customer by email, instantly pulling their Intercom conversation history alongside subscription tier from Stripe, recent purchases from your order database, and feature usage from your analytics backend. Display the combined view in a tabbed layout: one tab for conversation history, one for billing details, one for product usage metrics. This eliminates the context switching between Intercom, Stripe, and internal dashboards that slows support resolution time.

Prompt example:

```
Build a Retool customer support panel where agents search by email. Show their Intercom conversation list on the left with a conversation detail panel on the right. Below the conversations, display their subscription plan from a PostgreSQL customers table, their last 5 orders, and their monthly active days from a product analytics query. All panels should update when a different customer email is searched.
```

### Build an Intercom conversation management and triage dashboard

Create a Retool conversation management panel that displays open Intercom conversations filtered by team, assignee, and tag. Show response time SLA indicators for each conversation and surface conversations approaching or breaching response time targets. Add bulk action capabilities: assign conversations to team members, apply tags, and snooze conversations directly from Retool. Include a Chart showing conversation volume by hour of day and day of week to help managers plan team scheduling.

Prompt example:

```
Build a Retool conversation triage dashboard showing all open Intercom conversations in a Table with columns for contact name, conversation snippet, assigned team, time since last reply, and tags. Color-code rows by response time urgency. Add an 'Assign' button that calls the Intercom API to reassign the conversation, a 'Tag' dropdown to apply tags, and a Chart of daily conversation volume for the past 14 days.
```

### Build a proactive messaging and campaign monitoring panel

Create a Retool panel for customer success managers to send targeted Intercom messages to specific user segments and monitor message delivery performance. Allow managers to search for users matching specific criteria (e.g., trial users who have not invited a teammate), compose custom Intercom messages, and send them in bulk. Track sent message open rates and response rates in a Charts dashboard pulled from Intercom's message analytics endpoints.

Prompt example:

```
Build a Retool outreach panel where customer success managers search for Intercom contacts matching filter criteria (plan type, last seen date, tag). Show matching contacts in a Table with checkboxes. Add a 'Send Message' panel where managers compose a message with subject and body, then trigger the Intercom API to send it to all selected contacts. Show a delivery status Chart for recent outreach campaigns.
```

## Troubleshooting

### 401 Unauthorized errors on all Intercom API requests despite having the access token configured

Cause: The access token may have been revoked or the Intercom workspace region does not match the API base URL configured in Retool. US, EU, and AU workspaces use different API endpoints — using the US endpoint for an EU workspace causes authentication failures even with valid credentials.

Solution: Verify the workspace region in Intercom Settings → General → Workspace details. Ensure the Retool resource Base URL matches: https://api.intercom.io for US, https://api.eu.intercom.io for EU, https://api.au.intercom.io for AU. If the URL is correct, regenerate the access token in the Intercom Developer Hub and update the Retool Configuration Variable. Test the token directly with a curl request to confirm it is valid.

### Conversation search returns 0 results even though open conversations exist in the Intercom inbox

Cause: The Intercom conversations/search endpoint requires a JSON POST request body with a specific 'query' structure. An empty body, malformed query structure, or incorrect filter field names cause 0 results rather than an error.

Solution: Verify the POST request body is valid JSON with the correct structure: { 'query': { 'operator': 'AND', 'value': [ { 'field': 'state', 'operator': '=', 'value': 'open' } ] } }. Check the Body Type is set to JSON in the query configuration, not form data or raw text. Run the search with a minimal query body first (state = open) before adding additional filters to confirm the base query works.

### Conversation timestamps display incorrect dates — dates appear decades off or as 1970

Cause: Intercom returns timestamps as Unix timestamps in seconds. JavaScript's Date constructor expects milliseconds. Passing a seconds-based Unix timestamp to new Date() without multiplying by 1000 produces dates from the early 1970s.

Solution: Multiply all Intercom timestamps by 1000 before passing to Date constructors: new Date(conv.created_at * 1000).toLocaleDateString(). Apply this consistently throughout all transformers that handle Intercom date fields.

```
// Correct Intercom timestamp conversion
const date = new Date(intercomTimestamp * 1000).toLocaleDateString();
// NOT: new Date(intercomTimestamp).toLocaleDateString()
```

### Reply to conversation query returns 403 Forbidden even though the access token has admin access

Cause: The 'admin_id' field in the reply request body must be the numeric Intercom admin ID, not the email address or the access token. Using the wrong identifier type causes 403 authorization errors on conversation replies.

Solution: Create a query 'getMyAdminProfile' with Method GET and Path /me. This returns the authenticated admin's profile including their numeric 'id'. Store this ID and use it in the admin_id field of reply request bodies: "admin_id": {{ getMyAdminProfile.data.id }}. Run getMyAdminProfile once on app load and reference its result throughout the app.

## Frequently asked questions

### Does Retool have a native Intercom connector?

No, Retool does not have a native Intercom connector. You connect using a REST API Resource with Bearer token authentication. Intercom's API documentation at https://developers.intercom.com/docs/references/rest-api/ covers all available endpoints. Note that Retool Business and Enterprise plans do support embedding the Intercom Messenger widget directly inside Retool apps for live chat, but that is separate from the API-based REST integration.

### What is the difference between the Intercom API integration and embedding the Intercom Messenger in Retool?

The REST API integration (covered in this guide) connects Retool to Intercom's data: conversations, contacts, companies, and messages. This lets you build dashboards that read and write Intercom data. Embedding the Intercom Messenger is different: it adds the live chat widget to your Retool app so end users of that Retool app can initiate conversations with your support team. Messenger embedding requires a Retool Business or Enterprise plan and is configured through Retool's Settings.

### How do I filter conversations by assignee or team in the Intercom API?

Use Intercom's conversation search endpoint (POST /conversations/search) with filter conditions. To filter by assignee, add a filter condition: { 'field': 'assignee.id', 'operator': '=', 'value': 'ADMIN_ID' }. To filter by team, use { 'field': 'team_assignee.id', 'operator': '=', 'value': 'TEAM_ID' }. Combine multiple conditions using the 'AND' or 'OR' operator at the top level of the query object. Get admin IDs from GET /admins and team IDs from GET /teams.

### What are Intercom's API rate limits?

Intercom's API rate limits are 1,000 requests per minute for standard workspaces and higher for Enterprise plans. The rate limit information is included in response headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset). In Retool, add query caching to frequently-accessed queries and use Intercom's search endpoint with specific filters rather than loading all conversations — targeted queries use fewer API calls than broad queries with client-side filtering.

### Can I send Intercom messages to users from Retool?

Yes. Use POST /messages to send a new conversation initiated by an admin to a contact. The request body requires the message_type ('inapp', 'email', or 'push'), from object (admin ID and type), to object (user ID and type), and body (message content). You can also reply to existing conversations with POST /conversations/{id}/reply. Build a messaging form in Retool with a Multiline Text Input for the message body and a Button that triggers the send query.

---

Source: https://www.rapidevelopers.com/retool-integrations/intercom
© RapidDev — https://www.rapidevelopers.com/retool-integrations/intercom
