Welcome to our API reference!

You can view code examples in the area to the right, and you can switch the programming language of the examples with the tabs in the top right. We provide examples in Curl, Ruby, PHP, Java - and for Events, JavaScript.

If you're looking for quickstart guides and tutorials, head over to the Guides and tutorials section.

For more information about Intercom products, you can visit our product documentation.

Follow our blog and @intercomdevs on Twitter for the latest updates and news on the platform.

If you're building a publicly-available integration, take a look at our integration guidelines and the Developer Program before you get started. We're excited to see what you build! See what others have built here.

Suggest Edits

SDKs & Client Libraries

 

We've made a number of open source libraries available for the API

Looking to install Intercom on your web product or site using our client-side Javascript API? You can find full instructions in our docs here.

Suggest Edits

API Summary

 

The API is organized around the following resources -

API Area
Resource Area
Description

Users

Create and update Users. Use filters to get lists of Users, or access their profiles individually.

Companies

Create and update Companies. List companies or access them individually.

Leads

Create and update Leads. Get lists of Leads, or access their profiles individually.

Admins

View your App's Admins.

Tags

Organise Users and your App Admins with tags.

Segments

View your App's Segments.

Notes

Create and view notes about Users.

Events

Use Events to submit User activity to Intercom

Counts

Counts of Users and Companies by segment and tag. View open and closed counts for Admins.

Conversations

List conversations you have with users on your system. Allow Users and Admins to send messages and reply to conversations (only available on some plans).

JSON is returned in all responses.

The API also uses common approaches for the following:

Function
Description

API data is JSON encoded with UTF-8. API JSON is either a single object or a list of objects.

Access control using API Access Tokens.

4xx and 5xx responses returning JSON with error codes

Controls how many requests can be made in a time window

Methods are used in accordance with HTTP (GET POST and DELETE are the primary methods used) and resources are identified using URIs. All API requests are sent over HTTPS.

Suggest Edits

Access Tokens

 

Note: Access Tokens have replaced API Keys

If you're currently using an API Key to access the Intercom API for your own data, you should switch to using an Access Token asap - API Keys will be fully deprecated mid 2017.

Please note that Access Tokens were formerly called 'Personal Access Tokens'

You'll need an Access Token if you want to use the API to access your own Intercom data – for example, if you use the API with your own scripts to get data from your Intercom account.

If you intend to make an integration available publicly, and therefore need to access other people's Intercom data, you will need to set up OAuth instead.

If you're unsure, use this guide to work out whether you need an Access Token or OAuth.

Setting up Access Tokens

To get more information on how to create your access token please checkout our setup guide

Access Tokens should never be shared outside of your company

Access Tokens allow access to your private customer data in Intercom. They should not be shared outside of your company. Integrations requiring access to your Intercom account should be using OAuth – if an integration requests your Access Token, please let us know and don't share your Token with them.

Suggest Edits

Using Access Tokens

 

Access Tokens were previously called 'Personal Access Tokens'

They work in exactly the same way, just the name has changed!

Using Access Tokens

To use your Access Token simply provide it as part of the authorization header when you make a request. Access Tokens use the bearer authorization header when you make a request. This just means you need to specify the bearer type in the header.

For more info on the bearer token framework please see the official spec

Alternatively, you can always use the help function in some of our SDKs to authorize via Access Tokens, which means you don't need to specify the header explicitly (as it is all done for you under the hood).

We have access token helper function for most of our SDKs. However, if you cannot find any you can always use the previous API Key method for Access Tokens by simply leaving the password field empty.

$ curl \
-s https://api.intercom.io/users/5321a20f72cdbb4192000013 \
-H 'Authorization:Bearer <access_token>' \
-H 'Accept:application/json'

Example access token requests via SDKs

intercom = Intercom::Client.new(token: '<access_token>');
{"token": '<access_token>'}
var client = new Intercom.Client({ token: '<access_token>' });

Example access token in SDKs using API Key method

$client = new IntercomClient('<access_token>', '');
intercom = Intercom::Client.new(app_id: '<access_token>', api_key: '');

You need to set up OAuth if you're building an integration that you intend to make publicly available (and therefore need access to other people's Intercom data). If you're just accessing your own data, you can use Personal Access Tokens instead.

Note: OAuth has replaced API Keys for public integrations

As of April 2017, all public integrations must use OAuth rather than API Keys.

For more information on the difference between OAuth and Access Tokens, please see our OAuth guide.

Live OAuth Example Flow

We have a live OAuth example that may help explain the flow. You just need to have an Intercom account and you can check it out here

Applying for OAuth

We have implemented a version of the "Protocol" flow from the OAuth 2.0 specification. If you're thinking of building a connected app using OAuth, please look through the application process here to see how you can get developing immediately.

Automatic OAuth approval

When you apply via your TEST Intercom app you will be automatically approved for OAuth so can get started working on your integration immediately. When you are ready you can then follow the steps here to apply for your main Intercom production app.

Suggest Edits

Using OAuth

 

Initiating the OAuth flow

Once you have a client_id and a client_secret, you are ready to allow your customers to initiate the OAuth flow by sending them to https://app.intercom.io/oauth with the following parameters:

Parameter name
Description
Required?

client_id

From your credentials

yes

state

A value you can specify which is echoed back to you. We recommend using this to protect against CSRF attacks.

no (but recommended)

redirect_uri

One of your predefined callback URLs. If not specified a default is chosen.

no

For more detail on how to obtain the OAuth code you can see our guide here

Handling the redirect

Once the customer has confirmed, we will redirect back to your predefined redirect_uri with a code and state parameter. You can exchange these parameters for a token by POSTing to https://api.intercom.io/auth/eagle/token with the following parameters. Note that the code will expire after about 5 minutes.

Parameter name
Description
Required?

code

This is automatically passed by the redirect

yes

client_id

From your credentials

yes

client_secret

From your credentials

yes

If you still have question on how to generate a token after obtaining a code then please see this section of our guide for working with tokens

OAuth Token Usage

Once you have an OAuth token you can use it in the same way as a personal access token described above. i.e. you can use it with the bearer authorization header. Or you can use the SDK specific functions created for OAuth and personal access tokens.

The Users resource is the primary way of interacting with Intercom. You can create, update and delete your users, and add custom attributes describing them. Users can be viewed individually or as a list, and can be queried using tags or segments.

Suggest Edits

User Model

 

User Object

A user object contains the following fields -

Attribute
Type
Description

type

string

Value is 'user'

id

string

The Intercom defined id representing the user

created_at

timestamp

The time the user was added to Intercom

signed_up_at

timestamp

The time the user signed up

updated_at

timestamp

The last time the user was updated

user_id

string

The user id you have defined for the user. (Max limit of 255 UTF-8 characters, and should not have trailing or leading spaces)

email

string

The email you have defined for the user. (Max limit of 255 UTF-8 characters, and should not have trailing or leading spaces)

phone

string

The phone number of the user

custom_attributes

object

The custom attributes you have set on the user (case sensitive).

last_request_at

timestamp

The time the user last recorded making a request

session_count

integer

How many sessions the user has recorded

avatar

object

An avatar object for the user.

unsubscribed_from_emails

boolean

Whether the user is unsubscribed from emails

location_data

object

A Location Object relating to the user

user_agent_data

string

Data about the last user agent the user was seen using

last_seen_ip

string

An ip address (e.g. "1.2.3.4") representing the last ip address the user visited your application from. (Used for updating location_data)

pseudonym

string

The pseudonym used if this user was previously a Lead (http://docs.intercom.io/Intercom-for-customer-communication/the-intercom-messenger)

anonymous

boolean

Whether or not this is a Lead. Always false

companies

list

A list of companies for the user

social_profiles

list

A list of social profiles associated with the user

segments

list

A list of segments associated with the user

tags

list

A list of tags associated with the user

name

string

The full name of the user

Note that in some parts of the API, the user id field may be referred to using intercom_user_id.

Social Profile Object

Attribute
Type
Description

type

string

Value is 'social_profile'

name

string

The name of the service (e.g., twitter, facebook)

username

string

User name or handle on the service

url

string

The user homepage on the service

id

string

Optional. User ID on the service

Social data is read only and can not be updated via the API.

Avatar Object

Attribute
Type
Description

type

string

Value is 'avatar'

image_url

string

An avatar image URL. note: the image url needs to be https.

Location Object

Attribute
Type
Description

type

string

Value is 'location_data'

city_name

string

Optional. A city name

continent_code

string

Optional. A continent code

country_code

string

Optional. An ISO 3166 country code

country_name

string

Optional. The country name

latitude

number

Optional. The latitude

longitude

number

Optional. The longitude

postal_code

string

Optional. A postal code

region_name

string

Optional. A region name

timezone

string

Optional. An ISO 8601 timezone

Location data is read only and can not be updated via the API.

User List

Attribute
Type
Description

type

string

Value is 'user.list'

total_count

integer

The number of users for this app

pages

object

A Pagination object

users

array

A list of users

The user list does not return Leads - this means all objects in the list will have an anonymous value of false. Any user in the list that was converted from a Lead will retain their pseudonym value.

Example User Object (i.e. example JSON response)

{
  "type": "user",
  "id": "530370b477ad7120001d",
  "user_id": "25",
  "email": "wash@serenity.io",
  "phone": "+1123456789",
  "name": "Hoban Washburne",
  "updated_at": 1392734388,
  "last_seen_ip" : "1.2.3.4",
  "unsubscribed_from_emails": false,
  "last_request_at": 1397574667,
  "signed_up_at": 1392731331,
  "created_at": 1392734388,
  "session_count": 179,
  "user_agent_data": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9",
  "pseudonym": null,
  "anonymous": false,
  "custom_attributes": {
    "paid_subscriber" : true,
    "monthly_spend": 155.5,
    "team_mates": 1
  },
  "avatar": {
    "type":"avatar",
    "image_url": "https://example.org/128Wash.jpg"
  },
  "location_data": {
      "type": "location_data",
      "city_name": "Dublin",
      "continent_code": "EU",
      "country_code": "IRL",
      "country_name": "Ireland",
      "latitude": 53.159233,
      "longitude": -6.723,
      "postal_code": null,
      "region_name": "Dublin",
      "timezone": "Europe/Dublin"
  },
  "social_profiles": {
    "type":"social_profile.list",
    "social_profiles": [
      {
        "name": "Twitter",
        "id": "1235d3213",
        "username": "th1sland",
        "url": "http://twitter.com/th1sland"
      }
    ]
  },
  "companies": {
    "type": "company.list",
    "companies": [
      {
        "id" : "530370b477ad7120001e"
      }
    ]
  },
  "segments": {
    "type": "segment.list",
    "segments": [
      {
        "id" : "5310d8e7598c9a0b24000002"
      }
    ]
  },
  "tags": {
    "type": "tag.list",
    "tags": [
      {
        "id": "202"
      }
    ]
  }
}

Example List of Users

{
  "type": "user.list",
  "total_count": 1, 
  "users": [
    # an array of user objects
  ],
  "pages": {}
}
Suggest Edits

Create or Update User

 

Users can be created or updated via a POST method to https://api.intercom.io/users, which accepts a JSON object describing the user.

Users not found via email or user_id will be created, and those that are found will be updated.

Note that the following lookup order applies when updating users - id then user_id then email, and results in the following logic -

  • id is matched - the user_id and email will be updated if they are sent.
  • user_id match - the email will be updated, the id is not updated.
  • email match where no user_id set on the matching user - the user_id will be set to the value sent in the request, the id is not updated.
  • email match where there is a user_id set on the matching user - a new unique record with new id will be created if a new value for user_id is sent in the request.

Note that email values are downcased after they have been submitted to our API.

Attributes

The table below shows the fields you can create or update for a user -

Parameter
Required
Description

user_id

Required if no email is supplied.

A unique string identifier for the user. It is required on creation if an email is not supplied.

email

Required if no user_id is supplied.

The user's email address. It is required on creation if a user_id is not supplied.

phone

no

The user's phone number.

id

no

The id may be used for user updates.

signed_up_at

no

The time the user signed up

name

no

The user's full name

last_seen_ip

no

An ip address (e.g. "1.2.3.4") representing the last ip address the user visited your application from. (Used for updating location_data)

custom_attributes

no

A hash of key/value pairs containing any other data about the user you want Intercom to store.*

last_seen_user_agent

no

The user agent the user last visited your application with.

companies

no

Identifies the companies this user belongs to.

last_request_at

no

A UNIX timestamp (in seconds) representing the date the user last visited your application.

unsubscribed_from_emails

no

A boolean value representing the users unsubscribed status. default value if not sent is false.

update_last_request_at

no

A boolean value, which if true, instructs Intercom to update the users' last_request_at value to the current API service time in UTC. default value if not sent is false.

new_session

no

A boolean value, which if true, instructs Intercom to register the request as a session.

In particular, please note that location data and social profiles are computed by the server and can not be updated via the API.

Custom Attributes

The custom_attributes object allows you to send any information you wish about a user with the following restrictions

Field names must not contain Periods ('.') or Dollar ('$') characters

  • Field names must be no longer than 190 characters.
  • Field values must be JSON Strings, Numbers or Booleans - Objects and Arrays will be rejected.
  • String field values must be no longer than 255 characters.
  • Maximum of 250 fields.

Custom attribute as date

You can send dates as custom attributes by sending a unix timestamp. If the name of your custom attribute ends with _at then we'll automatically treat it as a date, rather than a number. See here for more info

Returns

A created or updated user object.

New user objects will be provided with an id field - this value cannot be created or edited by clients. Social profiles, location data and avatars are processed asynchronously, and may require a subsequent call to fetch their details.

Create or Update Users

$ curl https://api.intercom.io/users \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d '
{
  "user_id": "25",
  "email": "wash@serenity.io",
  "name": "Hoban Washburne",
  "phone": "555671243",
  "signed_up_at": 1392731331,
  "last_seen_ip" : "1.2.3.4",
  "last_seen_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9",
  "custom_attributes": {
    "paid_subscriber" : true,
    "monthly_spend": 155.5,
    "team_mates": 9,
    "last_order_at":1475569818
  },
  "companies": [
    {
      "company_id" : "366",
      "name" : "Serenity",
      "monthly_spend" : 500
    }
  ]
}'
HTTP/1.1 200 OK 
#Example Response
{
    "type": "user",
    "id": "5714dd359a3fd47136000001",
    "user_id": "25",
    "anonymous": false,
    "email": "wash@serenity.io",
    "phone": "555671243",
    "name": "Hoban Washburne",
    "pseudonym": null,
    "avatar": {
        "type": "avatar",
        "image_url": "https://secure.gravatar.com/avatar/0c3c17fd49f45c43f482730782b36d36?s=24&d=identicon"
    },
    "app_id": "ja43hiec",
    "companies": {
        "type": "company.list",
        "companies": [
            {
                "type": "company",
                "company_id": "366",
                "id": "574854e3ecd0c547ae0000e4",
                "name": "Serenity"
            }
        ]
    },
    "location_data": {
		...
    },
    "last_request_at": null,
    "last_seen_ip": "1.2.3.4",
    "created_at": 1460985141,
    "remote_created_at": 1392731331,
    "signed_up_at": 1392731331,
    "updated_at": 1480075457,
    "session_count": 0,
    "social_profiles": {
        "type": "social_profile.list",
        "social_profiles": [
            ...
        ]
    },
    "unsubscribed_from_emails": false,
    "user_agent_data": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9",
    "tags": {
        "type": "tag.list",
        "tags": []
    },
    "segments": {
        "type": "segment.list",
        "segments": []
    },
    "custom_attributes": {
        "paid_subscriber": true,
        "monthly_spend": 155.5,
        "team_mates": 9,
        "last_order_at": 1475569818
    }
}
intercom.users.create(:user_id => '25', :email => "wash@serenity.io")
<?php
$intercom->users->create([
    "user_id" => "25",
    "email" => "wash@serenity.io",
    "name" => "Hoban Washburne",
    "phone" => "555671243",
    "signed_up_at" => 1392731331,
    "last_seen_ip" => "1.2.3.4",
    "last_seen_user_agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9",
    "custom_attributes" => [
        "paid_subscriber"  => true,
        "monthly_spend" => 155.5,
        "team_mates" => 9,
        "last_order_at" =>1475569818,
    ],
    "companies" => [
        [
            "company_id"  => "366",
            "name"  => "Serenity",
            "monthly_spend"  => 500
        ],
    ],
]);
?>
import static io.intercom.api.CustomAttribute.*;

User user = new User()
.setEmail("wash@serenity.io")
.setUserId("25")
.addCustomAttribute(newStringAttribute("role", "sergeant"))
.addCustomAttribute(newBooleanAttribute("browncoat", true));

user = User.create(user);
Suggest Edits

View a User

 

Each user object has its own URL -

  • https://api.intercom.io/users/{id}

Where {id} is the value of the user's id field. This URL is the user's canonical address in the API.

Request Parameters

Parameter
Required
Description

user_id

no

The user id you have defined for the user

email

no

The email you have defined for the user

A user can also be fetched using a user_id or email parameter in the url, whose values are the company's user_id or email fields -

  • https://api.intercom.io/users?user_id={user_id}
  • https://api.intercom.io/users?email={email}

The email parameter value should be url encoded when sending.

Returns

A user object.

Example ID Request

$ curl \
-s https://api.intercom.io/users/5714dd359a3fd47136000001 \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
    "type": "user",
    "id": "5714dd359a3fd47136000001",
    "user_id": "25",
    "anonymous": false,
    "email": "wash@serenity.io",
    "phone": "555671243",
    "name": "Hoban Washburne",
    "pseudonym": null,
  ...
}
# NB: Full User objects are returned
intercom.users.find(:id => "5714dd359a3fd47136000001")
<?php

$user = $intercom->users->getUser("596f35f744c4c5f0cd30c8ef");
print_r($user->id);
?>

Example User ID Request

$ curl \
-s https://api.intercom.io/users?user_id=25 \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
intercom.users.find(:user_id => "128")
<?php

$user = $intercom->users->getUser("", ["user_id" => "111"]);
print_r($user->id);
?>
Map<String, String> params = Maps.newHashMap();
params.put("user_id", "1");
User user = User.find(params);

Example Email Request

$ curl \
-s https://api.intercom.io/users?email=wash%40serenity.io \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
intercom.users.find(:email => "bob@example.com")
<?php

$user = $intercom->users->getUser("", ["email" => "plato@phil.com"]);
print_r($user->id);
?>
Map<String, String> params = Maps.newHashMap();
params.put("email", "malcolm@serenity.io");
User user = User.find(params);
Suggest Edits

Updating the Last Seen Time

 

To update the last time the user was seen in your App, send the time in the last_request_at field in a user update request. You can also send update_last_request_at: true to tell the API to update the last request time to the time of your call (in UTC).

Example Update for Last Seen Time

$ curl https://api.intercom.io/users \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d '
{
  "user_id": "25",
  "last_request_at": 1480076371
}'
{
    "type": "user",
    "id": "5714dd359a3fd47136000001",
    "user_id": "25",
    "anonymous": false,
    "email": "wash@serenity.io",
    "phone": "555671243",
    "name": "Hoban Washburne",
    "pseudonym": null,
    "avatar": {
        "type": "avatar",
        "image_url": "https://secure.gravatar.com/avatar/0c3c17fd49f45c43f482730782b36d36?s=24&d=identicon"
    },
    "app_id": "ja43hiec",
    "companies": {
        "type": "company.list",
        "companies": [
            {
                "type": "company",
                "company_id": "366",
                "id": "574854e3ecd0c547ae0000e4",
                "name": "Serenity"
            }
        ]
    },
    "location_data": {
        ...
    },
    "last_request_at": 1480076371,
    "last_seen_ip": "1.2.3.4",
    "created_at": 1460985141,
    "remote_created_at": 1392731331,
    "signed_up_at": 1392731331,
    "updated_at": 1480076399,
    "session_count": 0,
    "social_profiles": {
        "type": "social_profile.list",
        "social_profiles": [
         ...
        ]
    },
    "unsubscribed_from_emails": false,
    "user_agent_data": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9",
    "tags": {
        "type": "tag.list",
        "tags": []
    },
    "segments": {
        "type": "segment.list",
        "segments": []
    },
    "custom_attributes": {
        "paid_subscriber": true,
        "monthly_spend": 155.5,
        "team_mates": 9,
        "last_order_at": 1475569818
    }
}
intercom.users.create(:user_id => '25', :last_request_at => Time.now)
<?php
$intercom->users->create([
    "user_id" => "550",
    "email" => "plato@phil.com",
    "last_request_at" => (time() - (2*24*60*60)) #2 days ago
]);
?>
user.setUpdateLastRequestAt(true);
User.update(user);
Suggest Edits

Incrementing User Sessions

 

To indicate the update is part of an active session pass new_session: true when you update the user. The API will then follow the rules for web sessions outlined in our session docs to decide whether the session count should be updated for the user.

Suggest Edits

Companies and Users

 

Companies field is an Array

Note that when associating a company with a user, the companies field used is an array, not an object (as is the case when the user is being fetched)

Create or Update Companies?

Users may be created or updated with a company object. If the company object does not already exist, it will be created for you. This saves having to create a company or check it exists before creating or updating a user.

To remove a company from a user add the field remove with a value of true to the embedded company object and submit the user as a update request. You must also submit the id of the company.

Note: the "id" to be used for the "companies" object is the company_id.

Associate a Company with a User

$ curl https://api.intercom.io/users \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d '
{
  "id": "531ee472cce572a6ec000005",
  "companies": [
    {
    "company_id" : "366",
    "name" : "Serenity"
    }
  ]
}'
<?php
$intercom->users->create([
    "user_id" => "111",
    "companies" => [
        [
            "company_id" => "10"
        ]
    ]
]);
?>
User user = User.find("541a144b201ebf2ec5000001");
user.addCompany(company);
User.update(user);

Remove a User from a Company

$ curl https://api.intercom.io/users \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d '
{
  "id": "531ee472cce572a6ec000005",
  "companies": [
    {
      "company_id" : "3",
     "remove" : true
    }
  ]
}'
 user.companies = [{ :company_id => "1234", :remove => true}]
<?php
$intercom->users->create([
    "email" => "plato@phil.com",
    "companies" => [
        [
            "company_id" => "9",
            "remove" => true
        ]
    ]
]);
?>
Suggest Edits

