Intercom Integration

Segment makes it easy to send your data to Intercom (and lots of other integrations). Once you've tracked your data through our open source libraries we'll translate and route your data to Intercom in the format they understand.

Getting Started

  1. Authorize your Intercom account in Segment.

  1. Select the Intercom Account you want to sync with Segment. You can choose which account to sync in the drop down menu in the top right.

  1. Now that you have authenticated, activate the Intercom integration.

  1. Once you have activated the integration this is what happens:
  • Our CDN is updated within 5-10 minutes. Then our snippet will start asynchronously loading Intercom’s library.js onto your page. This means you should remove Intercom’s snippet from your page.
  • Because Intercom only associates Track events with known users, an Identify call with a userId is required before Track events will be associated properly.


Calling page in Analytics.js triggers the Intercom update method, which will look for new Intercom messages that should be displayed to the current user.

The page and screen methods don’t have any effect on Intercom when used from our server-side or mobile SDKs.

If you have the Intercom’s Respond package, simply calling .page() (which is already included in our snippet) will trigger the chat widget to appear. Otherwise, you would need to call identify to make the chat widget appear.

Note: If you have the Respond package and calling page still does not show your chat widget, be sure to check your “Visitors on your website” setting inside your Intercom account!


From the Browser

When you call identify on analytics.js, we create the intercomSettings object and load Intercom’s javascript into the page. Here’s an example identify call that you can send:

