Skip to main content
RapidDev - Software Development Agency
retool-integrationsREST API Resource

How to Integrate Retool with Intercom

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.

What you'll learn

  • How to create an Intercom app in the Developer Hub and obtain an access token with appropriate scopes
  • How to configure an Intercom REST API Resource in Retool with Bearer token authentication
  • How to search and manage Intercom conversations, contacts, and companies via the REST API
  • How to build a customer 360 dashboard that combines Intercom data with internal database records
  • How to send messages and update conversation state from Retool using Intercom's API write endpoints
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate15 min read25 minutesCommunicationLast updated April 2026RapidDev Engineering Team
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.

Quick facts about this guide
FactValue
ToolIntercom
CategoryCommunication
MethodREST API Resource
DifficultyIntermediate
Time required25 minutes
Last updatedApril 2026

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.

Integration method

REST API Resource

Intercom provides a REST API (https://api.intercom.io/) authenticated with an access token obtained from an Intercom app created in the Developer Hub. The access token is sent as a Bearer token in every request. Retool connects via a REST API Resource with Bearer token authentication, proxying all requests server-side so the access token never reaches the browser. CORS is not a concern. A second integration mode — embedding Intercom Messenger inside Retool apps for live chat with end users — requires Retool Business or Enterprise plans and is a separate configuration from the REST API approach.

Prerequisites

  • 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.

Pro tip: Check your Intercom workspace region in Settings → General → Workspace Region before configuring the Retool resource base URL. Using the wrong regional API endpoint causes authentication failures even with a valid access token.

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.

Pro tip: Always specify the Intercom-Version header in your REST API Resource configuration. Intercom uses this header for API versioning, and omitting it defaults to an older version that may have different response structures than the current documentation describes.

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.

conversations_transformer.js
1// Transformer: normalize Intercom conversations for Table display
2const conversations = data.conversations || [];
3return conversations.map(conv => ({
4 id: conv.id,
5 contact_name: conv.source?.author?.name || conv.contacts?.contacts?.[0]?.name || 'Unknown',
6 contact_email: conv.contacts?.contacts?.[0]?.email || '',
7 subject: conv.title || (conv.source?.body || '').replace(/<[^>]+>/g, '').substring(0, 80),
8 state: conv.state,
9 assignee: conv.assignee?.name || 'Unassigned',
10 team: conv.team_assignee?.name || '',
11 tags: (conv.tags?.tags || []).map(t => t.name).join(', '),
12 created: new Date(conv.created_at * 1000).toLocaleDateString(),
13 updated: new Date(conv.updated_at * 1000).toLocaleDateString(),
14 waiting_since: conv.waiting_since
15 ? Math.floor((Date.now() - conv.waiting_since * 1000) / 3600000) + 'h'
16 : ''
17}));

Pro tip: Intercom timestamps are Unix timestamps in seconds (not milliseconds). Multiply by 1000 before passing to JavaScript Date constructors: new Date(conv.created_at * 1000).

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.

reply_conversation_body.json
1// Query body: Reply to an Intercom conversation
2// Method: POST
3// Path: /conversations/{{ conversationsTable.selectedRow.id }}/reply
4{
5 "type": "admin",
6 "message_type": "comment",
7 "body": {{ JSON.stringify(replyTextInput.value) }},
8 "admin_id": {{ JSON.stringify(retoolContext.currentUser.email) }}
9}

Pro tip: Intercom's conversation reply endpoint requires the 'admin_id' field set to the ID (not email) of the Intercom admin sending the reply. Create a query 'getAdminProfile' (GET /me) to retrieve the admin ID for the authenticated token and bind it to the reply query body.

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.

customer_profile_merge.js
1// JavaScript query: merge Intercom contact with internal DB record
2const intercomContact = searchContacts.data.data?.[0] || {};
3const dbCustomer = getCustomerFromDB.data?.[0] || {};
4
5return {
6 // Intercom fields
7 intercom_id: intercomContact.id,
8 name: intercomContact.name || 'Unknown',
9 email: intercomContact.email || '',
10 last_seen: intercomContact.last_seen_at
11 ? new Date(intercomContact.last_seen_at * 1000).toLocaleDateString()
12 : 'Never',
13 conversation_count: intercomContact.conversation_count || 0,
14
15 // Internal DB fields
16 plan: dbCustomer.plan || 'Unknown',
17 mrr: dbCustomer.mrr ? '$' + dbCustomer.mrr : 'N/A',
18 account_manager: dbCustomer.account_manager || 'Unassigned',
19 customer_since: dbCustomer.created_at
20 ? new Date(dbCustomer.created_at).toLocaleDateString()
21 : 'Unknown',
22 trial_end: dbCustomer.trial_end
23 ? new Date(dbCustomer.trial_end).toLocaleDateString()
24 : 'N/A'
25};

Pro tip: Use Retool's Transformer feature (Code panel → Transformers) to create standalone transformers that merge multiple query results — this keeps the join logic centralized and reusable across multiple app components rather than duplicating it in each component's data binding.

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.

Common 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.

Retool Prompt

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.

Copy this prompt to try it in Retool

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.

Retool Prompt

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.

Copy this prompt to try it in Retool

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.

Retool Prompt

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.

Copy this prompt to try it in Retool

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.

typescript
1// Correct Intercom timestamp conversion
2const date = new Date(intercomTimestamp * 1000).toLocaleDateString();
3// 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.

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

Alternatives

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.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Integrations are where projects stall

We wire Retool integrations like this one every week — auth, webhooks, edge cases included. Fixed-price builds from $13K, delivered in 6–10 weeks.

Talk to an integration engineer

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.