List Users

 

You can fetch a list of users. The user list is sorted by the created_at field and by default is ordered descending, most recently created first.

Request Parameters

You can optionally request the result page size and which page to fetch as follows -

Parameter
Required
Description

page

no

what page of results to fetch defaults to first page.

per_page

no

how many results per page defaults to 50, max is 60.

order

no

asc or desc. Return the users in ascending or descending order. defaults to desc.

sort

no

what field to sort the results by. Valid values: created_at,
last_request_at,
signed_up_at,
updated_at,

created_since

no

limit results to users that were created in that last number of days.

Returns

A pageable list of users. The user list contains a pages object that indicates if more users exist via the next field, whose value is a URL that can be used to fetch the next page. If the next field is not present, that indicates there are no further users in the list.

When using the Users endpoint and the pages object to iterate through the returned users, there is a limit of 10,000 Users that can be returned. If you need to list or iterate on more than 10,000 Users, please use the Scroll API.

List Users Example

$ curl https://api.intercom.io/users \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json'


HTTP/1.1 200 OK

{
  "type": "user.list",
  "total_count": 105,
  "users": [
    {
      "type": "user",
      "id": "530370b477ad7120001d",
       ...
     },
     ...
   ],
  "pages": {
    "next": "https://api.intercom.io/users?per_page=50&page=2",
    "page": 1,
    "per_page": 50,
    "total_pages": 3
  }
}

# NB: Full User objects are returned
intercom.users.all.each { ... }
<?php
$intercom->users->getUsers([]);
$users= $intercom->users->getUsers([]);

foreach ($users->users as $user) {
    print_r($user->id);
    echo "\n";
}?>
UserCollection users = User.list();

// get first page...
List<User> items = users.getPageItems();

// ...or iterate over all pages
while (users.hasNext()) {
    out.println(users.next().getId());
}
Suggest Edits

List by Tag, Segment, Company

 

You can fetch segmented users/leads by querying the users resource with a segment_id parameter, indicating the id of the segment to query with.

To fetch tagged users/leads, you can use a tag_id parameter to indicate the id of the tag. For information on tagging users see the section 'Tag or Untag Users'.

Note that you can not combine tag and segment parameters in the same request.

To list users belonging to a company, you can use the companies API. See the section "List Company Users"for details.

Request Parameters

Parameter
Required
Description

tag_id

no

The id of the tag to filter by.

segment_id

no

The id of the segment to filter by.

Returns

A pageable list of users and leads.

Like a plain company list, the result contains a pages object that indicates if more users exist via the next field.

Example Tag Request

$ curl https://api.intercom.io/users?tag_id=3142 \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
intercom.users.find_all({ :tag_id => '30126' })
<?php
$user = $intercom->users->getUsers(["tag_id" => '730128']);
print_r($user->users[0]->email);
echo "\n";
?>
Map<String, String> params = Maps.newHashMap();
params.put("tag_id", "30126");
UserCollection users = User.list(params);
while (users.hasNext()) {
    out.println(users.next().getId());
}

Example Segment Request

$ curl https://api.intercom.io/users?segment_id=5926 \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
  "type": "user.list",
  "total_count": 105,
  "users": [
    {
      "type": "user",
      "id": "530370b477ad7120001d",
       ...
     },
     ...
  ],
  "pages": {
    "next": "https://api.intercom.io/users?tag_id=3142&per_page=50&page=2",
    "page": 1,
    "per_page": 50,
    "total_pages": 3
  }
}

# NB: Full User objects are returned
intercom.users.find_all({ :segment_id => '30126' })
<?php
$user = $intercom->users->getUsers(["segment_id" => '58135df83917e42135b2ea29']);
print_r($user->users[0]->id);
echo "\n";
?>
Map<String, String> params = Maps.newHashMap();
params.put("segment_id", "30126");
UserCollection users = User.list(params);
while (users.hasNext()) {
    out.println(users.next().getId());
}
Suggest Edits

Delete a User

 

A user can be deleted by sending a DELETE request to its URL using the user's id field as part of the path -

  • https://api.intercom.io/users/{id}

Alternatively, a delete can be performed by sending a DELETE request using the email or user_id as query parameters -

  • https://api.intercom.io/users?email={email}
  • https://api.intercom.io/users?user_id={user_id}

Request Parameters

Parameter
Required
Description

email

no

The email you have defined for the user

user_id

no

The user id you have defined for the user

Please note that when a user is deleted, all of their conversations and message history will also be deleted.

Returns

A User object.

Example ID Delete Request

$ curl \
-s https://api.intercom.io/users/5321a20f72cdbb4192000013 \
-X DELETE \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 Ok

{
    "type": "user",
    "id": "5714dd359a3fd47136000001",
    "user_id": "25",
    "anonymous": false,
    "email": "wash@serenity.io",
    "phone": "555671243",
    "name": "Hoban Washburne",
    "pseudonym": null,
  ...
}
# NB: Full User objects are returned
user = intercom.users.find(:id => "56e1e5d4a40df1cc57000101")
intercom.users.delete(user)
<?php
$intercom->users->deleteUser("596d3bfdd45d2162b28560ea");
?>
User user = new User().setId("5310d8e8598c9a0b24000005");
User.delete(user.getId());

Example User ID Delete Request

$ curl \
-s https://api.intercom.io/users?user_id=25 \
-X DELETE \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 Ok

{
    "type": "user",
    "id": "5714dd359a3fd47136000001",
    "user_id": "25",
    "anonymous": false,
    "email": "wash@serenity.io",
    "phone": "555671243",
    "name": "Hoban Washburne",
    "pseudonym": null,
  ...
}
# NB: Full User objects are returned
user = intercom.users.find(:user_id => "1")
intercom.users.delete(user)
Map<String, String> params = Maps.newHashMap();
params.put("user_id", "1");
user = User.find(params);
User.delete(user.getId());
<?php
$intercom->users->deleteUser("", ["user_id" => "5087"]);
?>

Example User Email Delete Request

$ curl \
-s https://api.intercom.io/users?email=wash%40serenity.io \
-X DELETE \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'

HTTP/1.1 200 Ok

{
    "type": "user",
    "id": "5714dd359a3fd47136000001",
    "user_id": "25",
    "anonymous": false,
    "email": "wash@serenity.io",
    "phone": "555671243",
    "name": "Hoban Washburne",
    "pseudonym": null,
  ...
}
# NB: Full User objects are returned
user = intercom.users.find(:email => "foo@bar.com")
intercom.users.delete(user)
Map<String, String> params = Maps.newHashMap();
params.put("email", "malcolm@serenity.io");
user = User.find(params);
User.delete(user.getId());
<?php
$intercom->users->deleteUser("", ["email" => "test@example.com"]);
?>
Suggest Edits

Scroll over all users

 

The User listing functionality does not work well for huge datasets, and can result in errors and performance problems when paging deeply. The Scroll API provides an efficient mechanism for iterating over all users in a dataset.

  • Each app can only have 1 scroll open at a time. You'll get an error message if you try to have more than one open per app.
  • If the scroll isn't used for 1 minute, it expires and calls with that scroll param will fail
  • If the end of the scroll is reached, "users" will be empty and the scroll parameter will expire

Scroll Parameter

You can get the first page of users by simply sending a GET request to the scroll endpoint. For subsequent requests you will need to use the scroll parameter from the response.

# Send a GET request to get the first page of users
$ curl \
'https://api.intercom.io/users/scroll' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
# To get the next page use the scroll param returned in the response
$ curl \
'https://api.intercom.io/users/scroll?scroll_param=562bc29f-ea55-4823-aaaf-f3faadceaa59' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
  "type": "user.list",
  "users": [
    {
      "type": "user",
      "id": "530370b477ad7120001d",
       ...
     },
     ...
   ],
  "scroll_param": "25b649f7-4d33-4ef6-88f5-60e5b8244309"
}
# You can use the scroll method to list all your users
intercom.users.scroll.each { |user| puts user.name}
# Alternatively you can use the scroll.next method to get 100 users with each request
result = intercom.users.scroll.next
result.scroll_param
=> "0730e341-63ef-44da-ab9c-9113f886326d"
result = intercom.users.scroll.next("0730e341-63ef-44da-ab9c-9113f886326d");

Leads are useful for representing logged-out users of your application. The Leads resource provides methods to fetch, create, update and delete Leads within Intercom.

Leads were previously known as 'Contacts'. Our object names and types continue to be referred to as 'contacts/contact'. We will migrate to 'Leads/Lead' models at a future date.

Suggest Edits

Leads Object

 

A lead object contains the following fields -

Attribute
Type
Description

type

string

value is 'contact'

id

string

The Intercom defined id representing the Lead

created_at

timestamp

The time the Lead was added to Intercom

updated_at

timestamp

The last time the Lead was updated

user_id

string

Automatically generated identifier for the Lead

email

string

The email you have defined for the Lead

phone

string

The phone number you have defined for the lead

name

string

The name of the Lead

custom_attributes

object

The custom attributes you have set on the Lead

last_request_at

timestamp

The time the Lead last recorded making a request

avatar

object

An avatar object for the Lead

unsubscribed_from_emails

boolean

Whether the Lead is unsubscribed from emails

location_data

object

A Location Object relating to the Lead

user_agent_data

string

Data about the last user agent the Lead was seen using

last_seen_ip

no

An ip address (e.g. "1.2.3.4") representing the last ip address the Lead visited your application from. (Used for updating location_data)

companies

list

A list of companies for the Lead

social_profiles

list

A list of social profiles associated with the Lead

segments

list

A list of segments the Lead.

tags

list

A list of tags associated with the Lead.

Information on social profile, avatar and location objects can be found under the Users documentation.

Suggest Edits

Create Lead

 

Leads can be created via a POST method to https://api.intercom.io/contacts, which accepts a JSON object describing the lead.

No identifying information is required to create a Lead, Intercom assigns a user_id to each new Lead. Indeed, it is not possible to assign these through the API - to work with self-assigned user_ids, use the Users resource.

Contrary to Users, signed_up_at and sessions are not available for Leads. Otherwise, attributes to update on a Lead are the same as for a User.

Note that as with Users, user agent data is submitted as last_seen_user_agent.

Example Request

$ curl https://api.intercom.io/contacts \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d '
{
  "phone": "123987456",
  "email": "winstonsmith@truth.org",
  "name": "Winston Smith"
}'

HTTP/1.1 200 OK

# lead response

{
    "type": "contact",
    "id": "5811f6bbe6b4704ddfa84ac0",
    "user_id": "77177570-cf5d-4f1a-bc75-75202af47d4f",
    "anonymous": true,
    "email": "winstonsmith@truth.org",
    "phone": "00353875551234",
    "name": "Winston Smith",
    "pseudonym": "Lime Camel from Dublin",
    "avatar": {
        "type": "avatar",
        "image_url": null
    },
    "app_id": "ja43hiec",
    "companies": {
        "type": "company.list",
        "companies": []
    },
    "location_data": {
        "type": "location_data",
        "city_name": "Mukilteo",
        "continent_code": "NA",
        "country_name": "United States",
        "latitude": 47.913,
        "longitude": -122.3042,
        "postal_code": "98275",
        "region_name": "Washington",
        "timezone": "America/Los_Angeles",
        "country_code": "USA"
    },
    "last_request_at": 1477660267,
    "last_seen_ip": "1.2.3.4",
    "created_at": 1477572283,
    "remote_created_at": null,
    "signed_up_at": null,
    "updated_at": 1480067287,
    "session_count": 0,
    "social_profiles": {
        "type": "social_profile.list",
        "social_profiles": []
    },
    "unsubscribed_from_emails": false,
    "user_agent_data": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9",
    "tags": {
        "type": "tag.list",
        "tags": []
    },
    "segments": {
        "type": "segment.list",
        "segments": []
    },
    "custom_attributes": {
        "paid_subscriber": true,
        "monthly_spend": 155.5,
        "team_mates": 9
    }
}
intercom.contacts.create(:email => "winstonsmith@truth.org")
import static io.intercom.api.CustomAttribute.*;

Contact contact = new Contact()
    .setEmail("winstonsmith@truth.org");
contact = Contact.create(contact);
<?php
$intercom->leads->create(["email" => "socrates@phil.com"]);
?>
Suggest Edits

View a Lead

 

Leads can be looked up individually via their id, or with a user_id parameter.

user_id for leads

Remember that for leads the user_id will be automatically generated so it will look something like '8a88a590-e1c3-41e2-a502-e0649dbf721c'. (Note that this user_id is not retained when converting a lead to a user) For users the user_id is manually set so it will generally appear more like a regular number series e.g. '234'.

Example ID Request

$ curl \
https://api.intercom.io/contacts/5811f6bbe6b4704ddfa84ac0 \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'

or 

$ curl \
-s https://api.intercom.io/contacts?user_id=77177570-cf5d-4f1a-bc75-75202af47d4f \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
    "type": "contact",
    "id": "5811f6bbe6b4704ddfa84ac0",
    "user_id": "77177570-cf5d-4f1a-bc75-75202af47d4f",
    "anonymous": true,
    "email": "obrien@truth.org",
    "phone": "00353875551234",
    "name": "O&#39;Brien",
    "pseudonym": "Lime Camel from Dublin",
  ...
}
# NB: Full Contact objects are returned
contact = intercom.contacts.find(:id => "530370b477ad7120001d")
contact = intercom.contacts.find(:user_id => "8a88a590-e1c3-41e2-a502-e0649dbf721c")
Contact contact = Contact.findByID("530370b477ad7120001d");
contact = Contact.findByUserID("8a88a590-e1c3-41e2-a502-e0649dbf721c");
<?php
$lead = $intercom->leads->getLead("596f6b60d797879302bd7ac1");
print_r($lead->email);
?>

or
<?php
// Rememebr that user_ids for leads are 
// generated automatically so look different 
// from the user_ids you manually create for users
$lead = $intercom->leads->
    getLead("", ["user_id" => "ce12a681-e3d4-4a17-bbde-fe85e04ca3ef"]);
print_r($lead);
?>
Suggest Edits

Update Lead

 

Sending a POST request to /contacts and passing identifiers (user_id or id) in the body will result in an update of an existing Lead.

It is not possible to uniquely identify a Lead for an update with an email address.

Example Request

$ curl https://api.intercom.io/contacts \
-XPOST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d '
{
  "id": "5811f6bbe6b4704ddfa84ac0",
  "user_id": "77177570-cf5d-4f1a-bc75-75202af47d4f",
  "phone": "123987456",
  "email": "obrien@truth.org",
  "name": "OBrien",
  "last_seen_ip" : "1.2.3.4",
  "last_seen_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9",
  "custom_attributes": {
    "paid_subscriber" : true,
    "monthly_spend": 155.5,
    "team_mates": 9
  }
}'
contact.name = "Winston Smith"
intercom.contacts.save(contact)
contact.setName("Winston Smith");
Contact updated = Contact.update(contact);
<?php
$intercom->leads->create([
    "id" => "596f6b60d797879302bd7ac1",
    "phone" => "5552345657"
]);
?>
HTTP/1.1 200 OK
{
    "type": "contact",
    "id": "5811f6bbe6b4704ddfa84ac0",
    "user_id": "77177570-cf5d-4f1a-bc75-75202af47d4f",
    "anonymous": true,
    "email": "obrien@truth.org",
    "phone": "00353875551234",
    "name": "OBrien",
    "pseudonym": "Lime Camel from Dublin",
    "avatar": {
        "type": "avatar",
        "image_url": null
    },
    "app_id": "ja43hiec",
    "companies": {
        "type": "company.list",
        "companies": []
    },
    "location_data": {
        "type": "location_data",
        "city_name": "Mukilteo",
        "continent_code": "NA",
        "country_name": "United States",
        "latitude": 47.913,
        "longitude": -122.3042,
        "postal_code": "98275",
        "region_name": "Washington",
        "timezone": "America/Los_Angeles",
        "country_code": "USA"
    },
    "last_request_at": 1477660267,
    "last_seen_ip": "1.2.3.4",
    "created_at": 1477572283,
    "remote_created_at": null,
    "signed_up_at": null,
    "updated_at": 1480068674,
    "session_count": 0,
    "social_profiles": {
        "type": "social_profile.list",
        "social_profiles": []
    },
    "unsubscribed_from_emails": false,
    "user_agent_data": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9",
    "tags": {
        "type": "tag.list",
        "tags": []
    },
    "segments": {
        "type": "segment.list",
        "segments": []
    },
    "custom_attributes": {
        "paid_subscriber": true,
        "monthly_spend": 155.5,
        "team_mates": 9
    }
}
# contact response
Suggest Edits

List Leads

 

You can fetch a list of all leads. The lead list is sorted by the created_at field and by default is ordered descending, most recently created first. Apart from sorting, the same parameters for the User list apply here.

Example Request

$ curl https://api.intercom.io/contacts \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json'


HTTP/1.1 200 OK

{
  "type": "contact.list",
  "total_count": 105,
  "contacts": [
    {
      "type": "contact",
      "id": "530370b477ad7120001d",
       ...
     },
     ...
   ],
  "pages": {
    "next": "https://api.intercom.io/contacts?per_page=50&page=2",
    "page": 1,
    "per_page": 50,
    "total_pages": 3
  }
}

# NB: Full Contact objects are returned
intercom.contacts.all.each { ... }
<?php
$leads= $intercom->leads->getLeads([]);
foreach ($leads->contacts as $lead) {
    print_r($lead->id);
    echo "\n";
}
?>
ContactCollection contacts = Contact.list();

// get first page...
List<Contact> items = contacts.getPageItems();

// ...or iterate over all pages
while (contacts.hasNext()) {
    out.println(contacts.next().getID());
}
Suggest Edits

List by Email

 

You can fetch all Leads with a given email by querying the leads resource with an email parameter.

Example Request

$ curl \
https://api.intercom.io/contacts?email=obrien@truth.org \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
{
    "type": "contact.list",
    "pages": {
        "type": "pages",
        "next": null,
        "page": 1,
        "per_page": 50,
        "total_pages": 1
    },
    "contacts": [
        {
            "type": "contact",
            "id": "5811f6bbe6b4704ddfa84ac0",
            "user_id": "77177570-cf5d-4f1a-bc75-75202af47d4f",
            "anonymous": true,
            "email": "obrien@truth.org",
            "phone": "00353875551234",
            "name": "O&#39;Brien",
            "pseudonym": "Lime Camel from Dublin",
            "avatar": {
                "type": "avatar",
                "image_url": null
            },
            "app_id": "ja43hiec",
            "companies": {
                "type": "company.list",
                "companies": []
            },
            "location_data": {
                "type": "location_data",
                "city_name": "Mukilteo",
                "continent_code": "NA",
                "country_name": "United States",
                "latitude": 47.913,
                "longitude": -122.3042,
                "postal_code": "98275",
                "region_name": "Washington",
                "timezone": "America/Los_Angeles",
                "country_code": "USA"
            },
            "last_request_at": 1477660267,
            "last_seen_ip": "1.2.3.4",
            "created_at": 1477572283,
            "remote_created_at": null,
            "signed_up_at": null,
            "updated_at": 1480068674,
            "session_count": 0,
            "social_profiles": {
                "type": "social_profile.list",
                "social_profiles": []
            },
            "unsubscribed_from_emails": false,
            "user_agent_data": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9",
            "tags": {
                "type": "tag.list",
                "tags": []
            },
            "segments": {
                "type": "segment.list",
                "segments": []
            },
            "custom_attributes": {
                "paid_subscriber": true,
                "monthly_spend": 155.5,
                "team_mates": 9
            }
        }
    ],
    "total_count": 1,
    "limited": false
}
contacts = intercom.contacts.find_all(email: "winstonsmith@truth.org")
ContactCollection contacts = Contact.listByEmail("winstonsmith@truth.org");

// get first page...
List<Contact> items = contacts.getPageItems();

// ...or iterate over all pages
while (contacts.hasNext()) {
    out.println(contacts.next().getID());
}
<?php
$leads= $intercom->leads->getLeads(['email' => 'socrates@phil.com']);
foreach ($leads->contacts as $lead) {
    print_r($lead->id);
    echo "\n";
}?>
Suggest Edits

Delete a Lead

 

Leads can be deleted via their id, or with a user_id parameter.

Example ID Delete Request

$ curl \
https://api.intercom.io/contacts/5811f6bbe6b4704ddfa84ac0 \
-X DELETE \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 Ok

{
    "type": "contact",
    "id": "5811f6bbe6b4704ddfa84ac0",
    "user_id": "77177570-cf5d-4f1a-bc75-75202af47d4f",
    "anonymous": true,
    "email": "obrien@truth.org",
    "phone": "00353875551234",
    "name": "O&#39;Brien",
    "pseudonym": "Lime Camel from Dublin",
  ...
}
# NB: Full Contact objects are returned
contact = intercom.contacts.find(:id => "530370b477ad7120001d")
intercom.contacts.delete(contact)
Contact user = new Contact().setId("530370b477ad7120001d");
Contact.delete(contact);
<?php
$intercom->leads->deleteLead("596f6c41a43a45f05de3275f");
?>
Suggest Edits

Convert a Lead

 

Leads can be converted to Users. This is done by passing both Lead and User identifiers. If the User exists, then the Lead will be merged into it, the Lead deleted and the User returned. If the User does not exist, the Lead will be converted to a User, with the User identifiers replacing it's Lead identifiers.

Identifiers (id, user_id, email) from Leads are never added onto Users with a merge.

A Lead's email, but not user_id is retained when converting a Lead to a new User.

Example Lead Convert Request

$ curl \
https://api.intercom.io/contacts/convert \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json' \
-H 'Content-Type: application/json' -d '
{
  "contact": {
    "user_id": "8a88a590-e1c3-41e2-a502-e0649dbf721c"
  },
  "user": {
    "email": "winstonsmith@truth.org"
  }
}'
HTTP/1.1 200 Ok

{
  "type": "user",
  "email": "winstonsmith@truth.org"
}
# NB: Full User objects are returned
intercom.contacts.convert(contact, user)
<?php
$response = $intercom->leads->convertLead([
    "contact" => [
        "id" => "596f6b60d797879302bd7ac1" 
    ],
    "user" => [
        "user_id" => "470" 
    ]
]);
print_r($response)
?>
User converted = Contact.convert(contact, user);
Suggest Edits

