# Intercom Destination Config Reference


> Complete Rudder CLI reference for the Intercom destination config keys, credential requirements by connection mode, cloud and device mode settings, and secrets.



[Intercom](https://www.rudderstack.com/docs/destinations/streaming-destinations/intercom/) is a customer messaging destination. RudderStack sends `identify`, `track`, and `group` events to Intercom's REST API from its servers, or loads Intercom's own SDKs in device mode — the Messenger on web, and the mobile SDKs on Android and iOS.

In an Intercom destination spec:

- `type: intercom`
- `definition_version: 1`

## Sample configuration

```yaml
version: rudder/v1
kind: destination
metadata:
  name: intercom-prod
spec:
  id: intercom-prod
  display_name: Intercom Production
  type: intercom
  definition_version: 1
  enabled: true
  config:
    app_id: "{{ .INTERCOM_APP_ID }}"
    api_key: "{{ .INTERCOM_ACCESS_TOKEN }}"
    api_version: v2
    api_server: standard
    send_anonymous_id: true

    mobile_api_key_android: "{{ .INTERCOM_ANDROID_API_KEY }}"
    mobile_api_key_ios: "{{ .INTERCOM_IOS_API_KEY }}"

    event_filtering:
      blacklist:
        - Credit Card Added

    connection_mode:
      web: device
      android: device
      ios: device
      cloud: cloud
    consent_management:
      web:
        - provider: oneTrust
          consents:
            - analytics
```

The above example loads Intercom's SDKs on web, Android, and iOS in `device` mode, which use `app_id` and the mobile API keys, and sends server-side events in `cloud` mode with `api_key` — see [Key dependencies](#key-dependencies).

## Config keys

`config` accepts only the keys listed below. The [shared config key rules](https://www.rudderstack.com/docs/rudder-cli/destination-types/#config-key-rules) cover unknown keys, defaults, and immutability.

**Info**

Most Intercom keys affect only one connection mode, or one platform&#39;s SDK, and each key says which. Rudder CLI accepts every key whatever the mode — a key for another mode is stored and ignored.

In `cloud` mode Intercom accepts `identify`, `track`, and `group` events. In `device` mode, web sources send `identify`, `track`, and `page`, and Android and iOS sources send `identify` and `track`.

### Key dependencies

Device mode loads Intercom with `app_id`, and cloud mode calls Intercom's API with `api_key`. Rudder CLI checks for each key twice — once on the destination, and once on each connection:

| Key | Destination check: required when | Connection check: required when |
| :-----| :-----| :-----|
| `app_id` | `connection_mode` is set, and every entry in it maps `web`, `android`, or `ios` to `device` | A `web`, `android`, or `ios` source connects in `device` mode |
| `api_key` | `connection_mode` is set, and every entry in it maps `web`, `android`, `ios`, `unity`, `react_native`, `flutter`, or `cordova` to `cloud` | A source connects in `cloud` mode, except a `cloud`, `android_kotlin`, `ios_swift`, or `warehouse` source |

A `connection_mode` that mixes modes, or that names `cloud`, `android_kotlin`, `ios_swift`, or `warehouse`, requires neither key at the destination check, and neither does a spec without `connection_mode`. A spec that misses a key the destination check requires fails validation. For the connection check, see [Connect a source](#connect-a-source).

**Warning**

Set `app_id` if any source connects in `device` mode, and `api_key` if any source connects in `cloud` mode. Without `api_key`, RudderStack fails every cloud-mode event, whatever the source type — including the four source types Rudder CLI doesn&#39;t check.

Android and iOS device mode also need the platform&#39;s mobile API key, which Rudder CLI never requires — see [Mobile device mode](#mobile-device-mode).

### Connection

<div class="rs-ckeys">
<div class="rs-ckey" id="app_id">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">app_id</p>RequiredSecret</div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  ID of your Intercom workspace, which Intercom&rsquo;s web Messenger and mobile SDKs load with. The dashboard calls it <strong>App Id</strong>.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Required when a <code>web</code>, <code>android</code>, or <code>ios</code> source connects in <code>device</code> mode — see <a href="#key-dependencies" >Key dependencies</a>. Leave it unset otherwise.</li>
<li>1 to 100 characters, and must not contain line breaks.</li>
<li>A <code>{{ path || fallback }}</code> template is accepted in place of a literal.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  <p>Supply it as a <code>{{ .VAR }}</code> reference rather than a literal — see <a href="#secrets" >Secrets</a>.</p>
<p>See <a href="https://www.rudderstack.com/docs/destinations/streaming-destinations/intercom/#adding-device-mode-integration" >Adding device mode integration</a>.</p>

</div>

</div>

<div class="rs-ckey" id="api_key">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">api_key</p>RequiredSecret</div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Intercom access token RudderStack calls Intercom&rsquo;s REST API with. The dashboard calls it <strong>Access Token</strong>.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Required when a source connects in <code>cloud</code> mode — see <a href="#key-dependencies" >Key dependencies</a>. Leave it unset otherwise.</li>
<li>1 to 100 characters, and must not contain line breaks.</li>
<li>A <code>{{ path || fallback }}</code> template is accepted in place of a literal.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  <p>Supply it as a <code>{{ .VAR }}</code> reference rather than a literal — see <a href="#secrets" >Secrets</a>.</p>
<p>See <a href="https://www.rudderstack.com/docs/destinations/streaming-destinations/intercom/#connection-settings" >Connection settings</a> for where to find the access token.</p>

</div>

</div>

</div>

### Cloud mode

These keys configure how RudderStack calls Intercom's API, so they apply only to events sent in `cloud` mode. The dashboard shows them only then.

<div class="rs-ckeys">
<div class="rs-ckey" id="api_version">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">api_version</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p><p class="rs-ckey__field">
    Default value:
    <code>v2</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Intercom REST API version RudderStack sends to. The dashboard calls it <strong>Intercom REST API Version</strong>.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li><code>v2</code> — the latest API version, 2.10.</li>
<li><code>v1</code> — API version 1.4, kept for backward compatibility.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  See <a href="https://www.rudderstack.com/docs/destinations/streaming-destinations/intercom/migration-guide/" >Intercom API v2.10 Migration Guide</a>.
</div>

</div>

<div class="rs-ckey" id="api_server">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">api_server</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p><p class="rs-ckey__field">
    Default value:
    <code>standard</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Region of your Intercom workspace. The dashboard calls it <strong>API Server</strong>.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>One of <code>standard</code> (US), <code>eu</code>, or <code>au</code>.</li>
<li>Applies when <code>api_version</code> is <code>v2</code>. With <code>v1</code>, RudderStack always calls the US endpoint.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  <div class="rs-code">
  <div class="rs-code__head">yaml<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">api_version: v2
api_server: eu</code></pre></div>
</div>
</div>

</div>

<div class="rs-ckey" id="send_anonymous_id">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">send_anonymous_id</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>boolean</code>
  </p><p class="rs-ckey__field">
    Default value:
    <code>false</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Send the event&rsquo;s <code>anonymousId</code> as the Intercom user ID when <code>userId</code> is absent. The dashboard calls it <strong>Send AnonymousId as Secondary UserId</strong>.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Without it, an <code>identify</code> or <code>track</code> event carrying neither a <code>userId</code> nor an email fails, because Intercom needs one of them.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  See <a href="https://www.rudderstack.com/docs/destinations/streaming-destinations/intercom/#configuration-settings" >Configuration settings</a>.
</div>

</div>

<div class="rs-ckey" id="update_last_request_at">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">update_last_request_at</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>boolean</code>
  </p><p class="rs-ckey__field">
    Default value:
    <code>true</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Set the user&rsquo;s last seen time in Intercom to the time of each <code>identify</code> call. The dashboard calls it <strong>Enable this to update the last seen to the current time</strong>.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Applies when <code>api_version</code> is <code>v1</code>. It has no effect with <code>v2</code>.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  <div class="rs-code">
  <div class="rs-code__head">yaml<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">api_version: v1
update_last_request_at: false</code></pre></div>
</div><p>See <a href="https://www.rudderstack.com/docs/destinations/streaming-destinations/intercom/migration-guide/#step-2-review-connection-settings" >Review connection settings</a> in the migration guide.</p>
</div>

</div>

</div>

### Mobile device mode

These keys configure Intercom's mobile SDKs. Each is a plain string, not keyed by source type, though it applies to one platform only.

**Warning:** Rudder CLI doesn&#39;t require these keys, even when `android` or `ios` connects in `device` mode. Without the platform&#39;s key, the SDK doesn&#39;t initialize Intercom, so no device-mode events from that platform reach it.

<div class="rs-ckeys">
<div class="rs-ckey" id="mobile_api_key_android">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">mobile_api_key_android</p>Secret</div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Intercom API key for Android, from the Android installation settings in Intercom. The Android SDK initializes Intercom with it and <code>app_id</code>. The dashboard calls it <strong>Android API Key</strong>.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Applies to <code>android</code> sources in <code>device</code> mode only.</li>
<li>At most 100 characters, and must not contain line breaks.</li>
<li>A <code>{{ path || fallback }}</code> template is accepted in place of a literal.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  <p>Supply it as a <code>{{ .VAR }}</code> reference rather than a literal — see <a href="#secrets" >Secrets</a>.</p>
<p>See <a href="https://www.rudderstack.com/docs/destinations/streaming-destinations/intercom/#configuration-settings" >Configuration settings</a> for where to find the key.</p>

</div>

</div>

<div class="rs-ckey" id="mobile_api_key_ios">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">mobile_api_key_ios</p>Secret</div>
  <p class="rs-ckey__field">
    Type:
    <code>string</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Intercom API key for iOS, used on the same terms as <code>mobile_api_key_android</code>. The dashboard calls it <strong>iOS API Key</strong>.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Applies to <code>ios</code> sources in <code>device</code> mode only.</li>
<li>At most 100 characters, and must not contain line breaks.</li>
<li>A <code>{{ path || fallback }}</code> template is accepted in place of a literal.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  Supply it as a <code>{{ .VAR }}</code> reference rather than a literal — see <a href="#secrets" >Secrets</a>.
</div>

</div>

</div>

### Event filtering

**Warning**

[Client-side event filtering](https://www.rudderstack.com/docs/sources/event-streams/sdks/event-filtering/) applies only to sources connected in `device` mode — `web`, `android`, or `ios`. The dashboard shows these controls only then, and the SDK is what applies the filter.

Rudder CLI accepts the block in any mode, but events sent in `cloud` mode reach Intercom unfiltered.

<div class="rs-ckeys">
<div class="rs-ckey" id="event_filtering">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">event_filtering</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>object</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Restricts which <code>track</code> events the SDK passes to Intercom, by event name.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>Applies to sources connected in <code>device</code> mode.</li>
<li><code>whitelist</code> — array of event names to allow; every other <code>track</code> event is dropped.</li>
<li><code>blacklist</code> — array of event names to drop; every other <code>track</code> event is allowed.</li>
<li>The two are mutually exclusive, and Rudder CLI enforces it — setting both fails validation.</li>
<li>Each name is at most 100 characters, or a <code>{{ path || fallback }}</code> template.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  <div class="rs-code">
  <div class="rs-code__head">yaml<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">connection_mode:
  web: device
event_filtering:
  blacklist:
    - Credit Card Added</code></pre></div>
</div>
</div>

</div>

</div>

### Per-source keys

Both keys are objects keyed by the local source type — the tokens listed under [Source types](#source-types). A key naming a source type this destination doesn't support fails validation.

<div class="rs-ckeys">
<div class="rs-ckey" id="connection_mode">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">connection_mode</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>object</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Maps each source type you connect to the mode its events reach Intercom in, using the modes in <a href="#source-types" >Source types</a>.
</p>

<div class="rs-ckey__notes">
  <p class="rs-ckey__field">Notes:</p>
  <ul>
<li>An entry is required for each source type you connect — see <a href="#connect-a-source" >Connect a source</a>.</li>
<li>A mode the source type doesn&rsquo;t support on this destination fails validation — for example <code>device</code> for <code>android_kotlin</code>.</li>
<li>The entries also decide which credentials the destination needs — see <a href="#key-dependencies" >Key dependencies</a>.</li>
</ul>

</div>

<div class="rs-ckey__extra">
  <div class="rs-code">
  <div class="rs-code__head">yaml<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">connection_mode:
  web: device
  ios: device
  cloud: cloud</code></pre></div>
</div>
</div>

</div>

<div class="rs-ckey" id="consent_management">
  <div class="rs-ckey__title">
    <p class="rs-ckey__name">consent_management</p></div>
  <p class="rs-ckey__field">
    Type:
    <code>object</code>
  </p>
<p class="rs-ckey__field">
  Description:
  Consent provider configuration per source type. The entry shape, accepted providers, and the rules on <code>resolution_strategy</code> and <code>consents</code> are shared across all destination types — see <a href="https://www.rudderstack.com/docs/rudder-cli/destination-types/#consent-management" >Consent management</a>.
</p>

</div>

</div>

## Source types

Intercom accepts events from these source types in the mentioned connection modes:

| Source type | Connection mode |
| :-----| :-----|
| `android` | `cloud`, `device` |
| `android_kotlin` | `cloud` |
| `ios` | `cloud`, `device` |
| `ios_swift` | `cloud` |
| `web` | `cloud`, `device` |
| `unity` | `cloud` |
| `react_native` | `cloud` |
| `flutter` | `cloud` |
| `cordova` | `cloud` |
| `cloud` | `cloud` |
| `warehouse` | `cloud` |

`web`, `android`, and `ios` offer `device` mode, which loads Intercom's own SDK in the browser or app. The Kotlin and Swift SDKs — `android_kotlin` and `ios_swift` — are `cloud` only. See [Adding device mode integration](https://www.rudderstack.com/docs/destinations/streaming-destinations/intercom/#adding-device-mode-integration) and [RudderStack Connection Modes](https://www.rudderstack.com/docs/destinations/rudderstack-connection-modes/).

`warehouse` is the token a [Reverse ETL source](https://www.rudderstack.com/docs/sources/reverse-etl/) resolves to. Rudder CLI manages the destination’s `warehouse` entry — if the destination is connected to a Reverse ETL source, set `connection_mode.warehouse: cloud` in its spec, or `apply` removes it.

Rudder CLI can also declare the Reverse ETL connection itself, for the types listed under [Supported destinations](https://www.rudderstack.com/docs/rudder-cli/yaml-retl-connections/#supported-destinations) — see [Manage Reverse ETL Connections using Rudder CLI](https://www.rudderstack.com/docs/rudder-cli/retl-connections/).

**Info:** The dashboard additionally offers Intercom to AMP and Shopify sources. Rudder CLI doesn&#39;t manage those connections, so `amp` and `shopify` are invalid here.

## Connect a source

An event stream connection to this destination is checked against three rules at `validate` time.

**The source's type must be supported.** A source's type resolves to one of the tokens above before the check — a JavaScript source resolves to `web`, and webhook and server-side SDK sources resolve to `cloud`. Every type an event stream source can resolve to is supported here, so this check always passes.

**The destination config must carry a `connection_mode` entry for that source type.** This lives on the destination spec, not on the [connection spec](https://www.rudderstack.com/docs/rudder-cli/yaml-connections/). Without it:

```text
destination 'intercom-prod' config has no 'connection_mode' entry for source type 'web'
```

**The destination config must carry the credential for the connection's mode.** A `web`, `android`, or `ios` source connecting in `device` mode needs `app_id`. Without it:

```text
destination 'intercom-prod' config is missing fields required to connect a 'web' source: app_id
```

A source connecting in `cloud` mode needs `api_key`. Without it:

```text
destination 'intercom-prod' config is missing fields required to connect a 'web' source: api_key
```

`cloud`, `android_kotlin`, and `ios_swift` sources connect without either check. Set `api_key` for them anyway — see [Key dependencies](#key-dependencies).

## Secrets

`api_key`, `app_id`, `mobile_api_key_android`, and `mobile_api_key_ios` are the secret keys. Write each one you use as a `{{ .VAR }}` reference and supply the value at apply time:

```yaml
config:
  app_id: "{{ .INTERCOM_APP_ID }}"
  api_key: "{{ .INTERCOM_ACCESS_TOKEN }}"
  mobile_api_key_android: "{{ .INTERCOM_ANDROID_API_KEY }}"
  mobile_api_key_ios: "{{ .INTERCOM_IOS_API_KEY }}"
```

```bash
export RUDDER_INTERCOM_APP_ID="..."
export RUDDER_INTERCOM_ACCESS_TOKEN="..."
export RUDDER_INTERCOM_ANDROID_API_KEY="..."
export RUDDER_INTERCOM_IOS_API_KEY="..."
rudder-cli apply

# or
rudder-cli apply --var-file secrets.vars.yaml
```

Note that:

- `rudder-cli import` writes only the secrets the API returns, as `{{ .VAR }}` references, and leaves the others out. Add any secret key it leaves out, then supply the variables before you apply — see [Secrets](https://www.rudderstack.com/docs/rudder-cli/destination-types/#secrets).
- In `device` mode, `app_id` and the mobile API keys are embedded in the page or app, so masking them protects your YAML, not the values themselves.

See [How to Use Variable Substitution in Rudder CLI](https://www.rudderstack.com/docs/rudder-cli/variable-substitution/).

## Changes by release

<p>No changes since this type became available.</p>

For changes across every destination type, see [Destination Type Changes by Release](https://www.rudderstack.com/docs/rudder-cli/destination-types/changes/).

## See more

- [Intercom Destination](https://www.rudderstack.com/docs/destinations/streaming-destinations/intercom/) for credentials, device mode setup, and how RudderStack maps each event
- [Intercom API v2.10 Migration Guide](https://www.rudderstack.com/docs/destinations/streaming-destinations/intercom/migration-guide/) for the differences between `v1` and `v2`
- [Destination Type Reference for Rudder CLI](https://www.rudderstack.com/docs/rudder-cli/destination-types/) for the rules shared across destination types
- [Destination YAML Reference](https://www.rudderstack.com/docs/rudder-cli/yaml-destinations/) for the spec envelope