analytics.identify('user1234', {
  email: '',
  name: 'Teemo',
  company: {
    id: '813',
    name: 'Teemo Holding Company'
    createdAt: 'Thu Mar 24 2016 17:44:51 GMT+0000 (UTC)'
  createdAt: 'Thu Mar 24 2016 17:46:45 GMT+0000 (UTC)'

Here’s how we create the intercomSettings object:

  • The userId parameter (the first argument) is set to intercomSettings.user_id.
  • The traits parameter (the second argument) is set to intercomSettings.custom_attributes.
  • If you send we set it as
  • If you send we set it as
  • If you send we set it as
  • If you send traits.createdAt as a javascript Date object, a valid date string, milliseconds since the epoch, or as seconds like a Unix timestamp, we set intercomSettings.created_at as the unix timestamp in seconds for that created date.

Note: -traits.avatar is read-only. Intercom determines the avatar based on the email address of the user.

  • Passing will create a new Intercom Company if the company_id does not match a known company. If company is a string, we will set the company_id as a hash of company_name as an id is required to associate the user to the company.

The group call may be used to create/update company profiles explicitly.

Collect Context

With this option selected, identify calls will include contextual information collected by Segment’s mobile libraries if it is available. This info will be set as Custom Attributes on the Intercom user.

The fields collected from the context object are device.type, device.manufacturer, device.model,, os.version,, app.version and will populate in Intercom as device_type, device_manufacturer, etc.

Server-Side & Mobile

When you call identify from any of the server-side or mobile sources, we create or update a user in Intercom. We’ll map our special traits (email, firstName, lastName, createdAt, and company) to Intercom special properties.

You must enter an API key in your Intercom Advanced settings on your Segment integrations page to make server-side or mobile calls to Intercom.

If you want to use Intercom’s last_request_at, you’ll need to pass in active: true in the context object. Then, by default we will set last_request_at to the current time; however, if you pass in your own timestamp, pass it in as lastRequestAt (in camelCase), and we’ll set last_request_at to that value in our server-side sources (coming soon on mobile!).

If you want to include last_seen_user_agent then include it in the context.userAgent. Similarly with last_seen_ip which is used for geolocation, you can include the IP address at context.ip. Click here for an example.


Segment supports Intercom events in all of our sources through the track method.

If you send properties.revenue and properties.currency, we will format that according to Intercom’s Monetary Amount and send it as:

price: {
  amount: <properties.revenue> * 100, // since Intercom requires this in cents
  currency: <properties.currency> // will default to 'usd'

Limited Properties

Intercom can only store 5 event properties per event. That means if you send an event to Segment with more than 5 properties, Intercom will only show the first 5 properties.

Limited Events

Intercom only allows a total of 120 unique event names (see the questions titled “Is there a limit on the number of event types I can send?”). That means if you are sending Segment more than 120 unique event names, Intercom will only accept the first 120 events that hit their servers.

Server-side Race Condition

Because our server-side libraries batch calls by default, it may happen that an Identify call intended to create a user arrives simultaneously with a Track event associated with this user. If the Track event is processed before the user is created, an error will result and the event will not be recorded.

Adding a Flush method immediately following the Identify, and before any subsequent Track event, will help the Identify call reach Intercom first to create the user. Generally, this prevents the race condition, but an additional timeout can be used if necessary.


Segment supports Intercom companies in all of our sources through the group method. Users can be put into multiple groups, which will associate them to multiple companies in Intercom.'companyId123', {
  name: 'Segment'

Segment also maps to Intercom’s special properties monthly_spend and plan. All you have to do is set traits.monthlySpend and traits.plan.


Disassociating Users from a Company

You can unassociate a user from a company by passing in a field inside the company trait with remove: true in your identify calls.

  userId: '019mr8mf4r',
  traits: {
    name: 'Michael Bolton',
    email: '',
    plan: 'Enterprise',
    company: {
      id: 12345,
      remove: true

Secure Mode

If you want to enable Intercom secure mode for analytics.js, you can pass in the user_hash variable inside the context object.

The user_hash should be a SHA256 hash of your Intercom API secret and the userId. The hash is not based on the email, it’s based on the userId. Here’s an example rendering an identify call with secure mode:

analytics.identify('<%= %>', {
    email: '<%= %>',
    createdAt: '<%= current_user.created %>'
}, {
     Intercom: {
        user_hash: '<%= OpenSSL::HMAC.hexdigest("sha256", "YOUR_INTERCOM_APP_SECRET", %>'

YOUR_INTERCOM_APP_SECRET is found in Intercom’s secure mode setup guide.

Secure Mode plus filtering via Integrations Object

If using Intercom secure mode AND selective integrations functionality, the context object will look like this:

     Intercom: {
         user_hash: '<%= OpenSSL::HMAC.hexdigest("sha256", "YOUR_INTERCOM_APP_SECRET", %>'
     integrations: {
         All: false,
         Intercom: true

Unsubscribe Users

To unsubscribe users from emails, you may set a flag from server side libraries, unsubscribedFromEmails, inside context object:

node.js example:

  userId: '4832094283057439285723523452345',
    Intercom: { unsubscribedFromEmails: true }
  traits: {
    firstName: 'John ',
    lastName: 'Jacob',
    email: ''

Note: This will only work from server side libraries. NOT analytics.js!

Last Seen

By default Intercom updates the Last Seen user trait whenever a user’s profile is updated by identify calls. If you want to update a user without updating their Last Seen time, pass active with a value of false into the context (see below). Note that this only works server-side; Last Seen will always be updated client-side. This setting can be passed to the context for identify calls only. Please note that id or name are necessary to update company.

Here’s a full python example:

analytics.identify(user_id='some_user_id', traits={
    "email": "",
    "firstName": "Ben",
    "lastName": "McRedmond"
    "createdAt": 1363902294011,
    "plan": "Premium"
}, context={
    "ip": "",
    "active": False,
    "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.47 Safari/537.36"

Intercom Tags

Our API doesn’t support Intercom tags. Traits can be used instead of tags to create segments of users, and the advantage is you can use those traits in other integrations like Segment.

Conditionally show the Intercom chat widget

You can take advantage of Intercom’s hide_default_launcher option to selectively show the chat widget. According to Intercom’s docs, you want to first hide the Messenger for all users inside their UI via Messenger settings. Then think about how you want to programmatically decide which users you’d like to show the widget to. Then you can pass an Intercom specific integration setting like this:

// with analytics.js
analytics.identify('teemo', { someTrait: 'x'}, {
  Intercom: { hideDefaultLauncher: true }

Note: You can pass in the Intercom specific option via all supported calls for this integration (page, identify, and group)!


I’m seeing a 403 Forbidden error

You probably have Intercom’s secure mode setting turned on but are not passing the user_hash correctly or at all.

You may also have to whitelist your domain in Intercom’s dashboard. Otherwise, events on non-whitelisted pages may be rejected with a 403 error.

My Intercom Widget doesn’t show up

Make sure you are sending a page and identify call when the page is loaded. This allows Intercom to register the page and the user, which would enable the widget to appear.

If you are sending those two calls, then check that the CSS selector for the widget is correct. The default is #IntercomDefaultWidget, but if you customize your widget, then be sure to update this field accordingly.

Supported Sources and Connection Modes

📱 Device-based
☁️ Cloud-based

To learn more about about Connection Modes and what dictates which we support, see here.


Segment lets you change these integration settings via your Segment dashboard without having to touch any code.

Custom Inbox Button Selector

By default, Intercom will inject their own inbox button onto the page, but you can choose to use your own custom button instead by providing a CSS selector like: #my-button. Note: you must have enabled the Show the Intercom Inbox setting for this to work. The default value is #IntercomDefaultWidget

Enter your API Key

Note: this is required to send data to Intercom from your servers. You can find your API key after activating your account under the Configure > API Keys at It should be 40 characters long, and look something like this: 4ad6ce80fc1d441324cfb11cdf8d3ade8fc7e8fd.

App ID (required for analytics.js)

Note: this is required to send data to Intercom from your browser. You can find your API key after activating your account under the Gear Menu > Configure > API Keys at It should be 8 or 40 characters long, and look something like this: 9iefb489 or 5113430c43a1b34770769dedb3eb3435be1dd1e9.

Specific Nested Trait and Property Handling

Intercom does not accept nested custom traits or properties so by default we’ll flatten any custom nested properties. If you have specific properties that you’d like handled differently, enter the nested property name on the left, and how you’d like it to be transformed when it’s sent to Intercom on the right. You can either flatten, stringify, or drop specific nested custom properties. If you’d like your custom nested properties stringified or dropped by default, you can do so in the Default Nested Trait and Property Handling option.

Include Context with Identify Calls

Pass context data with Identify calls as Custom Attributes. Includes device.type, device.manufacturer, device.model,, os.version,, app.version

Default Nested Trait and Property Handling

Intercom does not accept nested custom traits or properties so by default we’ll flatten any custom nested properties. You can choose the default method for handling custom nested properties by selecting the default here. If there are specific properties you’d like handled differently than the default, you can do so in the Specific Nested Trait and Property Handling option.

To use Intercom’s Rich Link object, list the name of the exact Segment property name and make sure the value of those properties only include url and value keys.

If you have any questions or see anywhere we can improve our documentation, please let us know or kick off a conversation in the Segment Community!

Check out the code!