Scroll over all leads

 

The lead listing functionality does not work well for huge datasets, and can result in errors and performance problems when paging deeply. The Scroll API provides an efficient mechanism for iterating over all leads in a dataset.

  • Each app can only have 1 scroll open at a time. You'll get an error message if you try to have more than one open per app.
  • If the scroll isn't used for 1 minute, it expires and calls with that scroll param will fail
  • If the end of the scroll is reached, "contacts" will be empty and the scroll parameter will expire

Scroll Parameter

You can get the first page of leads by simply sending a GET request to the scroll endpoint. For subsequent requests you will need to use the scroll parameter from the response.

# Send a GET request to get the first page of leads
$ curl \
'https://api.intercom.io/contacts/scroll' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
# To get the next page use the scroll param returned in the response
$ curl \
'https://api.intercom.io/contacts/scroll?scroll_param=562bc29f-ea55-4823-aaaf-f3faadceaa59' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
  "type": "contact.list",
  "users": [
    {
      "type": "contact",
      "id": "530370b477ad7120001d",
       ...
     },
     ...
   ],
  "scroll_param": "25b649f7-4d33-4ef6-88f5-60e5b8244309"
}
# You can use the scroll method to list all your users
intercom.users.scroll.each { |lead| puts lead.name}
# Alternatively you can use the scroll.next method to get 100 leads with each request
result = intercom.contacts.scroll.next
result.scroll_param
=> "0730e341-63ef-44da-ab9c-9113f886326d"
result = intercom.contacts.scroll.next("0730e341-63ef-44da-ab9c-9113f886326d");
 

Visitors are useful for representing logged-out users that didn't interact with the Intercom widget yet. Visitors are not visible in Intercom platform. After specific actions Visitors can be converted to Leads in Intercom.
The Visitors resource provides methods to fetch, update, convert and delete.

Suggest Edits

Visitor Object

 

A visitor object contains the following fields -

Attribute
Type
Description

type

string

value is 'visitor'

id

string

The Intercom defined id representing the Visitor

created_at

timestamp

The time the Visitor was added to Intercom

updated_at

timestamp

The last time the Visitor was updated

user_id

string

Automatically generated identifier for the Visitor

name

string

The name of the Visitor

custom_attributes

object

The custom attributes you have set on the Visitor

last_request_at

timestamp

The time the Lead last recorded making a request

avatar

object

An avatar object for the Visitor

unsubscribed_from_emails

boolean

Whether the Visitor is unsubscribed from emails

location_data

object

A Location Object relating to the Visitor

user_agent_data

string

Data about the last user agent the Visitor was seen using

last_seen_ip

no

An ip address (e.g. "1.2.3.4") representing the last ip address the Visitor visited your application from. (Used for updating location_data)

social_profiles

list

A list of social profiles associated with the Visitor

segments

list

A list of segments the Visitor.

tags

list

A list of tags associated with the Visitor.

Suggest Edits

View a Visitor

 

Visitors can be looked up individually via their id, or with a user_id parameter.
To get the visitor user_id from the browser you can use the Intercom JS SDK following method : Intercom('getVisitorId').

Example ID Request

$ curl \
-s https://api.intercom.io/visitors/573479f784c5acde6a000575 \   
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'

or 

$ curl \
-s https://api.intercom.io/visitors\?user_id\=16e690c0-485a-4e87-ae98-a326e788a4f7 \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
  "type": "visitor",
  "id": "573479f784c5acde6a000575",
  "user_id": "16e690c0-485a-4e87-ae98-a326e788a4f7",
  "email": "winstonsmith@truth.org",
  "name": "Winston Smith",
  ...
}
# NB: Full Visitor objects are returned
visitor = intercom.visitors.find(:id => "530370b477ad7120001d")
visitor = intercom.visitors.find(:user_id => "8a88a590-e1c3-41e2-a502-e0649dbf721c")
Suggest Edits

Update a Visitor

 

Sending a PUT request to /visitors and passing identifiers (user_id or id) in the body will result in an update of an existing Visitor.

It is not possible to uniquely identify a Visitor for an update with an email address. Including an email address in the PUT request will result in converting the Visitor to a Lead.

Example Request

$ curl https://api.intercom.io/visitors \
-XPUT \
-H 'Authorization:Bearer <Your access token>'  \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d '
{
  "user_id": "124",
  "name": "Winston Smith",
  "last_seen_ip" : "1.2.3.4",
  "last_seen_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9",
  "custom_attributes": {
    "paid_subscriber" : true,
    "monthly_spend": 155.5,
    "team_mates": 9
  }
}'
HTTP/1.1 200 OK

# contact response
visitor.name = "Winston Smith"
visitor.custom_attribute[:foo] = 'bar'
intercom.visitors.save(visitor)
Suggest Edits

Delete a visitor

 

Example ID Delete Request

$ curl \
https://api.intercom.io/visitors/5321a20f72cdbb4192000013 \
-X DELETE \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 Ok

{
  "type": "visitor",
  "id": "530370b477ad7120001d",
  "user_id": "8a88a590-e1c3-41e2-a502-e0649dbf721c"
  ...
}
# NB: Full Visitor objects are returned
Suggest Edits

Convert a Visitor to a Lead

 

Visitors can be converted to Leads. This is done by passing Visitor identifiers and a type attribute set to 'lead'.

Example Lead Convert Request

$ curl \
https://api.intercom.io/visitors/convert \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
-H 'Content-Type: application/json' -d '
{
  "visitor": {
    "user_id": "8a88a590-e1c3-41e2-a502-e0649dbf721c"
  },
  "type": "lead"
}'
HTTP/1.1 200 Ok

{
  "type": "user",
  "email": "winstonsmith@truth.org"
}
# NB: Full User objects are returned
Suggest Edits

Convert a Visitor to a User

 

Example User Convert Request

Visitors can also be converted to Users. This is done by passing both Visitor and User identifiers and a type attribute set to 'user'.
If the User exists, then the Visitor will be merged into it, the Visitor deleted and the User returned. If the User does not exist, the Visitor will be converted to a User, with the User identifiers replacing it's Visitor identifiers.

Identifiers (id, user_id, email) from Visitors are never added onto Users with a merge.

A Visitor email, but not user_id is retained when converting a Visitor to a new User.

$ curl \
https://api.intercom.io/visitors/convert \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
-H 'Content-Type: application/json' -d '
{
  "visitor": {
    "user_id": "8a88a590-e1c3-41e2-a502-e0649dbf721c"
  },
  "user": {
    "email": "winstonsmith@truth.org"
  },
  "type": "user"
}'
# NB: Full User objects are returned
{
  "type": "lead",
  "user_id": "8a88a590-e1c3-41e2-a502-e0649dbf721c"
}
Suggest Edits

Companies

 

Companies allow you to represent commercial organizations using your product.

Each company will have its own description and be associated with users. You can create and update companies and add custom attributes describing them. Companies can be viewed individually or as a list, and can be queried using tags or segments.

Companies will not appear within Intercom until users have been added or associated with a company.

Suggest Edits

Company Model

 

Company Object

A company object contains the following fields -

Attribute
Type
Description

type

string

value is 'company'

id

string

The Intercom defined id representing the company

created_at

timestamp

The time the company was added to Intercom

remote_created_at

timestamp

The time the company was created by you

updated_at

timestamp

The last time the company was updated

company_id

string

The company id you have defined for the company

name

string

The name of the company

custom_attributes

object

The custom attributes you have set on the company

session_count

integer

How many sessions the company has recorded

monthly_spend

number

How much revenue the company generates for your business

user_count

number

The number of users in the company

plan

string

The name of the plan you have associated with the company

Company List

A company list contains the following fields -

Attribute
Type
Description

type

string

value is 'company.list'

total_count

integer

The number of companies for this App

companies

array

A list of companies

pages

object

Optional. A pagination object, which may be empty, indicating no further pages to fetch

Example Company Object

{
  "type": "company",
  "id": "531ee472cce572a6ec000006",
  "name": "Blue Sun",
  "plan": "plan1",
  "company_id": "6",
  "remote_created_at": 1394531169,
  "created_at": 1394533506,
  "updated_at": 1396874658,
  "monthly_spend": 49,
  "session_count": 26,
  "user_count": 10,
  "custom_attributes": {
    "paid_subscriber" : true,
    "team_mates": 0
  }
}

Example Company List

{
  "type": "company.list",
  "total_count": 1,
  "companies": [
    {
      "type": "company",
      "id": "531ee472cce572a6ec000006",
      "name": "Blue Sun",
      "plan": "plan1",
      "company_id": "6",
      "remote_created_at": 1394531169,
      "created_at": 1394533506,
      "updated_at": 1396874658,
      "monthly_spend": 49,
      "session_count": 26,
      "user_count": 10,
      "custom_attributes": {
        "paid_subscriber" : true,
        "team_mates": 0
      }
    }
  ],
  "pages": {
    "page": 1,
    "per_page": 50,
    "total_pages": 1
  }
}
Suggest Edits

Create or Update Company

 

Companies can be created or updated via a POST to https://api.intercom.io/companies, which accepts a JSON object describing the company.

Companies with no users

It is important to note that companies will be only visible in Intercom when there is at least one associated user. Check the Companies and Users section for more information

Companies are looked up via company_id, if not found via company_id, the new company will be created, if found, that company will be updated.

Note that the company_id field itself cannot be updated through the API.

Companies may also be created or updated via a User request - see the section "Create or Update User".

Attributes

The table below shows the fields you can create or update for a company -

Attribute
Type
Description

remote_created_at

timestamp

The time the company was created by you

company_id

string

The company id you have defined for the company

name

string

The name of the company

monthly_spend

number

How much revenue the company generates for your business. Note that this will truncate floats. i.e. it only allow for whole integers, 155.98 will be truncated to 155. Note that this has an upper limit of 2**31-1 or 2147483647.

plan

string

The name of the plan you have associated with the company

custom_attributes

object

A hash of key/value pairs containing any other data about the company you want Intercom to store.

Custom Attributes

The custom_attributes object allows you to send any information you wish about a company with the following restrictions -

  • Field names must not contain Periods (.) or Dollar ($) characters
  • Field names must be no longer than 190 characters.
  • Field values must be JSON Strings, Numbers or Booleans - Objects and Arrays will be rejected.
  • String field values must be no longer than 255 characters.
  • Maximum of 100 fields.

Session Count

A company's session count is tied to users' session count whilst in the context of that company. So, to update a company session count,
update the user with that company and increment the user's session.

Returns

The created or updated company object.

New company objects will be provided with an id field - this value cannot be created or edited by clients.

Example Request

$ curl https://api.intercom.io/companies \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type:application/json' -d '
{
  "name": "Blue Sun",
  "plan": "Paid",
  "company_id": "6",
  "remote_created_at": 1394531169,
  "custom_attributes": {
    "paid_subscriber" : true,
    "team_mates": 0,
    "monthly_spend": 155.98
  }
}'
HTTP/1.1 200 OK

{
    "type": "company",
    "company_id": "6",
    "id": "57e0120926806ceca3c13ba8",
    "app_id": "pi3243fa",
    "name": "Blue Sun",
    "remote_created_at": 1394531169,
    "created_at": 1474302473,
    "updated_at": 1475659931,
    "last_request_at": 1473419085,
    "monthly_spend": 49,
    "session_count": 0,
    "user_count": 0,
    "tags": {
        "type": "tag.list",
        "tags": []
    },
    "segments": {
        "type": "segment.list",
        "segments": [
            {
                "type": "segment",
                "id": "56cc69cc8618d37b45000009"
            }
        ]
    },
    "plan": {
        "type": "plan",
        "id": "108609",
        "name": "Paid"
    },
    "custom_attributes": {
        "paid_subscriber": true,
        "team_mates": 0,
        "referral_source": "Google",
        "founded": "20th Century",
        "monthly_spend": 155.98,
        "remove": true
    }
}
// unsupported
intercom.companies.create(:company_id => 6, :name => "Blue Sun", :plan => "Paid")
<?php
$intercom->companies->create([
    "name" => "Academy",
    "id" => "10"
])
?>
import static io.intercom.api.CustomAttribute.*;

Company company = new Company()
  .setName("Blue Sun")
  .setCompanyID("1")
  .setPlan(new Company.Plan("premium"))
  .addCustomAttribute(newIntegerAttribute("items", 246))
  .addCustomAttribute(CustomAttribute.newStringAttribute("bar", "fruity"));

company = Company.create(company);

company.setName("Blue Sun Corporation");
Company.update(company);
Suggest Edits

View a Company

 

Each company has its own URL -

  • https://api.intercom.io/companies/{id}

Where {id} is the value of the company's id field. This URL is the company's canonical address in the API.

Request Parameters

Parameter
Required
Description

name

no

The name of the company

company_id

no

The company_id you have given to the company

A company can also be fetched by its name using a name or company_id parameter in the url, whose values are the ones you have defined for that company -

  • https://api.intercom.io/companies?name={name}
  • https://api.intercom.io/companies?company_id={company_id}

The name parameter value should be url encoded when sending, as company names are allowed to have values that either need to be encoded as character data (e.g., whitespace) or are reserved characters (e.g., ':').

Example View Request and Response

$ curl \
-s https://api.intercom.io/companies?company_id=141 \
-H 'Authorization:Bearer <Your access token>' \
-H "Accept:application/json" \
HTTP/1.1 200 OK

{
  "type": "company",
  "id": "531ee472cce572a6ec000006",
  "name": "Blue Sun",
  "plan": {
    "type":"plan",
    "id":"1",
    "name":"Paid"
  },
  "company_id": "141",
  "remote_created_at": 1394531169,
  "created_at": 1394533506,
  "updated_at": 1396874658,
  "last_request_at": 1396874658,
  "monthly_spend": 49,
  "session_count": 26,
  "user_count": 10,
  "custom_attributes": {
    "paid_subscriber" : true,
    "team_mates": 0
  }
}
intercom.companies.find(:id => "41e66f0313708347cb0000d0")
<?php
# Using the name of the company
$intercom->companies->getCompanies(['name' => 'OneAmerica']);

# Via company_id
$intercom->companies->getCompanies(['company_id' => '10']);

?>
String id = "541a144b201ebf2ec5000001";
Company company = Company.find(id);
Suggest Edits

List Companies

 

You can fetch a list of companies. The company list is sorted by the last_request_at field and by default is ordered descending, most recently created first.

Note that the API does not include companies who have no associated users in list responses.

Request Parameters

You can optionally request the result page size and which page to fetch as follows -

Parameter
Required
Description

page

no

what page of results to fetch defaults to first page.

per_page

no

how many results per page defaults to 50.

order

no

asc or desc. Return the companies in ascending or descending order. defaults to desc.

Returns

A pageable list of companies. The list contains a pages object that indicates if more items exist via the next field, whose value is a URL that can be used to fetch the next page. If the next field is not present, that indicates there are no further items in the list.

When using the Companies endpoint and the pages object to iterate through the returned companies, there is a limit of 10,000 Companies that can be returned. If you need to list or iterate on more than 10,000 Companies, please use the Scroll API.

List companies

$ curl https://api.intercom.io/companies \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
  "type": "company.list",
  "total_count": 105,
  "companies": [
    {
      "type": "company",
      "id": "530370b477ad7120001d",
       ...
     },
     ...
   ],
  "pages": {
    "next": "https://api.intercom.io/companies?per_page=50&page=2",
    "page": 1,
    "per_page": 50,
    "total_pages": 3
  }
}

# NB: Full company objects are returned
intercom.companies.all.each { ... }
<?php
$companies= $intercom->companies->getCompanies([]);
foreach ($companies->companies as $company) {
    print_r($company->company_id);
    echo "\n";
}
?>
CompanyCollection companies = Company.list();
// get first page
List<Company> items = companies.getPageItems();
// or iterate over pages
while (companies.hasNext()) {
  System.out.println(companies.next().getName());
}
Suggest Edits

List by Tag or Segment

 

You can fetch segmented and tagged companies by querying the companies resource with the segment_id and tag_id parameters (for information on how to tag companies see the section "Create and update tags").

Note that you can query by tag or segment but not both in the same request.

Request Parameters

Parameter
Required
Description

tag_id

one of

The id of the tag to filter by.

segment_id

one of

The id of the segment to filter by.

Returns

A pageable list of companies. Like a plain company list, the result contains a pages object that indicates if more companies exist via the next field.

Example List by tag request

$ curl https://api.intercom.io/companies?tag_id=17 \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
  "type": "company.list",
  "total_count": 105,
  "companies": [
    {
      "type": "company",
      "id": "530370b477ad7120001d",
       ...
     },
     ...
   ],
  "pages": {
    "next": "https://api.intercom.io/companies?tag=14&per_page=50&page=2",
    "page": 1,
    "per_page": 50,
    "total_pages": 3
  }
}

# NB: Full company objects are returned
intercom.companies.find(:tag_id => "1234")
intercom.companies.find(:segment_id => "4567")
<?php
$companies = $intercom->companies->getCompanies(["tag_id" => '1153470']);
print_r($companies->companies);

$companies = $intercom->companies->getCompanies(["segment_id" => '596f8022227edee8a052e910']);
print_r($companies->companies);

?>
Map<String, String> params = Maps.newHashMap();
params.put("tag_id", "1234");
Company company = Company.list(map);

params = Maps.newHashMap();
params.put("segment_id", "4567");
Company company = Company.list(map);
Suggest Edits

Delete a Company

 

Currently, the API does not support deleting a company. The operation may be added in the future.

Returns

A company object.

Suggest Edits

List Company Users

 

The users belonging to a company can be listed by sending a GET request to https://api.intercom.io/companies/{id}/users, where {id} is the value of the company's id field.

To query for a company's users using the company id value you have assigned to the company, send a GET request to https://api.intercom.io/companies, using the parameter {company_id} with value of the company id, and a type field with a value of users.

Request Parameters

Parameter
Required
Description

company_id

yes

Your company id for the company.

type

yes

The value must be user

Returns

A pageable list of users and leads. Response objects contain type set to user and contact respectively. See the section "List Users" and "List Leads" for details of the JSON response.

Example ID Request

$ curl https://api.intercom.io/companies/5310dabd598c9a0a7e000005/users \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
intercom.companies.users(company.id)
Map<String, String> params params = Maps.newHashMap();
params.put("company_id", "6");
UserCollection users = Company.listUsers(params);

Example Company ID Request

$ curl https://api.intercom.io/companies?company_id=22&type=user \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
  "type": "user.list",
  "total_count": 10,
  "users": [
    {
      "type": "user",
      "id": "530370b477ad7120001d",
       ...
     },
     ...
   ]
}

# NB: Full User objects are returned
intercom.companies.users(company.company_id)
Map<String, String> params = Maps.newHashMap();
params.put("company_id", "1");
Company company = Company.find(map);
Suggest Edits

Scroll over all companies

 

The Company listing functionality does not work well for huge datasets, and can result in errors and performance problems when paging deeply. The Scroll API provides an efficient mechanism for iterating over all companies in a dataset.

  • Each app can only have 1 scroll open at a time. You'll get an error message if you try to have more than one open per app.
  • If the scroll isn't used for 1 minute, it expires and calls with that scroll param will fail
  • If the end of the scroll is reached, "companies" will be empty and the scroll parameter will expire

Scroll Parameter

You can get the first page of companies by simply sending a GET request to the scroll endpoint. For subsequent requests you will need to use the scroll parameter from the response.

# Send a GET request to get the first page of companies
$ curl \
'https://api.intercom.io/companies/scroll' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
# To get the next page use the scroll param returned in the response
$ curl \
'https://api.intercom.io/companies/scroll?scroll_param=562bc29f-ea55-4823-aaaf-f3faadceaa59' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
  "type": "company.list",
  "companies": [
    {
      "type": "company",
      "id": "530370b477ad7120001d",
       ...
     },
     ...
   ],
  "scroll_param": "25b649f7-4d33-4ef6-88f5-60e5b8244309"
}
# You can use the scroll method to list all your companies
intercom.companies.scroll.each { |company| puts company.name}
# Alternatively you can use the scroll.next method to get 100 companies with each request
result = intercom.companies.scroll.next
result.scroll_param
=> "0730e341-63ef-44da-ab9c-9113f886326d"
result = intercom.companies.scroll.next("0730e341-63ef-44da-ab9c-9113f886326d");

Admins are how you can view your teams and team members.

The API currently only supports viewing the admins and teams created in your App.
Creating and managing admins and teams must be done through the Intercom App.

Suggest Edits

Admin Model

 

Admin Object

An admin has a name, email and id field.

Attribute
Type
Description

type

string

value is 'admin' or 'team'

id

string

The id of the admin or team

name

string

The name of the admin or team

email

string

The email address of the admin. This attribute is null for teams.

Example Object

{
  "type": "admin",
  "id": "1",
  "name": "Hoban Washburne",
  "email": "wash@serenity.io"
}
Suggest Edits

List Admins

 

An App's admins can be fetched by sending a GET request to https://api.intercom.io/admins/.

Admin List

Attribute
Type
Description

type

string

value is 'admin.list'

admins

array

A list of admin objects

pages

object

Optional. A pagination object, which may be empty, indicating no further pages to fetch.

Request Parameters

None.

Returns

A list of admin objects for the App. The result may also have a pages object if the response is paginated.

A tag allows you to label your users and companies and list them using that tag.

This section describes how tags can be created updated and deleted. It also describes how users and companies can be tagged or untagged individually or in bulk.

How to query using a tag is described in the respective sections for users and companies - see "List by Tag, Segment, Company" for Users, and "List by Tag or Segment" for Companies.

List Admins

$ curl https://api.intercom.io/admins \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json'
HTTP/1.1 200 Ok

{
  "type": "admin.list",
  "admins": [
    {
      "type": "admin",
      "id": "1",
      "name": "Hoban Washburne",
      "email": "wash@serenity.io"
    },
    {
      "type": "admin",
      "id": "2",
      "name": "Zoe Alleyne",
      "email": "zoe@serenity.io"
    }
  ]
}
intercom.admins.all.each { ... }
<?php
$admins= $intercom->admins->getAdmins();
foreach ($admins->admins as $admin) {
    print_r($admin->id);
}?>
AdminCollection admins = Admin.list();
// get first page...
List<Admin> pageItems = admins.getPageItems();
// ...or iterate over pages
while (admins.hasNext()) {
    System.out.println(admins.next().getName());
}
Suggest Edits

Viewing the current admin and app

 

OAuth only

This feature is only available when using OAuth. This requires the "Read admins" permission.

You can view the name, email and app ID of the current authorised admin via a GET request to https://api.intercom.io/me.

Returns

An Admin model, with an embedded App object.

Attribute
Type
Description

type

string

value is 'admin'

id

string

The id of the admin

name

string

The name of the admin

email

string

The email address of the admin

email_verified

boolean

This field will indicate whether the Intercom user has verified their email or not

app.type

string

value is 'app'

app.id_code

string

The id of the app

app.name

string

The name of the app

app.created_at

timestamp

When the app was created

app.identity_verification

boolean

Whether or not the app uses identity verification

Single Sign On

If you are building a custom "Log in with Intercom" flow for your site, and you call the /me endpoint to identify the user logging, in you should not accept any sign ins from users with unverified email addresses as it poses a potential impersonation security risk.

Suggest Edits

View an Admin

 

Each admin object has its own URL -

  • https://api.intercom.io/admins/{id}

Where {id} is the value of the admins's id field.

Retrieve a single admin

$ curl https://api.intercom.io/admins/1 \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json'
HTTP/1.1 200 Ok

{
  "type": "admin",
  "id": "1",
  "name": "Hoban Washburne",
  "email": "wash@serenity.io"
}
<?php
$admin = $intercom->admins->getAdmin("493881");
?>

A tag allows you to label your users and companies and list them using that tag.

This section describes how tags can be created, updated and deleted. It also describes how users and companies can be tagged or untagged individually or in bulk.

How to query using a tag is described in the respective sections for users and companies - see “List by Tag, Segment, Company” for Users, and “List by Tag or Segment” for Companies.

Suggest Edits

Tag Model

 

Tag Object

A tag has a name and an id field. Once created the id field cannot be changed, but the name field can be updated later to allow tag renaming.

Attribute
Type
Description

type

string

value is 'tag'

id

string

The id of the tag

name

string

The name of the tag

Example Object

{
  "id": "17513",
  "name": "independent",
  "type": "tag"
}
Suggest Edits

Create and Update Tags

 

You can create a new tag by submitting a POST to https://api.intercom.io/tags along with a name for the tag. The tag name may contain whitespace and punctuation.

If the same tag name is sent multiple times, only one tag will be created for that name - this lets you avoid checking if a tag exists first.

Tag names are case insensitive - 'MyTag' and 'mytag' will result in a single tag being created.

A tag's name can also be updated by posting a tag to https://api.intercom.io/tags. The submitted tag object will contain the id of the tag to update and a new name for the tag. A successful request will update the name value for that tag and return the updated tag in the response.

Attributes

Attribute
Required
Description

name

Yes

The name of the tag, which will be created if not found, or the new name for the tag if this is an update request.

id

Yes for update

The id of tag to updates.

Returns

The newly created or updated tag object containing its name and id fields.

$ curl https://api.intercom.io/tags \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d'
{
  "name": "Independent"
}'
HTTP/1.1 200 Ok

{
  "type": "tag",
  "name": "Independent",
  "id": "17513"
}
intercom.tags.tag(name: 'Independent', users: [{ id: "42ea2f1b93891f6a99000427" }])
<?php
$intercom->tags->tag(["name" => "php-tag"]);
?>
Tag t = new Tag().setName("Independent");
t = Tag.create(t);
$ curl https://api.intercom.io/tags \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d'
{
  "id": "17513",
  "name": "Independent"
}'
HTTP/1.1 200 Ok

{
  "type": "tag",
  "name": "Independent",
  "id": "17513"
}
intercom.tags.tag(name: 'Independent', users: [ { id: "42ea2f1b93891f6a99000427" } ])
<?php
$intercom->tags->tag(["id" => "1160078", "name" => "php-tag-new"]);
?>
tag.setName("independent");
Tag.update(tag);
Suggest Edits

Tag or Untag Users, Companies & Leads (Contacts)

 

You can also tag users, companies, or leads (contacts) using a POST to https://api.intercom.io/tags. This lets you assign a tag to multiple users or companies at once. If the tag does not already exist it will be created for you.

Users can be tagged by supplying a users array. The array contains objects identifying users by their id, email or user_id fields.

Companies can be tagged by sending a companies array. The array contains objects identifying companies by their idor company_id fields.

Contacts/Leads can be tagged by supplying a users array. The array contains objects identifying leads by their id fields.

Companies and user tag directives cannot be mixed in the same request - a request will not process both company and user arrays.

We recommend tagging no more than 50 users at a time as larger amounts could result in a timeout.

Example Untag Request

To untag a company or user, each user or company object sent in the tagging request can be submitted with an untag field whose value is set to true.

Objects submitted with an untag field can be mixed with other objects being tagged. This allows tag and untag operations to be performed in a single request.

The default behaviour if untag is not suppled is to tag the object. Setting the untagvalue to false is the same as requesting the object be tagged.

Attributes

Attribute
Required
Description

name

required

The name of the tag, which will be created if not found.

users

optional

An array of objects identifying users.

companies

optional

An array of objects identifying companies.

Returns

The tag object containing its name and id fields.

Example Tag Request

$ curl https://api.intercom.io/tags \
-XPOST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d'
{
  "name": "Independent",
  "users": [
    {
      "id" : "53427b7ecce5722303000003"
    },
    {
      "user_id" : "22"
    },
    {
      "email" : "a@b.com"
    }
  ]
}'
HTTP/1.1 200 Ok

{
  "type": "tag",
  "name": "Independent",
  "id": "17513"
}
intercom.tags.tag(name: 'Independent', users: [{ id: "42ea2f1b93891f6a99000427" }, { email: "foo@bar.com" }])
<?php
# Note that you can use either id, user_id or email to tag a user.
# You only need to use one per user, e.g. the below will tag
# three users if each identifier is for a different, unique user
$intercom->tags->tag([
    "name" => "VIPs",
    "users" => [
        ["id" => "5977e20941abfc5aae4552d1"],
        ["user_id" => "12345"],
        ["email" => "camus@phil.com"]
    ]
]);
?>
User one = new User().setEmail("river@serenity.io");
User two = new User().setEmail("simon@serenity.io")
List<User> users = Lists.newArrayList(one, two);
Tag.tag(tag, new UserCollection(users));
$ curl https://api.intercom.io/tags \
-XPOST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d'
{
  "name": "Independent",
  "users": [
    {
      "id" : "53427b7ecce5722303000003",
      "untag": true
    },
    {
      "user_id" : "22"
    }
  ]
}'
intercom.tags.untag(name: 'blue', users: [{ id: "42ea2f1b93891f6a99000427" }])
<?php
$intercom->tagUsers(array(
  "name" => "Independent",
  "users" => array(
    array("user_id" => "22", "untag" => true)
  )
));
?>
User user = new User()
  .setEmail("simon@serenity.io")
  .untag();
List<User> users = Lists.newArrayList(user);
Tag.tag(tag, new UserCollection(users));
HTTP/1.1 200 Ok

{
  "type": "tag",
  "name": "Follow Up",
  "id": "17513"
}
Suggest Edits

Delete a Tag

 

A tag can be deleted by sending a DELETE request to its URL. A tag's URL is defined using using the tag's id field to create a URL of the form, https://api.intercom.io/tags/{id}.

Example Delete Tag Request

$ curl https://api.intercom.io/tags/17513 \
-X DELETE \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json'
# Not exposed in Ruby client
<?php
// Not exposed in PHP client
?>
Tag.delete(tag);
Suggest Edits

List Tags for an App

 

You can fetch the tags for an App by sending a GET request to https://api.intercom.io/tags.

Parameters

None.

Returns

A list of tag objects for the App.

Tag List

Attribute
Type
Description

type

string

value is 'tag.list'

tags

array

A list of tag objects

Example List Tag Request

$ curl https://api.intercom.io/tags \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json'
{
  "type": "tag.list",
  "tags": [
    {
      "type": "tag",
      "name": "Beta User",
      "id": 1
    },
    {
      "type": "tag",
      "name": "Amazing User",
      "id": 2
    },
    {
      "type": "tag",
      "name": "Epic User",
      "id": 3
    }
  ]
}
intercom.tags.all.each { ... }
<?php
$tags= $intercom->tags->getTags([]);
foreach ($tags->tags as $tag) {
    print "id:".$tag->id." name:".$tag->name."\n";
}?>
TagCollection tags = Tag.list();
while (tags.hasNext()) {
    out.println(tags.next().getId());
}
 

A segment is a group of your users defined by rules that you set. Users are automatically added to the segment every time the user updates to match those rules. Segments are different to tags, in that users need to be added to tags manually and tag members are not automatically managed.

The API supports fetching the list of segments created in your App, however creating and managing segments must be done through Intercom. For more information about segmenting users, please see the product documentation.

Suggest Edits

Segment Model

 

Segment Object

A segment has a name and an id field along with created_at and updated_at timestamps. It can optionally include a count of the items in the segment.

Attribute
Type
Description

type

string

value is segment'

id

string

The id representing the segment

name

string

The name of the segment

created_at

timestamp

The time the segment was created

updated_at

timestamp

The time the segment was updated

person_type

string

Type of the record: user or lead.

count

integer

The number of items in the segment. It's returned when include_count=true is included in the request.

Example Object

{
  "type": "segment",
  "id": "53203e244cba153d39000062",
  "name": "New",
  "created_at": 1394621988,
  "updated_at": 1394622004
}
Suggest Edits

List Segments

 

You can list the user segments for your App by sending a GET request to https://api.intercom.io/segments. Company segments can be listed by sending a GET request to https://api.intercom.io/segments?type=company.

You can also include counts in your segment model in the response if you add the parameter include_count=true in the request

Segment List

Attribute
Type
Description

type

string

value is 'segment.list'

segments

array

A list of segment objects

pages

object

Optional. A pagination object, which may be empty, indicating no further pages to fetch.

Returns

A list of segment objects for the App. The result may also have a pages object if the response is paginated.

Example Request

$ curl https://api.intercom.io/segments
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
  "type": "segment.list",
  "segments": [
    {
      "created_at": 1393613031,
      "id": "5310d8e7598c9a0b24000002",
      "name": "Active",
      "type": "segment",
      "updated_at": 1393613031
    },
    {
      "created_at": 1393613030,
      "id": "5310d8e6598c9a0b24000001",
      "name": "New",
      "type": "segment",
      "updated_at": 1393613030
    },
    {
      "created_at": 1393613031,
      "id": "5310d8e7598c9a0b24000003",
      "name": "Slipping Away",
      "type": "segment",
      "updated_at": 1393613031
    }
  ]
}
intercom.segments.all.each { ... }
<?php
$intercom->segments->getSegments([]);
?>
SegmentCollection segments = Segment.list();
while (segments.hasNext()) {
    out.println(segments.next().getId());
}
$ curl 'https://api.intercom.io/segments?count=segment&include_count=true'
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
    "type": "segment.list",
    "segments": [
        {
            "type": "segment",
            "id": "56cc69cd8618d37b4500000c",
            "name": "Active",
            "created_at": 1456237005,
            "updated_at": 1487064099,
            "person_type": "user",
            "count": 3
        },
        {
            "type": "segment",
            "id": "56cc69cc8618d37b4500000b",
            "name": "New",
            "created_at": 1456237004,
            "updated_at": 1473241975,
            "person_type": "user",
            "count": 0
        },
        {
            "type": "segment",
            "id": "56cc69cd8618d37b4500000d",
            "name": "Slipping Away",
            "created_at": 1456237005,
            "updated_at": 1473241975,
            "person_type": "user",
            "count": 0
        },
        {
            "type": "segment",
            "id": "56e6f1f2b7ebc2061200000d",
            "name": "test3WebSession",
            "created_at": 1457975794,
            "updated_at": 1473241976,
            "person_type": "user",
            "count": 1
        }
    ]
}
Suggest Edits

View a Segment

 

Each segment has its own URL -

  • https://api.intercom.io/segments/{id}

Where {id} is the value of the segment's id field. A GET request to a segment's URL will return the segment object.

You can also get a count for an individual segment by adding the parameter include_count=true

Returns

A segment object.

Example Request

$ curl https://api.intercom.io/segments/53203e244cba153d39000062 \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
  "type": "segment",
  "id": "53203e244cba153d39000062",
  "name": "New",
  "created_at": 1394621988,
  "updated_at": 1394622004
}
intercom.segments.find(:id => '1234')
Segment segment = Segment.find("1234");
$ curl https://api.intercom.io/segments/58a707924f6651b07b94376c?include_count=true \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
    "type": "segment",
    "id": "58a707924f6651b07b94376c",
    "name": "id=10",
    "created_at": 1487341458,
    "updated_at": 1487341459,
    "person_type": "user",
    "count": 5
}

Notes allow you to annotate and comment on your users.

A note can be authored by an admin about a user, and the notes associated with a user can be listed.

Suggest Edits

Note Model

 

Note Object

Attribute
Type
Description

type

string

value is 'note'

id

string

The id representing the note

created_at

timestamp

The time the note was created

user

User

The user the note was created about

body

string

The body text of the note.

author

Admin

Optional. Represents the Admin that created the note

Example Object

{
  "type": "note",
  "id": "16",
  "created_at": 1389913941,
  "body": "<p>Text for my note</p>",
  "author": {
    "type": "admin",
    "id": "21",
    "name": "Jayne Cobb",
    "email": "jayne@serenity.io",
    "companies": []
  },
  "user": {
    "type": "user",
    "id": "5310d8e8598c9a0b24000005"
  }
}
Suggest Edits

Create a Note

 

Notes can be created via a POST method to https://api.intercom.io/notes, which accepts a JSON object describing the note.

Attributes

The table below shows the fields you can use to create a note -

Argument
Required
Description

user

Yes

Representation of the user the note is to be created about.

user.user_id

one of

Your user_id for the user

user.email

one of

Your email address for the user

user.id

one of

The user id for the user

admin_id

No

The id of the admin creating the note.

body

Yes

The text of the note.

Returns

A note object. The submitted body may be enclosed with html p elements in the response.

Example Request

$ curl https://api.intercom.io/notes \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json'  \
-H 'Content-Type: application/json' -d '
{
  "admin_id" : "21",
  "body": "Text for my note",
  "user": {
    "id" : "5310d8e8598c9a0b24000005"
  }
}'
HTTP/1.1 200 OK

{
  "type": "note",
  "id": "16",
  "created_at": 1389913941,
  "body": "<p>Text for my note</p>",
  "author": {
    "type": "admin",
    "id": "21",
    "name": "Jayne Cobb",
    "email": "jayne@serenity.io",
    "companies": []
  },
  "user": {
    "type": "user",
    "id": "5310d8e8598c9a0b24000005"
  }
}
intercom.notes.create(:body => "Text for the note", :email => 'joe@example.com')
<?php
$intercom->notes->create([
        "body" => "Text for the note",
        "user" => (["id" => "4956efd9aad5c02fc4750ee9"])]
);
?>
User user = new User().setEmail("jayne@serenity.io");
Author author = new Author().setId("1");
Note note = new Note()
  .setUser(user)
  .setAuthor(author)
  .setBody("Text for the note");
Note.create(note);
Suggest Edits

List Notes for a User

 

A user's notes can be fetched by using a GET request to https://api.intercom.io/notes with an Intercom user id or user_id or email query parameter.

The value of the email parameter should be url encoded before sending.

Parameters

Parameter
Required
Description

user_id

one of

The user id you have defined for the user

email

one of

The email you have defined for the user

id

one of

The Intercom defined id representing the user

Returns

A pageable list of note objects for that User.

The list may contain a pages object that indicates if more notes exist via the next field, whose value is a URL that can be used to fetch the next page. If the next field is not present, that indicates there are no further notes in the list.

Note List Object

Attribute
Type
Description

type

string

value is 'note.list'

notes

array

A list of note objects

pages

object

Optional. A pagination object, which may be empty, indicating no further pages to fetch.

Example User ID Request

$ curl https://api.intercom.io/notes?user_id=25 \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json'
intercom.notes.find_all(:user_id => '123').each {|note| puts note.body}
<?php
$notes = $intercom->notes->getNotes(["user_id" => "20413"]);
foreach ($notes->notes as $note) {
    print "id:".$note->id." body:".$note->body."\n";
}
?>
Map<String, String> params = Maps.newHashMap();
params.put("user_id", "123");
NoteCollection notes = Note.list(params);
while (notes.hasNext()) {
    out.println(notes.next().getBody());
}

Example Email Request

$ curl https://api.intercom.io/notes?email=jayne%40serenity.io \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json'
HTTP/1.1 200 OK

{
  "type": "note.list",
  "notes": [
    {
      "type": "note",
      "id": "1",
      "created_at": 1389913941,
      "body": "<p>Text for my note</p>",
      "author": {
        "type": "admin",
        "id": "21",
        "name": "Jayne Cobb",
        "email": "jayne@serenity.io",
        "companies": []
      },
      "user": {
        "type": "user",
        "id": "5310d8e8598c9a0b24000005"
      }
    },
    {
      "type": "note",
      "id": "2",
      "created_at": 1389913951,
      "body": "<p>Text for my note</p>",
      "user": {
          "id": "5310d8e8598c9a0b24000005",
          "type": "user"
        }
    }
  ],
  "pages": {}
}
intercom.notes.find_all(:email => 'foo@bar.com').each {|note| puts note.body}
<?php
$notes = $intercom->notes->getNotes(["email" => "plato@phil.com"]);

foreach ($notes->notes as $note) {
    print "id:".$note->id." body:".$note->body."\n";
}
?>
Map<String, String> params = Maps.newHashMap();
params.put("email", "malcolm@serenity.io");
notes = Note.list(params);
while (notes.hasNext()) {
    out.println(notes.next().getBody());
}

Example ID Request

$ curl \
https://api.intercom.io/notes?id=5310d8e8598c9a0b24000005 \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json'
# Not exposed in Ruby client
<?php
$notes = $intercom->notes->getNotes(["id" => "5965efd9aad5c02fc4750ee6"]);
foreach ($notes->notes as $note) {
    print "id:".$note->id." body:".$note->body."\n";
}
?>
Map<String, String> params = Maps.newHashMap();
params.put("id", "5310d8e8598c9a0b24000005");
notes = Note.list(params);
while (notes.hasNext()) {
    out.println(notes.next().getBody());
}
Suggest Edits

View a Note

 

Each note has its own URL -

  • https://api.intercom.io/notes/{id}

Where {id} is the value of the note's id field. A GET request to a note's URL will return the note object.

Returns

A note object.

Example Request

$ curl https://api.intercom.io/notes/2 \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json'
HTTP/1.1 200 OK

{
  "type": "note",
  "id": "2",
  "created_at": 1389913951,
  "body": "<p>Text for my note</p>",
  "user": {
      "id": "5310d8e8598c9a0b24000005",
      "type": "user"
    },
  "author": {
    "type": "admin",
    "id": "21",
    "name": "Jayne Cobb",
    "email": "jayne@serenity.io",
    "avatar" : {
       "type":"avatar",
      "image_url": "http://example.org/128Jayne.jpg"
    },
    "companies": []
  }
}
intercom.notes.find(:id => note)
<?php
$note = $intercom->notes->getNote("9259097");
?>
Note note = Note.find("2");

Events are how you can submit user activity to Intercom. Once you're sending Intercom event data, you can filter your user base with those events and create Auto Messages to send whenever an event occurs. Every event is associated with an event name, the time it happened, the user that caused the event, and optionally some extra metadata. Events record the count, first and last occurrence of an event.

Events are different to Custom Attributes in that events are information on what Users did and when they did it, whereas Custom Attributes represent the User's current state as seen in their profile. For example, the first time they subscribed to a paid plan, or the most recent time they changed their plan would be represented by events, whereas a User Attribute would be used to record their current plan.

Because Events are used for filtering and messaging, and event names are used directly in Intercom by your App's Admins we recommend sending high-level activity about your users that you would like to message on, rather than raw clickstream or user interface actions. For example an order action is a good candidate for an Event, versus all the clicks and actions that were taken to get to that point. We also recommmend sending event names that combine a past tense verb and nouns, such as 'created-project'.

The Events API varies slightly from the rest of the APIs as follows -

  • You can submit events using JavaScript using the trackEvent method.
  • When there's an error or errors, a list structure is returned instead of a single error.
Suggest Edits

Submitting Events

 

You will need an Access Token that has write permissions to send Events. Once you have a key you can submit events via POST to the Events resource, which is located at https://api.intercom.io/events, or you can send events using one of the client libraries. When working with the HTTP API directly a client should send the event with a Content-Type of application/json.

When using the JavaScript API, adding the code to your app makes the Events API available. Once added, you can submit an event using the trackEvent method. This will associate the event with the Lead or currently logged-in user or logged-out visitor/lead and send it to Intercom. The final parameter is a map that can be used to send optional metadata about the event.

With the Ruby client you pass a hash describing the event to Intercom::Event.create, or call the track_user method directly on the current user object (e.g. user.track_event).

Lead Events

When submitting events for Leads, you will need to specify the Lead's id.

HTTP API Responses

  • Successful responses to submitted events return 202 Accepted with an empty body.
  • Unauthorised access will be rejected with a 401 Unauthorized or 403 Forbidden response code.
  • Events sent about users that cannot be found will return a 404 Not Found.
  • Server errors will return a 500 response code and may contain an error message in the body.

Submit an Event

$ curl https://api.intercom.io/events \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H "Content-Type: application/json" -d'
{
  "event_name" : "invited-friend",
  "created_at": 1391691571,
  "user_id" : "314159"
}'

HTTP/1.1 202 Accepted
Intercom('trackEvent', 'invited-friend');
intercom.events.create(event_name: "invited-friend", email: user.email, created_at: 1391691571)
<?php
$intercom->events->create([
    "event_name" => "php-test",
    "created_at" => 1500907513,
    "user_id" => "1276"
]);
?>
Event event = new Event()
  .setEventName("invited-friend")
  .setCreatedAt(1234L)
  .setUserID("314159");

Event.create(event);
Suggest Edits

Event Model

 

Event Object

An Event Object describes the event and contains the following fields

Attribute
Required
Description

event_name

yes

The name of the event that occurred. This is presented to your App's admins when filtering and creating segments - a good event name is typically a past tense 'verb-noun' combination, to improve readability, for example updated-plan.

created_at

yes

The time the event occurred as a UTC Unix timestamp

user_id

yes if no email

Your identifier for the user.

id

yes if no email or user_id.

Your identifier for a lead or a user.

email

yes if no user_id

An email address for your user. An email should only be used where your application uses email to uniquely identify users

metadata

no

optional metadata about the event.

The event_name field is processed as follows -

  • Names are treated as case insensitive - 'Completed-Order' and 'completed-order' will be considered the same event for your application.
  • Periods (.) and dollars ($) in event names are replaced with hyphens. e.g., 'completed.order' will be stored as 'completed-order'.

To avoid confusion we recommend submitting lower case event names that do not contain periods or dollars!

Metadata Object

Please note that it's currently not possible to segment users or message them based on event metadata. for more information on events and metadata please see here

Sending an event with metadata

Metadata can be used to submit an event with extra key value data. Each event can contain up to five metadata key values.

Some use cases for event metadata are -

  • Linking an event back to a page in your website.
  • Describing before and after values for a subscription plan change.
  • Sending contextual information about an online order, a booking.

See the section 'Metadata Types' for more information on the kinds of metadata you can send.

Event Object

{
  "event_name" : "invited-friend",
  "created_at": 1389913941,
  "user_id": "342311"
}
// Sufficient to send just the event name
Intercom('trackEvent', 'invited-friend');
# create an event as a hash
event = {
  :event_name => "invited-friend",
  :email => current_user.email,
  :created_at => 1391691571
}
intercom.events.create event
<?php
$event = array(
  "event_name" => "invited-friend",
  "created_at" => 1391691571,
  "user_id" => "314159"
);
$intercom->events->create($event);
?>
Event event = new Event()
  .setEventName("invited-friend")
  .setUserID("1314159");
  .setCreatedAt(currentTimeMillis()/1000L);

Event.create(event);
$ curl https://api.intercom.io/events \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H "Content-Type: application/json" -d'
{
  "event_name" : "invited-friend",
  "created_at": 1389913941,
  "user_id": "314159",
  "metadata": {
     "invitee_email": "pi@example.org",
     "invite_code": "ADDAFRIEND"
  }
}'
var metadata = {
  invitee_email: 'pi@example.org',
  invite_code: 'ADDAFRIEND'
};
Intercom('trackEvent', 'invited-friend', metadata);
metadata = {
  :invitee_email => 'pi@example.org',
  :invite_code => 'ADDAFRIEND'
}
intercom.events.create {
  :event_name => "invited-friend",
  :email => current_user.email,
  :created_at => 1391691571,
  :metadata => metadata
}
<?php
$metadata = array(
  "invitee_email" => "pi@example.org",
  "invite_code" => "ADDAFRIEND"
);
$intercom->events->create(array(
  "event_name" => "invited-friend",
  "created_at" => 1391691571,
  "user_id" => "314159",
  "metadata" => $metadata
));
?>
Event event = new Event()
  .setEventName("invited-friend")
  .setUserID("314159")
  .putMetadata("invite_mail", "pi@example.org")
  .putMetadata("invite_code", "ADDAFRIEND")
  .putMetadata("found_date", currentTimeMillis()/1000L);

Event.create(event);
Suggest Edits

Event de-duplication

 

The API may detect and ignore duplicate events. Each event is uniquely identified as a combination of the following data - the App identifier, the User identifier, the Event name and the Event created time. As a result, it is strongly recommended to send a second granularity Unix timestamp in the created_at field.

Duplicated events are responded to using the normal 202 Accepted code - an error is not thrown, however repeat requests will be counted against any rate limit that is in place.

Suggest Edits

Event Metadata Types

 

Metadata Objects support a few simple types that Intercom can present on your behalf -

Type
Description
Example

String

The value is a JSON String

"source":"desktop"

Number

The value is a JSON Number

"load": 3.67

Date

The key ends with the String _date and the value is a Unix timestamp, assumed to be in the UTC timezone.

"contact_date": 1392036272

Link

The value is a HTTP or HTTPS URI.

"article": "https://example.org/ab1de.html"

Rich Link

The value is a JSON object that contains url and value keys.

"article": {"url": "https://example.org/ab1de.html", "value":"the dude abides"}

Stripe Data

The key is one of - 'stripe_customer', 'stripe_invoice', 'stripe_charge'. The value is a Stripe identifier.

"stripe_customer": "cus_42424242424"

Monetary Amount

The value is a JSON object that contains amount and currency keys. The amount key is a positive integer representing the amount in cents. The price in the example to the right denotes €349.99.

"price": {"amount": 34999, "currency": "eur"}

API Responses

  • Successful responses to submitted events return 202 Accepted with an empty body.
  • Unauthorised access will be rejected with a 401 Unauthorized or 403 Forbidden response code.
  • Events sent about users that cannot be found will return a 404 Not Found.
  • Event lists containing duplicate events will have those duplicates ignored.
  • Server errors will return a 500 response code and may contain an error message in the body.

Event Metadata Types

$ curl https://api.intercom.io/events \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H "Content-Type: application/json" -d'
{
  "event_name" : "placed-order",
  "created_at": 1389913941,
  "user_id": "314159",
  "metadata": {
    "order_date": 1392036272,
    "stripe_invoice": "inv_3434343434",
    "order_number": {
      "value":"3434-3434",
      "url": "https://example.org/orders/3434-3434"
    },
    "price": {
      "currency":"usd",
      "amount": 2999
    }
  }
}'
var more_metadata = {
  order_date: 1392036272,
  stripe_invoice: 'inv_3434343434',
  order_number: {
    value: "3434-3434",
    url: 'https://example.org/orders/3434-3434'
  },
  price: {
    currency: 'usd',
    amount: 2999
  }
};
Intercom('trackEvent', 'placed-order', more_metadata);
more_metadata = {
  :order_date => Time.now.to_i,
  :stripe_invoice => 'inv_3434343434',
  :order_number => {
    :value => '3434-3434',
    :url => 'https://example.org/orders/3434-3434'
  },
  price: {
    :currency => 'usd',
    :amount => 2999
  }
}
intercom.events.create({
  :event_name => "placed-order",
  :email => current_user.email,
  :created_at => 1391691571,
  :metadata => more_metadata
})
<?php
$metadata = ([
    "order_date" => time(),
    "stripe_invoice" => "inv_3434343434",
    "order_number" => ([
        "value" => "3434-3434",
        "url" => "https://example.org/orders/3434-3434"]),
        "price" => ([
            "currency" => "usd",
            "amount" => 2999])
]);

$intercom->events->create([
    "event_name" => "placed-order",
    "created_at" => 1500907515,
    "user_id" => "20413",
    "metadata" => $metadata
]);
?>
Map<String,Object> order = Maps.newHashMap();
order.put("value", "3434-3434");
order.put("url", "https://example.org/orders/3434-3434");

Map<String,Object> price = Maps.newHashMap();
price.put("currency", "usd");
price.put("amount", 2999);

Map<String,Object> meta = Maps.newHashMap();
meta.put("order_date", currentTimeMillis()/1000L);
meta.put("stripe_invoice", "inv_3434343434");
meta.put("price", price);
meta.put("order_number", order);

Event event = new Event()
  .setEventName("placed-order")
  .setUserID("314159")
  .setMetadata(meta);

Event.create(event);
# The metadata key values in the example
# are treated as follows-
#
# - order_date: a Date
#    (key ends with '_date').
#
# - stripe_invoice: The identifier of the Stripe invoice
#     (has a 'stripe_invoice' key)
#
# - order_number: Rich Link
#     (contains 'url' and 'value')
#
# - price: Amount in US Dollars
#     (contains 'amount' and 'currency')
Suggest Edits

List Events

 

The events belonging to a customer can be listed by sending a GET request to https://api.intercom.io/events with a user or lead identifier along with a type parameter. The identifier parameter can be one of user_id, email or intercom_user_id. The type parameter value must be user.

  • https://api.intercom.io/events?type=user&user_id={user_id}
  • https://api.intercom.io/events?type=user&email={email}
  • https://api.intercom.io/events?type=lead&intercom_user_id={id}

The email parameter value should be url encoded when sending.

You can optionally define the result page size as well with the per_page parameter.

Request Parameters

Parameter
Required
Description

type

yes

The value must be user

user_id

no

The user id you have defined for the user

email

no

The email you have defined for the user

intercom_user_id

no

The Intercom defined id for the user

per_page

no

How many results to return per page defaults to 50.

summary

no

Boolean value. When set to true, event counts are returned grouped by event name.

Returns

A pageable list of events. The event list contains a pages object that indicates if more events exist for the customer via the next field, whose value is a URL that can be used to fetch the next page. If the next field is not present, that indicates there are no further events for the user. Clients should note that the parameters in the returned link are not assured to be the same as those sent in the request.

The event list is sorted by the created_at field and ordered descending, most recently created first.

As well as the fields that were supplied when the event was posted to Intercom (see Event Model for details) the event payload will also contain an id field that uniquely identifies the event and may optionally contain an intercom_user_id containing the Intercom defined id representing the user.

You can use the API to get counts of users, leads and companies filtered by certain criteria.

Counts are a good way to periodically obtain data for the purposes of tracking rates of change in user and company data.

List all customer events

$ curl 'https://api.intercom.io/events?type=user&user_id=314159' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json'
HTTP/1.1 200 OK

{
  "type": "event.list",
  "events": [
      {
        "event_name" : "ordered-item",
        "created_at": 1391691571,
        "user_id" : "314159"
      },
      {
        "event_name" : "invited-friend",
        "created_at": 1389913941,
        "user_id" : "314159",
        "metadata": {
         "invitee_email": "pi@example.org",
         "invite_code": "ADDAFRIEND"
         }
      },
     ...
   ],
  "pages": {
    "next": "https://api.intercom.io/events?type=user&intercom_user_id=55a3b&before=144474756550"
  }
}

# NB: Full event objects are returned
# Not exposed in Ruby client
<?php
$events = $intercom->events->getEvents(["user_id" => "20413"]);
foreach ($events->events as $event) {
    print "id:".$event->id." name:".$event->event_name."\n";
}?>
// Not exposed in Java client
Suggest Edits

View User Event Summaries

 

If you simply want to get a count of the number of different events associated with a user then you can use the 'summary=true' parameter of the events endpoint. This means you do not receive the full list of all users events and just the counts of the different events per user.

Get summary count of user events

$ curl 'https://api.intercom.io/events?type=user&user_id=314159&summary=true' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json'
{
    "type": "event.summary",
    "email": "test-user@example.com",
    "intercom_user_id": "56e1e5d4a40df1cc57000101",
    "user_id": "314159",
    "events": [
        {
            "name": "updated-profile",
            "first": "2016-03-18T10:05:15.000Z",
            "last": "2016-03-18T13:28:38.000Z",
            "count": 5,
            "description": null
        },    
        {
            "name": "purchased-item",
            "first": "2016-09-30T11:39:06.000Z",
            "last": "2016-09-30T11:39:06.000Z",
            "count": 4,
            "description": null
        },
        {
            "name": "subscribed-for-demo",
            "first": "2016-11-24T12:26:34.000Z",
            "last": "2016-11-24T12:26:34.000Z",
            "count": 2,
            "description": null
        }
    ]
}

You can use the API to get counts of users and companies filtered by certain criteria.

Counts are a good way to periodically obtain data for the purposes of tracking rates of change in user and company data.

Suggest Edits

App Total Count Model

 

App Total Count Object

The total count object contains the summary of the following fields in you app -

Attribute
Type
Description

type

string

value is 'count.hash'

company

object

Contains the number of companies in your App

segment

object

Contains the number of segments in your App

tag

object

Contains the number of tags in your App

user

object

Contains the number of users in your App

lead

object

Contains the number of leads in your App

The count of tags and segments includes archived tags and segments.

The counts for your App can be obtained using GET against the https://api.intercom.io/counts URL with the type and count parameters as follows

Count
Type Value
Count Value

Global App Counts

None

None

{
    "type": "count.hash",
    "company": {
        "count": 55
    },
    "user": {
        "count": 54944
    },
    "lead": {
        "count": 17
    },
    "tag": {
        "count": 1012
    },
    "segment": {
        "count": 7
    }
}
# App Counts
$ curl 'https://api.intercom.io/counts' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
# App Total Counts
HTTP/1.1 200 OK

{
    "type": "count.hash",
    "company": {
        "count": 55
    },
    "user": {
        "count": 54944
    },
    "lead": {
        "count": 17
    },
    "tag": {
        "count": 1012
    },
    "segment": {
        "count": 7
    }
}
intercom.counts.for_app
<?php
// Global App Counts
$intercom->counts->getCounts([]);
?>
// Global App Counts
final Counts.Totals appTotals = Counts.appTotals();
appTotals.getCompany().getValue();
appTotals.getSegment().getValue();
appTotals.getTag().getValue();
appTotals.getUser().getValue();
Suggest Edits

Conversation Count Model

 

Conversation Count Object

The conversation count supplies global counts about your App's conversations

Attribute
Type
Description

type

string

value is 'count'

conversation

object

Contains counts related to conversations

conversation.assigned

number

Contains the number of assigned conversations

conversation.closed

number

Contains the number of closed conversations

conversation.open

number

Contains the number of open conversations

conversation.unassigned

number

Contains the number of unassigned conversations

The counts for your App can be obtained using GET against the https://api.intercom.io/counts URL with the type and count parameters as follows

Count
Type Value
Count Value

Conversation Count

conversation

None

{
    "type": "count",
    "conversation": {
        "open": 30,
        "closed": 17,
        "unassigned": 0,
        "assigned": 30
    }
}
# Conversation Counts
$ curl 'https://api.intercom.io/counts?type=conversation' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
# Conversation App Counts
HTTP/1.1 200 OK

{
    "type": "count",
    "conversation": {
        "open": 30,
        "closed": 17,
        "unassigned": 0,
        "assigned": 30
    }
}
intercom.counts.for_type(type: 'conversation')
<?php
$counts = $intercom->counts->getCounts(["type" => "conversation"]);
print_r($counts);
?>
// Conversation Counts
final Counts.Conversation totals = Counts.conversationTotals();
totals.getAssigned();
totals.getClosed();
totals.getOpen();
totals.getUnassigned();
Suggest Edits

Admin Conversations Count Model

 

Admin Conversation Count Object

The admin conversation count supplies per Admin counts

Attribute
Type
Description

type

string

value is 'count'

conversation

object

Contains counts related to admins

conversation.admin

array

Contains and array of objects detailing each Admin

conversation.admin.open

number

Contains the number of open conversations for the Admin

conversation.admin.closed

number

Contains the number of closed conversations for the Admin

conversation.admin.id

string

Contains the Admin id

conversation.admin.name

string

Contains the Admin name

The counts for your App can be obtained using GET against the https://api.intercom.io/counts URL with the type and count parameters as follows

Count
Type Value
Count Value

Conversation Admin Count

conversation

admin

{
  "type": "count",
  "conversation": {
    "admin": [
      {
        "id": "1",
        "name": "Wash",
        "open": 0,
        "closed": 1
      },
      {
        "id": "2",
        "name": "Jayne",
        "open": 0,
        "closed": 0
      }
    ]
  }
}
# Conversation Admin Counts
$ curl 'https://api.intercom.io/counts?type=conversation&count=admin' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
# Conversation Admin Counts
HTTP/1.1 200 OK

{
  "type": "count",
  "conversation": {
    "admin": [
      {
        "id": "1",
        "name": "Wash",
        "open": 0,
        "closed": 1
      },
      {
        "id": "2",
        "name": "Jayne",
        "open": 0,
        "closed": 0
      }
    ]
  }
}
intercom.counts.for_type(type: 'conversation', count: 'admin')
<?php
// Conversation Admin Count
$counts = $intercom->counts->getCounts(["type" => "conversation", "count" => "admin"]);
print_r($counts);
?>
// Conversation Admin Count
final Counts.Conversation counts = Counts.conversationAdmins();
List<Admin> admins = counts.getAdmins();
for (Admin admin : admins) {
    out.println(
      admin.getName() + ": " +
      admin.getClosed() + ", " +
      admin.getOpen());
}
Suggest Edits

User Segment/Tag Count Model

 

The count of tags and segments includes archived tags and segments.

User Segment/Tag Count Object

Count Object includes count for users and leads.

Attribute
Type
Description

type

string

value is 'count'

user

object

Contains a field called segment containing segment counts

user.segment

array

Contains a list of segment counts

user.tag

array

Contains a list of tag counts

The counts for your App can be obtained using GET against the https://api.intercom.io/counts URL with the type and count parameters as follows

Count
Type Value
Count Value

User Segment Count

user

segment

User Tag Count

user

tag

{
  "type": "count",
  "user": {
    "tag": [
        {
          "Independent": 3
        }
    ]
  }
}
{
  "type": "count",
  "user": {
    "segment": [
      {
        "Active": 1
      },
      {
        "New": 0
      },
      {
        "VIP": 0
      },
      {
        "Slipping Away": 0
      },
      {
        "segment 1": 1
      }
    ]
  }
}
# User Tag Count
$ curl 'https://api.intercom.io/counts?type=user&count=tag' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'

# User Segment Count
$ curl 'https://api.intercom.io/counts?type=user&count=segment' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
# User Tag Count
HTTP/1.1 200 OK

{
  "type": "count",
  "user": {
    "tag": [
        {
          "Independent": 3
        }
    ]
  }
}

# User Segment Count
HTTP/1.1 200 OK

{
  "type": "count",
  "user": {
    "segment": [
      {
        "Active": 1
      },
      {
        "New": 0
      },
      {
        "VIP": 0
      },
      {
        "Slipping Away": 0
      },
      {
        "segment 1": 1
      }
    ]
  }
}
intercom.counts.for_type(type: 'user', count: 'tag')
intercom.counts.for_type(type: 'user', count: 'segment')
<?php
// User Tag Count
$counts = $intercom->counts->getCounts(["type" => "user", "count" => "tag"]);
print_r($counts);

// Company Segment Count
$counts = $intercom->counts->getCounts(["type" => "user", "count" => "segment"]);
?>
// User Tag Count
final List<Counts.CountItem> tags = Counts.userTags();
for (Counts.CountItem tag : tags) {
  out.println(tag.getName() + ": " + tag.getValue());
}

// User Segment Count
final List<Counts.CountItem> segments = Counts.userSegments();
for (Counts.CountItem seg : segments) {
  out.println(seg.getName() + ": " + seg.getValue());
}
Suggest Edits

Company User/Segment/Tag Count Model

 

Company User/Segment/Tag Count Object

Attribute
Type
Description

type

string

value is 'count'

company

object

Contains a field called segment containing segment counts

company.segment

array

Contains a list of segment objects their name and their number of companies tagged

company.tag

array

Contains a list of tag objects with their name and their number of companies tagged

company.user

array

Contains an array of companies with their name and their number of users

The counts for your App can be obtained using GET against the https://api.intercom.io/counts URL with the type and count parameters as follows

Count
Type Value
Count Value

Company Segment Count

company

segment

Company Tag Count

company

tag

Company User Count

company

user

Pagination with company counts

Company counts are returned via pagination, which means it defaults to 50 results per page unless you specify otherwise. e.g.
'https://api.intercom.io/counts?type=company&count=tag&per_page=10"

To get the next page of results you need to make a GET request with the "next" RUL supplied in the initial response.

# Company Tag Count
$ curl 'https://api.intercom.io/counts?type=company&count=tag&per_page=5' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'

# Company Segment Count
$ curl 'https://api.intercom.io/counts?type=company&count=segment' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'

# Company User Count
$ curl 'https://api.intercom.io/counts?type=company&count=user' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
# Company Tag Count
HTTP/1.1 200 OK

{
    "type": "count",
    "company": {
        "tag": [
            {
                "VIP": 0
            },
            {
                "UpMarket": 0
            },
            {
                "test": 0
            },
            {
                "new": 0
            },
            {
                "smb": 0
            }
        ]
    },
    "pages": {
        "pages": {
            "type": "pages",
            "next": "https://api.intercom.io/counts?type=company&count=tag&page=2&per_page=5",
            "page": 1,
            "per_page": 5,
            "total_pages": 203
        }
    }
}

# Company Segment Count
HTTP/1.1 200 OK
{
    "type": "count",
    "company": {
        "segment": [
            {
                "Active": 2
            },
            {
                "New": 0
            },
            {
                "Slipping Away": 0
            },
            {
                "id=10": 10
            }
        ]
    },
    "pages": {}
}

# Company User Count
HTTP/1.1 200 OK

{
  "type": "count",
  "company": {
    "user": [
      {
        "Independents": 7,
        "remote_company_id": "6"
      },
      {
        "Alliance": 1,
        "remote_company_id": "7"
      }
    ]
  },
  "pages": {}
}
intercom.counts.for_type(type: 'company', count: 'tag')
intercom.counts.for_type(type: 'company', count: 'segment')
intercom.counts.for_type(type: 'company', count: 'user')
<?php
// Company Tag Count
$counts = $intercom->counts->getCounts(["type" => "company", "count" => "tag"]);
print_r($counts);

// Company User Count
$counts = $intercom->counts->getCounts(["type" => "company", "count" => "user"]);
print_r($counts);

//Company Segment Count
$counts = $intercom->counts->getCounts(["type" => "company", "count" => "segment"]);
print_r($counts);

?>
// Company User Count
final List<Counts.CountItem> users1 = Counts.companyUsers();
for (Counts.CountItem c : users1) {
  out.println(c.getName() + ": " + c.getValue());
}

// Company Tag Count
final List<Counts.CountItem> tags1 = Counts.companyTags();
for (Counts.CountItem tag : tags1) {
  out.println(tag.getName() + ": " + tag.getValue());
}

// Company Segment Count
final List<Counts.CountItem> segments1 = Counts.companySegments();
for (Counts.CountItem seg : segments1) {
 out.println(seg.getName() + ": " + seg.getValue());
}
Suggest Edits

Conversations

 

Conversation are how you can communicate with users in Intercom.

To start a conversation you and your users can send messages. The API supports two ways to start a conversation -

* From a user to you, called a ‘user initiated’ conversation.
* From a team member to a single user called an ‘admin initiated’ conversation.

The API does not currently support sending admin initiated messages to multiple users, creating auto messages or sending from teams, but we’d be interested in hearing your usecases - please contact team@intercom.io.

Once a message has been sent the conversation can begin! Users and Admins can reply to any conversation via the API - see the section “Replying to a Conversation” for details.

The Conversations API is only available to Apps with a trial or an active subscription.

Note

There may be a short delay between user creation and a user becoming available for messaging through the API. A 404 will be returned in this case, and you should retry the request after a delay.

Note

If you try to send an email to a user who has unsubscribed, we will return a 403 and the message "This user is unsubscribed from emails".

Suggest Edits

Conversation Model

 

A conversation lets you track and describe communications with your users. Each conversation contains the message that initiated the conversation, the user involved, the admin assigned to the conversation and a list of parts describing the conversation thread. The open or closed status of the conversation is also provided.

Conversation Object

Attribute
Type
Description

type

string

value is 'conversation'

id

string

The id representing the conversation

created_at

timestamp

The time the conversation was created

updated_at

timestamp

The last time the conversation was updated

waiting_since

timestamp

The last time a customer responded to an admin.
In other words, the time a customer started waiting for a response.

snoozed_until

timestamp

If set this is the time in the future when this conversation will be marked as open.
i.e. it will be in a snoozed state until this time

conversation_message

Message

The message that started the conversation rendered for presentation.

user

User

The user the conversation concerns

customers

List

The list of customers (users or leads) involved in this conversation.
This will only contain one customer unless more were added via the group conversation feature

assignee

Admin

The admin the conversation is currently assigned to.
Note nobody_admin indicates the conversation is assigned to Nobody.

conversation_parts

Object

A conversation part object with a list of conversation parts

open

Boolean

Indicates whether a conversation is open (true) or closed (false)

state

String

Can be set to "open", "closed" or "snoozed".

read

Boolean

Indicates whether a conversation has been read

tags

List

A list of tags associated with the conversation.

total_count

Integer

The number of conversation parts in this conversation.

waiting_since 2000 years in the future?

Waiting since lets you identify how long a customer has been waiting for a response. This time, however, is not always relevant. For example, when the last person to respond was an admin, or the conversation was closed after a user response (e.g. "thanks, bye"). In these cases we will set the date to 2000 years in the future.

Message Object

Attribute
Type
Description

type

string

_value is 'conversation_message'_

id

string

The id representing the message

subject

string

Optional. The message subject

body

string

The message body, which may contain HTML

author

Admin

The Admin that created the message

attachments

List

A list of attachments for the part

url

string

The URL the User started a conversation on

Example Conversation Object

{
  "type": "conversation",
  "id": "147",
  "created_at": 1400850973,
  "updated_at": 1400857494,
  "waiting_since": 1400857494,
  "snoozed_until": null,
  "conversation_message": {
    "type": "conversation_message",
    "subject": "",
    "body": "<p>Hi Alice,</p>\n\n<p> We noticed you using our Product,  do you have any questions?</p> \n<p>- Jane</p>",
    "author": {
      "type": "admin",
      "id": "25"
    },
    "attachments": [
      {
        "name": "signature",
        "url": "http://example.org/signature.jpg"
      }
    ]
  },
  "user": {
    "type": "user",
    "id": "536e564f316c83104c000020"
  },
  "customers": [
    {
      "type": "user",
      "id": "58ff3f670f14ab4f1aa83750"
    }
  ],
  "assignee": {
    "type": "admin",
    "id": "25"
  },
  "open": true,
  "state": "open",
  "read": true,
  "conversation_parts": {
    "type": "conversation_part.list",
    "conversation_parts": [
      //... List of conversation parts
    ],
    "total_count":1
  },
  "tags": { "type": 'tag.list', "tags": [] } 
}
Suggest Edits

Conversation Part Model

 

A conversation part describes an element of the conversation.

A conversation part has a html encoded body, an author, and may have an attachments list. Conversation parts have created, updated and notified timestamps. Each conversation part also has a part type - these types are described below.

Conversation Part Object

Attribute
Type
Description

type

string

The value is 'conversation_part'

id

string

The id representing the conversation part

part_type

string

The type of conversation part

body

string

The html encoded body of the comment

created_at

timestamp

The time the conversation part was created

updated_at

timestamp

The last time the conversation part was updated

notified_at

timestamp

The time the user was notified with the conversation part

assigned_to

string

The id of the admin that the conversation is assigned to (not null only when part_type: assignment).

author

User or Admin

The user or admin that created the part

attachments

List

A list of attachments for the part

There are five possible values for the part_type: comment, note, assignment, open and close:

  * A standard reply from a user or admin to a conversation.
  * Has a body.
  * A note created by an Admin on the conversation.
  * Has a body.
  * Should only be viewable as an Admin.
  * An assignment of the conversation to an Admin, or _Nobody_.
  * Can have a body.
  * Should only be viewable as an Admin.
  * Opens the conversation.
  * Can have a body.
  * Should only be viewable as an Admin.

  * Closes the conversation.
  * Can have a body.
  * Should only be viewable as an Admin.

Example Conversation Part Object

{
    "type": "conversation_part",
    "id": "4412",
    "part_type": "comment",
    "body": "<p>Hi Jane, it's all great thanks!</p>",
    "created_at": 1400857494,
    "updated_at": 1400857494,
    "notified_at": 1400857587,
    "assigned_to": null,
    "author": {
      "type": "user",
      "id": "536e564f316c83104c000020"
    },
    "attachments": []
}
Suggest Edits

Admin Initiated Conversation

 

You can create a new admin initiated message by submitting a POST to https://api.intercom.io/messages along with JSON message.

An admin initiated message can be delivered to a user as an In-App conversation or as an Email. The message_type field is used to determine which, with a value of either inapp or email. For admin initiated In-App messages, they will not trigger push notifications.

Receiving Users are identified by a user_id, id, or email field in the to object.

Receiving Contacts are identified by a user_id or id field in the to object.

The type field for the to object is then set to either contact or user.

The subject field is only used for email type messages and will not be used for inapp message types.

A sending admin must be added using the from field, along with a type field value of admin and the corresponding Intercom id for that admin. The admin's Intercom id value may be obtained from the admin list resource.

Conversation V Message

Note that since creating an admin-initiated conversation hits the /messages endpoint, the response contains a message object rather than a conversation object. As a result you will not see the conversation ID in the returned message object. You may, however, retrieve the customers's conversations and iterate over them looking for the message_id value.

Attributes

Attribute
Type
Description

message_type

string

The kind of message being created. Values: inapp or email

subject

string

Optional unless message_type is email. The title of the email.

body

string

The content of the message. HTML or plaintext.

template

string

The style of the outgoing message. Only valid for email messages. Possible values plain or personal.

from

object

Required. An admin object containing the admin's id. The type field must have a value of admin.

to

object

Required. A user object containing the user's id, email or user_id. The type field must have a value of user or of contact.

Returns

The created message object.

If the from type was supplied with an admin's details, the owner field in the response will represent the admin in question.

Email From Admin

$ curl https://api.intercom.io/messages \
-XPOST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d'
{
  "message_type": "email",
  "subject": "Hey",
  "body": "Ponies, cute small horses or something more sinister?",
  "template": "plain",
  "from": {
    "type": "admin",
    "id": "394051"
  },
  "to": {
    "type": "user",
    "id": "536e564f316c83104c000020"
  }
}'
HTTP/1.1 200 OK

{
  "type": "admin_message",
  "id": "2001",
  "created_at": 1401916877,
  "message_type": "email",
  "subject" : "Hey",
  "body" : "Ponies, cute small horses or something more sinister?",
  "template": "plain",
  "owner": {
    "email": "wash@serenity.io",
    "id": "394051",
    "name": "Wash",
    "type": "admin"
  }
}
intercom.messages.create(
  :message_type => 'email',
  :subject  => 'This Land',
  :body     => "Har har har! Mine is an evil laugh!",
  :template => "plain", # or "personal",
  :from => {
    :type => "admin",
    :id   => "394051"
  },
  :to => {
    :type => "user",
    :id => "536e564f316c83104c000020"
  }
)
<?php
$intercom->messages->create([
    "message_type" => "email",
    "subject" => "Plato Quote",
    "body" => "And what, Socrates, is the food of the soul?",
    "from" => [
        "type" => "admin",
        "id" => "814860"
    ],
    "to" => [
        "type" => "user",
        "email" => "socrates@email.com"
    ]
]);
?>
User user = new User()
  .setId("5310d8e8598c9a0b24000005");
Admin admin = new Admin()
  .setId("394051");
AdminMessage adminMessage = new AdminMessage()
  .setAdmin(admin)
  .setUser(user)
  .setSubject("This Land")
  .setBody("Har har har! Mine is an evil laugh!")
  .setMessageType("email")
  .setTemplate("plain"); // or personal
Conversation.create(adminMessage);
Suggest Edits

User or Contact Initiated Conversation

 

You can create a new user or contact initiated message by submitting a POST to https://api.intercom.io/messages along with a JSON message.

The sending user or contact is identified by their user_id or id (or email if they're a user) values in the from field, along with a type field value of user or contact.

The message_type for a user initiated message is always treated as a inapp and will appear as a conversation inside Intercom. The email message type is not currently supported for a user initiated message.

User initiated messages can not be sent to specific admins, and as such, do not use the to field.

Attributes

Attribute
Type
Description

body

string

The content of the message. Plaintext only, HTML is not supported.

from

object

A user or contact object containing the user's id or user_id (or email if user). The type field must have a value of user or contact.

Returns

The created message object.

User Initiated Message

$ curl https://api.intercom.io/messages \
-XPOST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d'
{
  "from": {
    "type": "user",
    "id": "536e564f316c83104c000020"
  },
  "body": "Hey"
}'
HTTP/1.1 200 OK

{
  "type": "user_message",
  "id": "2001",
  "created_at": 1401917202,
  "body" : "Hey, is the new thing in stock?",
  "message_type": "inapp"
}
intercom.messages.create(
  :from => {
    :type => "user",
    :id => "536e564f316c83104c000020"
  },
  :body => "Hey"
)
<?php
$intercom->messages->create([
    "message_type" => "inapp",
    "body" => "Surely, I said, knowledge is the food of the soul",
    "from" => [
        "type" => "user",
        "id" => "5989303470da497b1babb9ef"
    ]
]);
?>
UserMessage userMessage = new UserMessage()
  .setBody("Hey! Is there, is there a reward?")
  .setUser(user);
Conversation.create(userMessage);
Suggest Edits

Get a Single Conversation

 

Parameters

Specify the id of the conversation you wish to retrieve using the URL https://api.intercom.io/conversations/{id} URL structure where {id} is the id field of the conversation.

Parameter
Required
Description

display_as

no

Set to plaintext to retrieve conversation messages in plain text

Returns

A full Conversation object including Tags, with Conversation Parts.

Parts in the conversation_parts object are ordered by with the most recently created parts appearing at the end of the list.

The maximum number of conversation parts that can be returned via the API is 500. If you have more than that we will return the 500 most recent conversation parts.

Get a Single Conversation

$ curl https://api.intercom.io/conversations/147 \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'

HTTP/1.1 200 OK

{
    "type": "conversation",
    "id": "147",
    "created_at": 1400850973,
    "updated_at": 1400857494,
    "conversation_message": {
      "type": "conversation_message",
      "subject": "",
      "body": "<p>Hi Alice,</p>\n\n<p>We noticed you using our Product, do you have any questions?</p> \n<p>- Jane</p>",
      "author": {
        "type": "admin",
        "id": "25"
      },
      "attachments": [
        {
          "name": "signature",
          "url": "http://someurl.com/signature.jpg"
        }
      ]
    },
    "user": {
      "type": "user",
      "id": "536e564f316c83104c000020"
    },
    "assignee": {
      "type": "admin",
      "id": "25"
    },
    "open": true,
    "read": true,
    "conversation_parts": {
      "type": "conversation_part.list",
      "conversation_parts": [
        //... List of conversation parts
      ]
    },
    "tags": { "type": 'tag.list', "tags": [] } }
}
intercom.conversations.find(:id => '147')
<?php
$intercom->conversations->getConversation("10957850396");
?>
Conversation conversation = Conversation.find("147");

ConversationMessage message =
  conversation.getConversationMessage();

ConversationPartCollection parts =
  conversation.getConversationPartCollection();

List<ConversationPart> list = parts.getPageItems();

for (ConversationPart part : list) {
  String partType = part.getPartType();
  Author author = part.getAuthor();
  String body = part.getBody();
}

ConversationPart recent =
  conversation.getMostRecentConversationPart();

Admin assignee =
  conversation.getAssignee();

User user =
  conversation.getUser();
Suggest Edits

Replying to a Conversation

 

Arguments

For a User Reply:

Argument
Required
Description

type

Yes

user

message_type

Yes

Must be comment

body

Yes

The text body of the comment

intercom_user_id

one of

The Intercom defined id representing the user

user_id

one of

The user id you have defined for the user

email

one of

The email you have defined for the user

attachment_urls

No

A list of URLs of (image only) files that will be added as attachments. You can include up to 5 attachments.

or for an Admin Reply:

Argument
Required
Description

type

Yes

admin

message_type

Yes

Must be comment, assignment, open, close, or note

admin_id

Yes

The id of the Admin who is authoring the comment

body

No

The text body of the comment. Must be set for comment and note

assignee_id

No

Assignments only: assigns the conversation to the given admin id. Note this must be "0" if you want to move it to unassigned

attachment_urls

No

A list of URLs of files that will be added as attachments. You can include up to 5 attachments..

Notes are not visible to the end user.

Returns

A full Conversation object, with Conversation Parts.

Reply with and Without Attachments

#Reply without attachment
$ curl https://api.intercom.io/conversations/147/reply \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json' \
-H 'Content-Type:application/json' -d'
{
  "intercom_user_id": "536e564f316c83104c000020",
  "body": "Thanks again :)",
  "type": "user",
  "message_type": "comment"
}'



#Reply with attachment
$ curl https://api.intercom.io/conversations/147/reply \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json' \
-H 'Content-Type:application/json' -d'
{
  "intercom_user_id": "536e564f316c83104c000020",
  "body": "Thanks again :)",
  "type": "user",
  "message_type": "comment",
  "attachment_urls": ["http://www.example.com/attachment.jpg"]
}'
HTTP/1.1 200 OK

{
    "type": "conversation",
    "id": "147",
    # ...
}
# NB: Full Conversation Object returned
#Reply without attachment
intercom.conversations.reply(:id => conversation.id, :type => 'user', 
  :email => 'bob@example.com', :message_type => 'comment', :body => 'foo')

#Reply with attachment
intercom.conversations.reply(:id => conversation.id, :type => 'user', 
  :email => 'bob@example.com', :message_type => 'comment', 
  :body => 'foo', :attachment_urls => ["http://www.example.com/attachment.jpg"])
<?php
//Reply without attachment
$intercom->conversations->replyToConversation("10957850396", [
    "intercom_user_id" => "5977303470ab497b1babb9ef",
    "body" => "Thinking: the talking of the soul with itself",
    "type" => "user",
    "message_type" => "comment"
]);


//Reply with attachment
$intercom->conversations->replyToConversation("10957850396", [
  "intercom_user_id" => "5977303470ab497b1babb9ef",
  "body" => "Thinking: the talking of the soul with itself",
  "type" => "user",
  "message_type" => "comment",
  "attachment_urls" => ["http://www.example.com/attachment.jpg"]
]);
?>
User user = new User().setId("5310d8e8598c9a0b24000005");
UserReply userReply = new UserReply(user);
userReply.setBody("Mighty fine shindig");

Conversation.reply("66", userReply);

Admin admin = new Admin().setId("1");
AdminReply adminReply = new AdminReply(admin);
adminReply.setBody("These apples are healthsome");

Conversation.reply("66", adminReply);
Suggest Edits

Replying to Users Last Conversation

 

Instead of specifying a conversation id when replying, you can also reply to the most recent conversation for a user at https://api.intercom.io/conversations/last/reply:

Replying to the Users Most Recent Conversation

# Send a reply from admin 1234 to a user's last conversation
$ curl https://api.intercom.io/conversations/last/reply \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json' \
-H 'Content-Type:application/json' -d'
{
  "intercom_user_id": "536e564f316c83104c000020",
  "body": "Let me know if you have any more questions!",
  "type": "admin",
  "admin_id": "1234",
  "message_type": "comment"
}'
<?php

$intercom->conversations->replyToLastConversation([
    "intercom_user_id" => "5977303470ab497b1babb9ef",
    "body" => "I am the wisest man alive, for I know one thing, and that is that I know nothing.",
    "type" => "user",
    "message_type" => "comment"
]);
?>
Suggest Edits

Assigning a Conversation to Unassigned

 

You can assign a conversation to be unassigned when you reply to a conversation. You should do this if you do not want the conversation to remain in your own inbox. This will allow other people pick up the conversation when the user replies to it

Assign to Unassigned

#Assign converstion to unassigned
curl https://api.intercom.io/conversations/6167678340/reply \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json' \
-H 'Content-Type:application/json' -d'
{
  "body": "Reassigning to no-one!",
  "type": "admin",
  "id": "6167678340",
  "admin_id": "1234",
  "assignee_id": "0",
  "message_type": "assignment"
}'
#Assign converstion to unassigned  
intercom.conversations.reply({
  :id => '10289052666', 
  :type => 'admin',
  :admin_id => "1234",
  :assignee_id => 0,
  :message_type => 'assignment', 
  :body => 'reassigning to no-one!'
})
<?php
$intercom->conversations->replyToConversation("10957850396", [
    "intercom_user_id" => "5977303470ab497b1babb9ef",
    "body" => "Reassigning to no-one, i.e. unassigned", // appears as note
    "type" => "admin",
    "admin_id" => "814860",
    "message_type" => "assignment",
    "assignee_id" => "0" 
]);
?>
Suggest Edits

Marking a Conversation as Read

 

You can mark a conversation within Intercom as read.

Mark a Conversation as Read

$ curl https://api.intercom.io/conversations/147 \
-X PUT \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json' \
-H 'Content-Type:application/json' -d'
{
  "read": true
}'
HTTP/1.1 200 OK

{
  "type": "conversation",
  "id": "147",
  "created_at": 1400850973,
  "updated_at": 1400857494,
  "read": true
  # ...
}

# NB: Full Conversation Object returned
conversation.read = true
intercom.conversations.save(conversation)
<?php
$intercom->conversations->markConversationAsRead("10957850396");
?>
Admin admin = new Admin().setId("1");
AdminReply adminReply = new AdminReply(admin);
adminReply.setMessageType("close");
Conversation.reply("66", adminReply);
Suggest Edits

Adding to group conversations

 

customers

Note that customers refers to both users and leads.

Customers can be added to a conversation via a POST method to https://api.intercom.io/conversations/{convo_id}/customers/, which accepts a JSON object describing the customer.

Arguments

Argument
Required
Description

admin_id

Yes

You must provide the ID of a valid admin to add a customer to the conversation

customer

Yes

This is a list of one or more customers that you want to add to the conversation. For each customer you can specify one of the following params to identify the customer to add to the conversation.

intercom_user_id

one of

The Intercom defined id representing the user (in the URL)

user_id

one of

The user id you have defined for the user (or auto defined in the case of leads)

email

one of

The email you have defined for the user

Note about customers without an email

If you try to add a customer via intercom_user_id or user_id which does not have an email you will receive an error. Alternatively, If you add a customer via the email parameter and there is no user/lead in the system for that customer then we will create a new lead.

Adding a customer to a group conversation

$ curl 'https://api.intercom.io/conversations/11055118659/customers' \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json' \
-H 'Content-Type:application/json' -d'
{
  "admin_id": "781236",
  "customer":{
    "intercom_user_id": "58c1c78946a0aa9ef45b098a"
  }
}'
HTTP/1.1 200 OK

{"customers":[
  {"type":"user","id":"597f02cb22f4bb37597e0b7d"}, 
  {"type":"lead","id":"58ff3f670f14ab4f1aa83750"}]
}
Suggest Edits

Deleting from group conversations

 

customers

Note that customers refers to both users and leads.

Customers can be removed from a conversation via a DELETE method to https://api.intercom.io/conversations/{convo_id}/customers/{id}, which accepts a JSON object describing the customer.

Arguments

Argument
Required
Description

admin_id

Yes

You must provide the ID of a valid admin to add a customer to the conversation

Adding a customer to a group conversation

$ curl 'https://api.intercom.io/conversations/11055118659/customers/58c1c72246a0aa9ef45a098e' \
-X DELETE \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json' \
-H 'Content-Type:application/json' -d'
{
  "admin_id": "781345"
}'
HTTP/1.1 200 OK

{"customers":[
  {"type":"user","id":"597f02cb22f4bb37597e0b7d"}]
}x§
Suggest Edits

Snoozing a conversation

 

Customers can snooze a conversation via a POST method to https://api.intercom.io/conversations/{convo_id}/reply/, which accepts a JSON object identifying the time you want the conversation snoozed until.

Arguments

Argument
Required
Description

admin_id

Yes

Only admins can snooze a conversation so you need to provide the admin_id

message_type

Yes

Must be snoozed

snooze_until

Yes

The time in Unix time (i.e. seconds) you want the conversation to reopen

Snooze a conversation

$ curl 'https://api.intercom.io/conversations/11055118659/reply' \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json' \
-H 'Content-Type:application/json' -d'
{
  "admin_id": "724860",
  "message_type":"snoozed",
  "snoozed_until":"1501512795"
}'
{
    "type": "conversation",
    "id": "11055118659",
    "created_at": 1501496012,
    "updated_at": 1501508752,
    "waiting_since": 1501498931,
    "snoozed_until": null,
    "conversation_message": {
        "type": "conversation_message",
        "id": "55951247",
        "subject": "",
        "body": "<p>Hi \ud83d\ude00 We hope you enjoy the example app. To get started just copy and paste some code into the JS editor. Let us know if you think this is useful? <br></p>",
        "author": {
            "type": "admin",
            "id": "724865"
        },
        "attachments": [],
        "url": null
    },
    "user": {
        "type": "lead",
        "id": "597f02cb22f4bb37597e0b7d"
    },
    "customers": [
        {
            "type": "lead",
            "id": "597f02cb22f4bb37597e0b7d"
        },
        {
            "type": "user",
            "id": "58ff3f670f14ab4f1aa83750"
        }
    ],
    "assignee": {
        "type": "admin",
        "id": "724860"
    },
    "conversation_parts": {
        "type": "conversation_part.list",
        "conversation_parts": [
            {
                "type": "conversation_part",
                "id": "712337945",
                "part_type": "comment",
                "body": "<p>test convo 1</p>",
                "created_at": 1501496025,
                "updated_at": 1501496025,
                "notified_at": 1501496025,
                "assigned_to": null,
                "author": {
                    "type": "user",
                    "id": "597f02cb22f4bb37597e0b7d"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712338024",
                "part_type": "comment",
                "body": "<p>TestApp typically replies in a few hours. Don\u2019t miss their reply.</p>",
                "created_at": 1501496028,
                "updated_at": 1501496028,
                "notified_at": 1501496028,
                "assigned_to": null,
                "author": {
                    "type": "bot",
                    "id": "815309"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712338089",
                "part_type": "comment",
                "body": "<p></p><p>Get notified by email</p>",
                "created_at": 1501496030,
                "updated_at": 1501496030,
                "notified_at": 1501496031,
                "assigned_to": null,
                "author": {
                    "type": "bot",
                    "id": "815309"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712344562",
                "part_type": "comment",
                "body": "<p>group test two</p>",
                "created_at": 1501496290,
                "updated_at": 1501496290,
                "notified_at": 1501496291,
                "assigned_to": {
                    "type": "admin",
                    "id": "724860"
                },
                "author": {
                    "type": "admin",
                    "id": "724860"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712383990",
                "part_type": "participant_added",
                "body": null,
                "created_at": 1501497831,
                "updated_at": 1501497831,
                "notified_at": 1501497832,
                "assigned_to": null,
                "author": {
                    "type": "admin",
                    "id": "724860"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712411349",
                "part_type": "participant_added",
                "body": null,
                "created_at": 1501498885,
                "updated_at": 1501498885,
                "notified_at": 1501498885,
                "assigned_to": null,
                "author": {
                    "type": "admin",
                    "id": "724860"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712412506",
                "part_type": "comment",
                "body": "<p>group test</p>",
                "created_at": 1501498931,
                "updated_at": 1501498931,
                "notified_at": 1501498932,
                "assigned_to": null,
                "author": {
                    "type": "user",
                    "id": "597f02cb22f4bb37597e0b7d"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712425169",
                "part_type": "participant_removed",
                "body": null,
                "created_at": 1501499414,
                "updated_at": 1501499414,
                "notified_at": 1501499414,
                "assigned_to": null,
                "author": {
                    "type": "admin",
                    "id": "724860"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712728293",
                "part_type": "snoozed",
                "body": null,
                "created_at": 1501508752,
                "updated_at": 1501508752,
                "notified_at": 1501508752,
                "assigned_to": null,
                "author": {
                    "type": "admin",
                    "id": "724860"
                },
                "attachments": [],
                "external_id": null
            }
        ],
        "total_count": 9
    },
    "open": true,
    "state": "snoozed",
    "read": false,
    "tags": {
        "type": "tag.list",
        "tags": []
    }
}
Suggest Edits

Unsnoozing a conversation

 

Arguments

Argument
Required
Description

admin_id

Yes

Only admins can snooze a conversation so you need to provide the admin_id

message_type

Yes

Must be open to re-open or 'unsnooze' the conversation

Snooze a conversation

$ curl 'https://api.intercom.io/conversations/11055118659/reply' \
-X POST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json' \
-H 'Content-Type:application/json' -d'
{
  "admin_id": "814860",
  "message_type":"open"
}'
{
    "type": "conversation",
    "id": "11055118659",
    "created_at": 1501496012,
    "updated_at": 1501508752,
    "waiting_since": 1501498931,
    "snoozed_until": null,
    "conversation_message": {
        "type": "conversation_message",
        "id": "55951247",
        "subject": "",
        "body": "<p>Hi \ud83d\ude00 We hope you enjoy the example app. To get started just copy and paste some code into the JS editor. Let us know if you think this is useful? <br></p>",
        "author": {
            "type": "admin",
            "id": "724865"
        },
        "attachments": [],
        "url": null
    },
    "user": {
        "type": "lead",
        "id": "597f02cb22f4bb37597e0b7d"
    },
    "customers": [
        {
            "type": "lead",
            "id": "597f02cb22f4bb37597e0b7d"
        },
        {
            "type": "user",
            "id": "58ff3f670f14ab4f1aa83750"
        }
    ],
    "assignee": {
        "type": "admin",
        "id": "724860"
    },
    "conversation_parts": {
        "type": "conversation_part.list",
        "conversation_parts": [
            {
                "type": "conversation_part",
                "id": "712337945",
                "part_type": "comment",
                "body": "<p>test convo 1</p>",
                "created_at": 1501496025,
                "updated_at": 1501496025,
                "notified_at": 1501496025,
                "assigned_to": null,
                "author": {
                    "type": "user",
                    "id": "597f02cb22f4bb37597e0b7d"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712338024",
                "part_type": "comment",
                "body": "<p>TestApp typically replies in a few hours. Don\u2019t miss their reply.</p>",
                "created_at": 1501496028,
                "updated_at": 1501496028,
                "notified_at": 1501496028,
                "assigned_to": null,
                "author": {
                    "type": "bot",
                    "id": "815309"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712338089",
                "part_type": "comment",
                "body": "<p></p><p>Get notified by email</p>",
                "created_at": 1501496030,
                "updated_at": 1501496030,
                "notified_at": 1501496031,
                "assigned_to": null,
                "author": {
                    "type": "bot",
                    "id": "815309"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712344562",
                "part_type": "comment",
                "body": "<p>group test two</p>",
                "created_at": 1501496290,
                "updated_at": 1501496290,
                "notified_at": 1501496291,
                "assigned_to": {
                    "type": "admin",
                    "id": "724860"
                },
                "author": {
                    "type": "admin",
                    "id": "724860"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712383990",
                "part_type": "participant_added",
                "body": null,
                "created_at": 1501497831,
                "updated_at": 1501497831,
                "notified_at": 1501497832,
                "assigned_to": null,
                "author": {
                    "type": "admin",
                    "id": "724860"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712411349",
                "part_type": "participant_added",
                "body": null,
                "created_at": 1501498885,
                "updated_at": 1501498885,
                "notified_at": 1501498885,
                "assigned_to": null,
                "author": {
                    "type": "admin",
                    "id": "724860"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712412506",
                "part_type": "comment",
                "body": "<p>group test</p>",
                "created_at": 1501498931,
                "updated_at": 1501498931,
                "notified_at": 1501498932,
                "assigned_to": null,
                "author": {
                    "type": "user",
                    "id": "597f02cb22f4bb37597e0b7d"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712425169",
                "part_type": "participant_removed",
                "body": null,
                "created_at": 1501499414,
                "updated_at": 1501499414,
                "notified_at": 1501499414,
                "assigned_to": null,
                "author": {
                    "type": "admin",
                    "id": "724860"
                },
                "attachments": [],
                "external_id": null
            },
            {
                "type": "conversation_part",
                "id": "712728293",
                "part_type": "snoozed",
                "body": null,
                "created_at": 1501508752,
                "updated_at": 1501508752,
                "notified_at": 1501508752,
                "assigned_to": null,
                "author": {
                    "type": "admin",
                    "id": "724860"
                },
                "attachments": [],
                "external_id": null
            }
        ],
        "total_count": 9
    },
    "open": true,
    "state": "snoozed",
    "read": false,
    "tags": {
        "type": "tag.list",
        "tags": []
    }
}
Suggest Edits

List Conversations

 

Extended Scope Required

You will receive a 401 token_unauthorized response when requesting to list conversations with a standard access token.

You must request extended access tokens.

Conversation lists do not contain a conversation_parts or tags Object, for brevity. The part list for an individual conversation can be fetched when retrieving the conversation itself.

All Conversations

To fetch a list of all conversations send a GET request to https://api.intercom.io/conversations with no parameters. A Conversation List object is returned.

Conversations can be sorted with the following parameters:

Parameter
Required
Description

order

no

asc or desc. Return the conversations in ascending or descending order. defaults to desc.

sort

no

what field to sort the results by. Valid values: created_at, updated_at, waiting_since. defaults to updated_at.

Where'd my conversations go?

When sorting by waiting_since, not all conversations are returned. If a teammate was the last person to reply, or the conversation is closed then those conversations will not show up on this list. This is to ensure you have an easy way of identifying and prioritizing those customers who have been waiting longest.

Ordering and sorting with filters

It should be noted that the format for ordering and sorting is different when listing conversations for customers and admins as opposed to listing all conversations (i.e. without any filters). When you are using filters such as admin/customers 'order' refers to the fields you want to order the list by and 'sort' refers to whether you want it sorted asc or desc. The reverse is true when listing conversation without any filtering

Conversations by Admin

You can send the following parameters to view a single Admin's conversations -

Parameter
Required
Description

type

yes

The type of entity to query for. Value must be admin for admin queries.

admin_id

yes

The id for the Admin whose conversations to retrieve. To retrieve all unassigned conversations, set the id to be 'nobody'.

open

no

Boolean, when true fetches just open conversations, when false just closed conversations

display_as

no

Set to plaintext to retrieve conversation messages in plain text

pages

no

Optional. A pagination object, which may be empty, indicating no further conversations to fetch.

order

no

what field to sort the results by. Valid values: created_at, updated_at, waiting_since. defaults to updated_at.

sort

no

asc or desc. Return the conversations in ascending or descending order. defaults to desc.

Conversations by Customers

You can send the following parameters to view a single Customer's conversations -

Parameter
Required
Description

type

yes

The type of entity to query for. Value must be user.

intercom_user_id

one of

The id of the User whose conversations to retrieve

user_id

one of

Your user_id for the user

email

one of

Your email for the user

unread

no

Boolean, when true fetches just unread conversations

display_as

no

Set to plaintext to retrieve conversation messages in plain text

pages

no

Optional. A pagination object, which may be empty, indicating no further conversations to fetch.

order

no

what field to sort the results by. Valid values: created_at, updated_at, waiting_since. defaults to updated_at.

sort

no

asc or desc. Return the conversations in ascending or descending order. defaults to desc.

When querying the conversations for a particular User, we carry out message matching for that User and your existing Auto Messages, at most once per 15 minutes.

Note: You can list leads by setting the type to user and using the intercom_user_id identifier.

List Open Conversations for a Particular Admin

$ curl \
"https://api.intercom.io/conversations?type=admin&admin_id=25&open=true" \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
  "type": "conversation.list",
  "conversations": [
    {
      "type": "conversation",
      "id": "147",
      "created_at": 1400850973,
      "updated_at": 1400857494,
      "user": {
        "type": "user",
        "id": "536e564f316c83104c000020"
      },
      "assignee": {
        "type": "admin",
        "id": "25"
      },
      "conversation_message": {
        "type": "conversation_message",
        "subject": "",
        "body": "<p>Hi Alice,</p>\n\n<p>We noticed you using our Product, do you have any questions?</p> \n<p>- Jane</p>",
        "author": {
          "type": "admin",
          "id": "25"
        },
        "attachments": [
          {
            "name": "signature",
            "url": "http://someurl.com/signature.jpg"
          }
        ]
      }
    }
  ]
}
intercom.conversations.find_all(:type => 'admin', :id => 25, :open => true)
<?php
$intercom->conversations->getConversations([
    "type" => "admin",
    "admin_id" => "891290",
    "open" => false
]);
?>
Map<String, String> params = Maps.newHashMap();
params.put("type", "admin");
params.put("admin_id", "1");
ConversationCollection conversations = Conversation.list(params);
while (conversations.hasNext()) {
  Conversation conversation = conversations.next();
}
Suggest Edits

Sorting by customer waiting time

 

This will enable you to sort your conversations by the customers who have been waiting the longest. Note that if a teammate was the last person to reply, or the conversation is closed then those conversations will not show up on this list. This is to ensure you have an easy way of identifying and prioritizing open conversations where a customer was the last person to respond.

Sort conversation by waiting_since

$ curl 'https://api.intercom.io/conversations?order=waiting_since&sort=desc' \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json' 
{
    "type": "conversation.list",
    "pages": {
        "type": "pages",
        "next": "https://api.intercom.io/conversations?order=waiting_since&sort=desc&per_page=20&page=2
",
        "page": 1,
        "per_page": 20,
        "total_pages": 30
    },
    "conversations": [
        {
        ....
        ....
        ....
        conversation list
        ....
        ....
        ....
                        },
                "attachments": [],
                "url": null
            },
            "open": true,
            "state": "open",
            "read": true
        }
    ]
}
Suggest Edits

Closing a conversation

 

You can close a conversation with or without a reply once you set the message to close: "message_type":"close".

Closing a Conversation Without Reply

curl https://api.intercom.io/conversations/xxx/reply
-X POST
-H 'Authorization:Bearer <Your access token>'
-H 'Accept:application/json'
-H 'Content-Type:application/json'
-d '{ "admin_id": CLOSING_ADMIN_ID, "message_type": "close", "type": "admin"}'
<?php

$intercom->conversations->replyToConversation("10957850396", [
    "type" => "admin",
    "admin_id" => "814860",
    "message_type" => "close"
]);
?>


Closing a Conversation With Reply

curl https://api.intercom.io/conversations/xxx/reply
-X POST
-H 'Authorization:Bearer <Your access token>'
-H 'Accept:application/json'
-H 'Content-Type:application/json'
-d '{ "body":"closing this convo", "admin_id": CLOSING_ADMIN_ID, "message_type": "close", "type": "admin"}'
<?php

$convo = $intercom->conversations->replyToConversation("10957850396", [
    "body" => "The beginning is the most important part of the work, but this is the end ... of the conversation!",
    "type" => "admin",
    "admin_id" => "814860",
    "message_type" => "close"
]);
?>
Suggest Edits

Webhooks and Notifications

 

You can use webhooks to receive notifications, such as conversation replies, and users being created. Notifications are grouped into topics which can be subscribed to.

The main concepts for the webhook API are subscriptions, topics, notifications and services.

Subscriptions

A Webhook subscription lets you register a URL which will have notifications posted to it. A webhook can be created via the API as described in the section “Manage Subscriptions”, or through your dashboard in the developer hub. Subscriptions can request notifications are sent with a signed verification. Each subscription also has a set of activity feeds described in “Subscription Feeds

Topics

A subscription will contain one or more topics. Topics can also have a sub topic - for example the topic user.created has a main topic of user and subtopic of created. Subscribing to a main topic will subscribe the webhook to all its sub-topics.

Notifications

The object delivered to a webhook is a notification. Notifications have payloads, which contain the API’s existing JSON objects, such as user or conversations.

Services

Services allow you to have notifications sent to another service or application, such as Slack or Hipchat, with the notification formatted for that service. Services are configured and managed via your App’s settings in Intercom, or through the service provider’s settings.

The API currently only accepts subscriptions for the web service type, for general webhooks. You can see the available services here. Please note that some services may only provide a subset of the topics described here.

Suggest Edits

Subscription Model

 

Subscriptions are how you can set up webhook notifications for your App.

Subscription Object

A subscription object contains the following fields -

Attribute
Type
Description

type

string

_value is 'notification_subscription'_

id

string

The Intercom defined id representing the subscription.

created_at

timestamp

The time the subscription was added to Intercom

updated_at

timestamp

The last time the subscription was updated

url

string

The url the notification should be sent to. Required depending on the service type.

service_type

string

The type of the service being called. Default is web for a plain webhook, which is the only accepted value currently.

topics

array

An array of topics to subscribe to.

active

boolean

Indicates whether the subscription is currently active.

hub_secret

string

Optional key used to sign notifications.

metadata

object

Required for event.created webhooks.

Example Subscription Object

{
  "type": "notification_subscription",
  "id": "nsub_6ab4c480-fd8b-11e3-958f-c779cae3e1b3",
  "created_at": 1392731331,
  "updated_at": 1392731331,
  "service_type": "web",
  "topics": ["company", "conversation.user.created"],
  "url": "https://example.org/hooks/1",
  "active": true,
  "hub_secret": "7fa38fa4e7120189f631a6769dd4876b"
}
Suggest Edits

Notification Model

 

Notification Object

Example Notification Object

A notification object contains the following fields -

Attribute
Type
Description

type

string

_value is 'notification_event'_

id

string

The Intercom defined id representing the notification.

self

string

The Intercom defined URL for the subscription. Optional

created_at

timestamp

The timestamp the notification was created.

topic

string

Corresponds to a topic, eg 'company.created', 'conversation.assigned'

delivery_attempts

number

The number of times this notification has been attempted.

first_sent_at

timestamp

The first time the delivery was attempted.

data

object

A container for the data associated with the notification.

data.item

object

The data associated with the notification, which will have a 'type' field.

The contents of data.item object will be defined according to its type field. In the example to the right, the type value of company indicates a company object.

{
  "type": "notification_event",
  "topic": "company.created",
  "id": "notif_ccd8a4d0-f965-11e3-a367-c779cae3e1b3",
  "created_at": 1392731331,
  "delivery_attempts": 1,
  "first_sent_at": 1392731392,
  "data": {
    "item": {
      "type": "company",
      "id": "531ee472cce572a6ec000006",
      "name": "Blue Sun",
      "company_id": "6",
      "remote_created_at": 1394531169,
      "created_at": 1394533506,
      "updated_at": 1396874658,
      "custom_attributes": {
      }
    }
  }
}

The following topics and sub-topics can be subscribed to. The 'Item Type' column shows the API type that will be sent as the data of the Notification (for more information on API types, see "API Summary" in the Intercom API documentation.

Topic
Item Type
Description

conversation.user.created

Conversation

Subscribe to user and lead initiated messages

conversation.user.replied

Conversation

Subscribe to user conversation replies

conversation.admin.replied

Conversation

Subscribe to admin conversation replies

conversation.admin.single.created

Conversation

Subscribe to admin initiated 1:1 conversation

conversation.admin.assigned

Conversation

Subscribe to admin conversation assignments

conversation.admin.noted

Conversation

Subscribe to admin conversation notes

conversation.admin.closed

Conversation

Subscribe to admin conversation closes

conversation.admin.opened

Conversation

Subscribe to admin conversation opens

user.created

User

Subscribe to user creations

user.deleted

User

Subscribe to user deletions. Not sent for bulk deletions.

user.unsubscribed

User

Subscribe to user unsubscriptions from email

user.email.updated

User

Subscribe to user's email address being updated

user.tag.created

UserTag

Subscribe to users being tagged. Not sent for bulk tagging.

user.tag.deleted

UserTag

Subscribe to users being untagged

contact.created

Lead

Subscribe to Lead creations

contact.signed_up

Lead

Subscribe to Leads converting to a User

contact.added_email

Lead

Subscribe to Leads adding email

visitor.signed_up

Visitor

Subscribe to visitors converting to a User

company.created

Company

Subscribe to company creations

event.created

Event

Subscribe to events (Beta!)

ping

Ping

Sent when a post to the Subscription's ping resource is received, or periodically by Intercom. Ping is always subscribed to.

  • The UserTag object is specific to webhooks - see "User Tag Object" for a description.
  • On the Intercom site, bulk user tagging operations do not trigger webhooks and only single user tag operations will result in a webhook being sent.
Suggest Edits

Manage Subscriptions

 

Create a Subscription

You can create a new subscription by submitting a POST to https://api.intercom.io/subscriptions along with the JSON for the subscription. A maximum of 250 subscriptions can be created through the API.

Attribute
Type
Description

service_type

string

The type of the service being called. Default is web for a plain webhook, which is the only accepted value currently. Defaults to web if not sent.

url

string

Required. The url the event should be sent to. Required depending on the service type.

topics

array

Required. An array of topics to subscribe to.

hub_secret

string

Optional. A key used to sign notifications.

The response will contain the id of the subscription.

The ping topic is always subscribed to and cannot be unsubscribed from. The API may send a ping event during or soon after creation. By default the subscription is treated as active.

Create a Subscription in Developer Hub Dashboard

You can create webhooks via the Dashboard in the Developer Hub. To create (and manage) a webhook, you can go to the 'Webhooks' section of this dashboard.

$ curl https://api.intercom.io/subscriptions \
-XPOST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d'
{
  "service_type": "web",
  "topics": ["conversation.admin.replied", "user.created"],
  "url": "https://example.org/hooks/1"
}'
HTTP/1.1 200 Ok

{
  "type": "notification_subscription",
  "id": "nsub_6ab4c480-fd8b-11e3-958f-c779cae3e1b3",
  "created_at": 1392731331,
  "updated_at": 1392731331,
  "service_type": "web",
  "topics": ["conversation.admin.assigned", "company.created"],
  "url": "https://example.org/hooks",
  "active": true,
  "hub_secret": null
}
Subscription sub = new Subscription();
sub.setUrl(new URI("https://example.org/webhooks/1"));
sub.addTopic(Subscription.Topic.USER_CREATED);
sub.addTopic(Subscription.Topic.USER_TAG_CREATED);
sub.addTopic(Subscription.Topic.COMPANY);
sub.setAppID("pi3243fa:");

Subscription.create(sub);
Suggest Edits

View a Subscription

 

Each subscription object has its own URL -

  • https://api.intercom.io/subscriptions/{id}

Where {id} is the value of the subscriptions's id field. Subscriptions may also have a self field containing the URL to be used.

Update a Subscription

Example Update Request

You can update a subscription's topics, active status and url, by submitting a POST to the subscription's URL, along with the JSON for the subscription. The topics, url, active and hub_secret fields can be updated.

The topics array sent during an update will replace the existing list of topics and is not merged. For example if the subscription is susbcribed to the topics ["company", "users"] and is updated with the list ["conversation", "company"], the final result will be ["conversation", "company"] and the users topic will be unsubscribed from.

Setting the active status to false means the subscription will stop receiving events. Note that events triggered when a subscription is inactive may not be sent when the subscription is later re-activated.

Delete a Subscription

Example Delete Subscription Request

A subscription can be deleted by sending a DELETE request to its URL.

Example Request

$ curl \
-s https://api.intercom.io/subscriptions/nsub_6ab4c480-fd8b-11e3-958f-c779cae3e1b3 \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept:application/json'
HTTP/1.1 200 OK

{
  "type": "notification_subscription",
  "id": "nsub_6ab4c480-fd8b-11e3-958f-c779cae3e1b3",
  "created_at": 1392731331,
  "updated_at": 1392731331,
  "service_type": "web",
  "topics": ["conversation", "company"],
  "url": "https://example.org/hooks",
  "active": true,
  "hub_secret": null
}
Subscription sub = Subscription.find("nsub_60ca7690");
$ curl -XPOST \
https://api.intercom.io/subscriptions/nsub_6ab4c480-fd8b-11e3-958f-c779cae3e1b3 \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d'
{
  "topics": ["conversation", "company", "users"],
  "url": "https://example.org/hooks/1"
}'
HTTP/1.1 200 Ok

{
  "type": "notification_subscription",
  "id": "nsub_6ab4c480-fd8b-11e3-958f-c779cae3e1b3",
  "created_at": 1392731331,
  "updated_at": 1392732945,
  "service_type": "web",
  "topics": ["conversation", "company", "user"],
  "url": "https://example.org/hooks/1"
  "active": true,
  "hub_secret": null
}
Subscription sub = Subscription.find("nsub_60ca7690");
sub.setUrl(new URI("https://example.org/webhooks/2"));
Subscription.update(sub);
$ curl https://api.intercom.io/subscriptions/nsub_6ab4c480-fd8b-11e3-958f-c779cae3e1b3 \
-X DELETE \
-H 'Authorization:Bearer <Your access token>'
Subscription sub = Subscription.find("nsub_60ca7690");
Subscription.delete(sub);
Suggest Edits

List Subscriptions

 

You can fetch the subscriptions for an App by sending a GET request to https://api.intercom.io/subscriptions/.

Example List Subscriptions Request

$ curl https://api.intercom.io/subscriptions \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json'
intercom.subscriptions.all.each { ... }
HTTP/1.1 200 Ok

{
  "type": "notification_subscription.list",
  "notification_subscriptions": [
      {
        "type": "notification_subscription",
        "id": "nsub_6ab4c480-fd8b-11e3-958f-c779cae3e1b3",
        "created_at": 1392731331,
        "updated_at": 1392731331,
        "service_type": "web",
        "topics": ["user"],
        "url": "https://example.org/hooks/1",
        "active": true,
        "hub_secret": null
      },
      {
        "type": "notification_subscription",
        "id": "nsub_3fb4c480-fd8b-11e3-958f-c779cae3e1cd",
        "created_at": 1392731122,
        "updated_at": 1392731122,
        "service_type": "web",
        "topics": [
          "conversation.user.created",
          "conversation.user.replied"
        ],
        "url": "https://example.org/hooks/2",
        "active": true,
        "hub_secret": null
      }
  ],
  "pages":{}
}
SubscriptionCollection list = Subscription.list();

while (list.hasNext()) {
    Subscription sub = list.next();
    String appID = sub.getAppID();
    String serviceType = sub.getServiceType();
    List<Subscription.Topic> topics = sub.getTopics();
    String hubSecret = sub.getHubSecret();
}
Suggest Edits

Subscription Feeds

 

Each subscription object has a set of activity feeds -

  • https://api.intercom.io/subscriptions/{id}/sent : A feed of notifications sent.
  • https://api.intercom.io/subscriptions/{id}/error : A feed of errors returned by the webhook.

Where {id} is the value of the subscriptions's id field.

The feeds are not permanent archives and notifications may only retrievable for a period of time; a best effort is made to keep 30 days of activity data.

Subscription Error Feed

The error feed for a subscription,https://api.intercom.io/subscriptions/{id}/error, contains a list delivery failures. Each item in the list is the notification that also contains a http_request object that captures the request details.

The http_request object has the following fields -

Attribute
Type
Description

type

string

value is 'http.request'

request_method

string

The HTTP method.

request_uri

string

The fully qualified request URI

request_headers

object

An object containing the request header names and values sent to the server

response_status_code

number

The HTTP response code returned by the server

response_headers

object

An object containing the response header names and values returned by the server

response_entity

string

The response body returned by the server. If the response was JSON, the data will be escaped.

request_entity

string

The request body sent to the server.

The request_entity will contain an escaped JSON document with a field called "type" whose value is "self" indicating the containing notification JSON was what was submitted to the server.

A notification may appear multiple times in the error feed, once for each failed attempt to send.

Example Notification with error

{
  "type" : "notification.list",
  "notifications" : [
    {
      "type": "notification_event",
      "topic": "company.created",
      "id": "notif_ccd8a4d0-f965-11e3-a367-c779cae3e1b3",
      "created_at": 1392731331,
      "data": {
        "item": {
          "type": "company",
          "id": "531ee472cce572a6ec000006",
          "name": "Blue Sun",
          "company_id": "6",
          "remote_created_at": 1394531169,
          "created_at": 1394533506,
          "updated_at": 1396874658,
          "custom_attributes": {
          }
        }
      },
      "http_request" : {
        "request_method" : "POST",
        "request_uri" : "https://example.org/hooks/1",
        "request_headers" : {
          "Accept" : "application/json",
          "User-Agent" : "intercom-parrot-service-client/1.0",
          "Content-Type" : "application/json"
        },
        "request_entity" : "{\"type\":\"self\"}",
        "response_status_code" : 500,
        "response_headers" : {
          "X-Frame-Options" : "SAMEORIGIN",
          "Server" : "Apache",
          "Connection" : "keep-alive",
          "Vary" : "Accept-Encoding",
          "Content-Length" : "7",
          "Date" : "Tue, 12 Aug 2014 02:14:54 GMT",
          "Content-Type" : "text/plain"
        },
        "response_entity" : "You might wanna look to that\n"
      }
    },
    ...list of errors...
  ]
}
NotificationErrorCollection errs =
  Subscription.errorFeed(subscription.getId());

while (errs.hasNext()) {
  NotificationError err = errs.next();

  RequestResponseCapture c = err.getCapture();

  URI requestURI = c.getRequestURI();
  String method = c.getRequestMethod();
  Map<String, String> reqHeaders = c.getRequestHeaders();
  String reqEntity = c.getRequestEntity();

  int statusCode = c.getResponseStatusCode();
  Map<String, String> resHeaders = c.getResponseHeaders();
  String resEntity = c.getResponseEntity();
}
Suggest Edits

Subscription Ping

 

Each Subscription object can be pinged by sending a POST notification to -

  • https://api.intercom.io/subscriptions/{id}/ping

Where {id} is the id of the subscription. This results in a ping notification being sent to the url of the webhook. For services a message is rendered and presented.

The Ping object has the following fields -

Attribute
Type
Description

type

string

value is 'ping'

message

string

A text message

Note that all subscriptions should be implemented to accept ping events, as the API may send them at any time.

Example Ping Request

$ curl -XPOST \
https://api.intercom.io/subscriptions/nsub_6ab4c480-fd8b-11e3-958f-c779cae3e1b3/ping \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json'


HTTP/1.1 200 Ok

Example Ping Notification

{
  "type": "notification_event",
  "topic": "ping",
  "id": "notif_ccd8a4d0-f965-11e3-a367-c779cae3e1b4",
  "created_at": 1392731331,
  "delivery_attempts": 1,
  "first_sent_at": 1392731392,
  "data": {
    "item": {
      "type": "ping",
      "message": "shipping is your company's heartbeat"
    }
  }
}
Suggest Edits

Event Webhooks

 

Event webhooks are in Beta.

We'll be refining the API for a short while before lifting the beta tag, and we'd love to know what you think. Please send any feedback, questions or bug reports to us using the Intercom Messenger below!

Notes:

  • The initial beta support does not limit to number of event names per topic, but this may be changed before moving out of Beta.
  • We'll be adding support for event webhook subscriptions in the PHP, Ruby, Go, Node and Java clients.

Create an Event Webhook Subscription

To subscribe to event webhooks, add the event.created topic to your subscription in the topics field.

The names of the events must also be supplied in the subscription. This can be done by posting an array called event_names in the metadata field of the subscription. The event_names array is required for an events subscription - there is no option to subscribe to all event names.

Apart from the need to declare the event names, the event.created is a regular webhook and can be used with other topics in the same subscription.

Update an Event Webhook Subscription

You can update a subscription's event names by submitting a POST to the subscription's URL as described in Create a Subscription along with an updated event_names array. Note that the updated array replaces the existing array - the entire set of event names you want to subscribe to should be sent in an update.

Event Webhook Model

Example Event Notification Object

As with other topics, events sent to a webhook are published inside a Notification Object.

As well as the regular fields that were created when the event was posted to Intercom (see Event Object for details) the event payload will also contain an id field that uniquely identifies the event.

Example Event Webhook Create Request

$ curl https://api.intercom.io/subscriptions \
-XPOST \
-H 'Authorization:Bearer <Your access token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' -d'
{
  "service_type": "web",
  "topics": ["event.created"],
  "url": "https://example.org/hooks/1",
  "metadata": { 
    "event_names": ["invited-friend"]
  }
}'
HTTP/1.1 200 Ok

{
  "type": "notification_subscription",
  "id": "nsub_6ab4c480-fd8b-11e3-958f-c779cae3e1b3",
  "created_at": 1392731331,
  "updated_at": 1392731331,
  "service_type": "web",
  "topics": ["event.created"],
  "url": "https://example.org/hooks",
  "active": true,
  "hub_secret": null,
  "metadata" :{
    "event_names": ["invited-friend"]
  }
}
{
  "type": "notification_event",
  "topic": "event.created",
  "id": "notif_ccd8a4d0-f965-11e3-a367-c779cae3e1b3",
  "created_at": 1392731331,
  "delivery_attempts": 1,
  "first_sent_at": 1392731392,
  "data": {
    "item": {
      "type": "event",
      "id": "e5cc5f72-5522-11e4-9a06-49b58bcd0509",
      "event_name" : "invited-friend",
      "created_at": 1389913941,
      "user_id": "314159",
      "metadata": {
         "invitee_email": "pi@example.org",
         "invite_code": "ADDAFRIEND"
      }
    }
  }
}
Suggest Edits

Signed Notifications

 

You can request notifications from Intercom are signed by adding a hub_secret field to the subscription. The value of the hub_secret is used as the key to create a hash signature of the JSON notification The digest is then sent using an X-Hub-Signature header in the request and can be verified by the receiving webhook.

The signature is the hexadecimal (40-byte) representation of a SHA-1 signature computed using the HMAC algorithm as defined in RFC2104.

The X-Hub-Signature header value starts with the string sha1= followed by the signature - for example, X-Hub-Signature: sha1=21ff2e149e0fdcac6f947740f6177f6434bda921.

Example Signed Request

POST https://example.org/hooks
User-Agent: intercom-parrot-service-client/1.0
X-Hub-Signature: sha1=21ff2e149e0fdcac6f947740f6177f6434bda921
Accept: application/json
Content-Type: application/json
{
  "type" : "notification_event",
  "id" : "notif_78c122d0-23ba-11e4-9464-79b01267cc2e",
  "topic" : "user.created",
  "app_id" : "tx2p130c",
  "data" : {
    "type" : "notification_event_data",
    "item" : {
      "type" : "user",
      "id" : "530370b477ad7120001d",
      "user_id" : "25",
      "name" : "Hoban Washburne",
      "unsubscribed_from_emails" : false,
      "custom_attributes" : {}
    }
  }
}
Suggest Edits

Webhook Models

 

The API defines some data models specific to webhooks.

User Tag Object

A user tag is composed from the existing user and tag JSON and is sent when users are tagged and untagged via the user.tag.created and user.tag.deleted topics -

Attribute
Type
Description

type

string

_value is 'user_tag'_

created_at

timestamp

The time the user tag object was created

tag

Tag

The tag that was added or removed.

user

User

The user that was tagged or untagged.

Example User Tag Object

{
  "type": "user_tag",
  "created_at": 1392731331,
  "tag" : {
      "id": "17513",
      "name": "independent",
      "type": "tag"
    },
  "user" : {
      "type": "user",
      "id": "530370b477ad7120001d",
      "user_id": "25"
  }
}
Suggest Edits

Error Objects

 

The API will return an Error List for a failed request, which will contain one or more Error objects.

Error List Attributes

Each error has the following attributes

Field
Description

type

The type is error.list

errors

An array of one or more error objects

Error Object Attributes

Each Error Object has the following attributes

Field
Description

code

A string indicating the kind of error, used to further qualify the HTTP response code

message

Optional. Human readable description of the error

field

Optional. Used to identify a particular field or query parameter that was in error.

Error List Object

{
  "type": "error.list",
  "errors": [
    {
      "code": "not_found",
      "message": "No such user_id[314159]",
      "field": "user_id"
    },
    {
      "code": "not_found",
      "message": "No such email[pi@example.org]",
      "field": "email"
    }
  ]
}
// the JavaScript client doesn't directly expose error data
# the Ruby client doesn't directly expose error data
<?php
// the PHP client doesn't directly expose error data
?>
try {
  UserCollection uc = User.list();
} catch(IntercomException  ie) {
  Error e = ie.getFirstError();
  log.error("{}:{}", e.getCode(), e.getMessage());
}
Suggest Edits

Error Codes

 

The API may send the following error codes. Other codes may be added in the future.

Field
Description

server_error

Generic server error

client_error

Generic client error

type_mismatch

The JSON value type is incorrect for the field

parameter_not_found

A required parameter was not supplied

parameter_invalid

A parameter's value is invalid

action_forbidden

The action is not authorized

conflict

There is existing data that clashes with the request data

api_plan_restricted

The API is not available on this App's Plan

rate_limit_exceeded

The rate limit for the App has been exceeded

unsupported

The operation is not supported

token_revoked

The token or API Key has been revoked

token_blocked

The API Key or App has been blocked

token_not_found

The token or API Key does not exist

token_unauthorized

The token or API Key is not allowed to access the resource

token_expired

The token is expired

missing_authorization

No authorization data was found on the request

retry_after

The client should wait for a time before retrying the request

job_closed

The client should start a new bulk job

not_restorable

This user was blocked and cannot be recreated

Suggest Edits

HTTP Responses

 

The API returns HTTP responses on each request to indicate the success or otherwise of API requests. The codes listed below are often used, and the API may use others. Note that 4xx and 5xx responses may be returned for any request and clients should cater for them.

Response Code
Description

400

Bad Request -- General client error, possibly malformed data.

401

Unauthorized -- The API Key was not authorised (or no API Key was found).

402

Payment Required -- The API is not available on your current plan.

403

Forbidden -- The request is not allowed.

404

Not Found -- The resource was not found.

405

Method Not Allowed -- The resource does not accept the HTTP method.

406

Not Acceptable -- The resource cannot return the client's required content type.

408

Request Timeout -- The server would not wait any longer for the client.

409

Conflict - Multiple existing users match this email address - must be more specific using user_id

415

Unsupported Media Type - The server doesn't accept the submitted content-type.

422

Unprocessable Entity -- The data was well-formed but invalid.

429

Too Many Requests -- The client has reached or exceeded a rate limit, or the server is overloaded.

500, 502, 503, 504

Server errors - something went wrong with Intercom's servers.

503 or 504 responses are most likely momentary operational errors, these requests should be retried once.

Suggest Edits

Rate Limiting

 

The API may rate limit submission of requests for your application. Such limits are managed as an allowed number of operations per time window, where an operation might be read or an update. In that case a '429 Too Many Requests' response code will be returned along with the following headers -

Rate Limit Headers

X-RateLimit-Limit: Maximum number of operations allowed in the current window
X-RateLimit-Remaining: Number of operations left in the current window.
X-RateLimit-Reset: Time when rate limit window will be reset as a Unix timestamp.

Note that the default rate limit is 500 operations per minute per app.

Update to rate limits

We recently updated our rate limiting monitoring process. The maximum number of operations you can perform in 1 minute has not changed (it is still 500). However, to prevent large spikes in traffic this total is now distributed over 10 second periods. This means for a rate limit of 500 per minute you can send a maximum of 83 operations per 10 second period (500/6).

If you have a large number of operations to perform you should break these into groups of 83 or less (assuming your rate limit is 500 per minute) and send these groups every 10 seconds. You can look at the example headers on the right to see how you can use these to know the remaining time and request you have in your current 10 second window

For more information on how to best handle rate limits please see this blog post

# Example with a rate limit of 60 (note default is 500)
$ curl https://api.intercom.io/users/56e1e5d4a40df1cc57000101 -v -H 'Accept: application/json' -H 'Authorization:Bearer <Your access token>' | python -m json.tool

HTTP/1.1 200 OK
Content-Type: application/json
ate: Fri, 17 Feb 2017 11:55:03 GMT
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 10
X-RateLimit-Reset: 1487332510

# After another request:
HTTP/1.1 200 OK
Content-Type: application/json
Date: Fri, 17 Feb 2017 11:55:06 GMT
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 9
X-RateLimit-Reset: 1487332510

# 10 seconds later after window resets
HTTP/1.1 200 OK
Content-Type: application/json
Date: Fri, 17 Feb 2017 11:55:14 GMT
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 10
X-RateLimit-Reset: 1487332520

# And if you make more than the 10 requests in 10 seconds
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Date: Fri, 17 Feb 2017 11:55:18 GMT
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1487332520
intercom.rate_limit_details
#=> {:limit=>180, :remaining=>179, :reset_at=>2014-10-07 14:58:00 +0100}
Suggest Edits

Object Model

 

Common Fields

API objects have a type field indicating their object type. Each object in the API may be given an identifier, indicated via its id field, and will typically be addressable via a URI. Many objects will also have a created_at field indicating the object's creation date as a UTC Unix timestamp.

Dates and Timestamps

All temporal fields in the API are encoded as Unix timestamps and are by definition always treated as UTC. The most common time fields in the API are created_at and updated_at.

Parameter
Description

created_at

The time the object was created. In most, but not all cases, this is the time the object was created according to the API server.

updated_at

The time the object was last updated according to the API server.

Optional Fields

Unpopulated optional data is returned as follows -

  • Number, String and Boolean types may be returned as having null values.
  • Arrays and Objects may be returned as empty ([] {})

In general clients should be able to handle null and empty fields.

Metadata and Custom Attributes

Some object types, such as Events, Users and Companies, have a metadata or custom_attributes field that allows clients to set custom-defined data about an object.

Common Fields and Metadata

{
  "type": "user",
  "id": "456456456456",
  "self": "https://api.intercom.io/users/456456456456",
  "created_at": 1392241887,
  "custom_attributes": {
    "note": "some extra information"
  }
}
 

Data is encoded as defined by JSON in RFC4627. The default encoding for APIs is UTF-8. Certain characters, such as Emojji may be handled as surrogate unicode pairs (see section '2.5. Strings' of RFC4627).

Some query parameters may need to be url encoded when sending - for example, the email parameter value used to query users should be encoded.

Suggest Edits

Identifiers and URLs

 

All objects in the API have an id field indicating their logical identifier. Some objects may optionally also have a self field that indicates a URL or canonical address for the object.

Parameter
Description

id

A string that identifies the object within the API. The id field will not be larger than 128 characters (in SQL it corresponds to a varchar(128)).

self

A URL that addresses the object within the API. The self field will not be larger than 255 characters (in SQL it corresponds to a varchar(255)).

These fields must always be treated as opaque strings - no guarantees are made about the internal structure of the id or self fields for an object.

The id field is always defined by the API server and is guaranteed to be unique relative to the type field - this means no two user objects will have the same id field, but a user and a company may have the same value for their id fields. . Some object types (such as User), also support client defined identifiers.

The company and user objects deserve special mention when it comes to identity for two reasons -

  • They allow you send your own external identifiers - email and user_id for users and company_id for companies.
  • The user id field is in some cases, aliased to intercom_user_id. This is done to distinguish it from other identifiers in the API and to avoid confusion as to which object type an id denotes.
Suggest Edits

Pagination

 

Some list resources in the API are paginated by default to allow clients to traverse data over multiple requests. Their responses may contain a pages object that contains pagination links a client can use to traverse the data without having to construct a query. The link relations for the pages field are as follows -

Parameter
Description

next

A link to the next page of results. A response that does not contain a next link does not have further data to fetch.

prev

A link to the previous page of results.

first

A link to the first page of results.

last

A link to the last page of results.

Suggest Edits

Use of HTTP

 

Request methods are used in accordance with HTTP -

  • GET is used to access resources and perform queries. The API does not allow modifications (creates, updates, deletes) to occur via GET.
  • POST is used to create or update resources. The preferred model for creation is to post JSON to a 'collections' resource - for example the collections resource for users is https://api.intercom.io/users. PATCH is not currently used by the API.
  • DELETE is used to delete resources.

Responses use standard HTTP codes. Where there are client or server errors, a list of of one or more errors in JSON format is returned in the body - see "Errors" for more details.

The API may send cache directives where suitable, notably the ETag, Last-Modified and If-Modified-Since headers.

The Accept header must be used by a client used to indicate a preferred response for GET/HEAD requests. Requests without an Accept header of application/json may be rejected with a client error of 404 or 406. The Content-Type header should be used by clients to indicate the submitted format for POST/PUT requests.

Suggest Edits

Compatibility

 

JSON objects in the API follow a must ignore processing model, where clients are expected to ignore data fields they don't understand.

For example if the client saw the JSON as shown in the example on the right ('Unknown Field')
and did not understand the such_key field (and who can blame it?), it must pretend the field wasn't there and will process the object as if it looked liked the object shown in 'Must Ignore'.

When fetching content, fields that are optional for API objects are indicated in the documentation - clients must not assume they will always be present. When submitting content, fields that are required to be sent by client are also indicated in the documentation - if these are not sent the API may reject the request.

In general the API may reject JSON where data is not valid or incomplete with a 422 Unprocessable Entity response and an error message explaining the issue. For example, an email message type may be rejected if it is not sent with a subject field.

Unknown Field

{
  "type": "user",
  "user_id" : "456456",
  "email" : "j@example.org",
  "such_key": "so_value"
}

Must Ignore Interpretation

{
  "type": "user",
  "user_id" : "456456",
  "email" : "j@example.org"
}