Setting up OAuth

You'll need to set up OAuth if you're building an integration with Intercom that accesses other people's Intercom data - i.e. an integration you're making available to people outside of your own company.

Before applying for OAuth, please take a look at our OAuth application process. This will help you understand how to get automatically approved for OAuth so you can get started developing immediately. It will also explain how to apply for OAuth from your main production app once you are ready.

Note: OAuth has replaced API Keys for public integrations

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

If you just want to access your own Intercom data, you can use Access Tokens. If you're unsure, use this guide to work out which you need.

You can set up OAuth in a few simple steps:

  • Apply for OAuth from your TEST Intercom app
  • Get the authorization code
  • Get the access token

After you complete these steps you will be able to use your access token to execute the actions authorized by an Intercom customer. We will look at each one of these steps in detail below.

1. Apply for OAuth from your TEST app

If you want to access your customers' data via the API, then the first step is to apply for OAuth from your TEST app. Once your application has been automatically approved you will get a client ID and client secret that you can use to get authorization on behalf of your customers.

Once you have switched to your TEST app you can apply for OAuth here or by going to 'settings' within the Intercom app menu (hover over your avatar on the bottom left) and then clicking 'app settings' > 'developer tools' > 'OAuth'. Remember to make sure you are applying from your TEST app before you have approved explicit approval to apply from your main production app.

Although you will get automatic approval with your TEST app it is still important to add as much info as possible in the description field. This help us get an idea for what you are trying to do and will definitely help when it comes to final approval for your main production app. Basically ... the more info you provide the better.

Callback URL

When you register your app for OAuth you will need to provide a callback URL. This will be the URL which we POST to when your user has authorized your app to access their info. In other words, it is the URL Intercom will use to send the Authorization code for your user.

We will describe this in the next section with a worked example, so we don’t need to get into more detail here. For now, it is enough to know that the redirect will need to communicate over a TLS/SSL connection, so the URL will need to be over HTTPS. Otherwise, the application to register your app will fail.

Also, you can provide multiple, comma-separated URLs in this parameter. After approval, you can choose which URL to use when you're initiating the OAuth flow via the redirect_uri parameter. This means you can include testing as well as production URLs here.

Scopes

Scopes (i.e. permissions) let you specify exactly how your application needs to access an Intercom user’s account. You should only request the scopes you definitely need for your use case and provide clear descriptions of why you need each one - you can always request more later. This will speed up the approval of your request.

Extended scopes give access to more sensitive user data and therefore require a more detailed explanation of how they’ll be used in order to be approved.

If you want quick approval, or you are testing a potential service, then you should only select standard scopes where possible. Most requests are approved within 5 working days, if all the required information has been provided.

Standard scopes

These are commonly-used scopes and are generally quick to be approved.

Standard scopes
Description

Write users and companies

Create and update users and companies

Write tags

Create, update, use and delete tags

Write events

Submit events (i.e. user activity)

Write conversations

Reply to, mark as read and close conversations

Read one user and one company

List and view a single user and company

Read one admin

View a single admin

Read events

List all events belonging to a single user

Write events

Ability to submit events (i.e. user activity)

Read events

List all events belonging to a user

Read tags

List all tags

Read counts

Count users and companies with specified criteria

Extended scopes

These scopes give access to more sensitive user data and therefore require a more detailed explanation of how they’ll be used in order to be approved.

Extended scopes
Description

Read and write users

List all users and execute bulk actions on users

Read and list users and companies

List and view all users and companies

Read conversations

View users’ conversations

Read admins

List and view all admins

Manage webhooks

Create and update webhooks

2. Get the Code

To explain how OAuth works in Intercom, we can look at a typical authorization code grant flow. This is where an app - let's call it MyApp - wants to execute some action in Intercom on behalf of people who use MyApp and are also Intercom customers.

Let's assume at this point that my registration application was approved. Now, when I look at the OAuth section in "App Settings" within Intercom, I see a "Client ID" and a "Client Secret". Once you have these you can get your Authorization Code and Access Token to enable you to access your users’ data on their behalf. So let's get that Authorization Code.

To get the Authorization Code you simply need to send a GET request to the following address:

https://app.intercom.io/oauth?client_id=___&state=___

Your user will follow this link to the Intercom site and will be presented with the permissions that MyApp is requesting. Once the user approves this request, they are redirected back to MyApp’s site via the redirect URL you already provided.

Intercom provides some sample code that you can use to allow the user to authorize MyApp’s request via a "Connect with Intercom" button. You can find it on your OAuth page. We have created a very simple Sinatra setup that you could use one of your publicly available endpoints to test the OAuth flow.

Note that you will need to generate a Self Signed Certificate and a Private Key. If you already have SSL setup on your site then you will not need to take this step. But for the purposes of a simple test we can simply create a Self Signed Cert to use for HTTPS.
openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout pkey.pem -out cert.crt

openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout pkey.pem -out cert.crt
<a href="https://app.intercom.io/oauth?client_id=<XXXXXXXXXXXX>&state=example"><img src="https://static.intercomassets.com/assets/oauth/primary-7edb2ebce84c088063f4b86049747c3a.png" srcset="https://static.intercomassets.com/assets/oauth/primary-7edb2ebce84c088063f4b86049747c3a.png 1x, https://static.intercomassets.com/assets/oauth/primary@2x-0d69ca2141dfdfa0535634610be80994.png 2x, https://static.intercomassets.com/assets/oauth/primary@3x-788ed3c44d63a6aec3927285e920f542.png 3x"/></a>
#!/usr/bin/env ruby
#
# This code snippet shows how to enable SSL in Sinatra+Thin.
#

require 'sinatra'
require 'thin'
require 'json'
require 'slim'


class MyThinBackend < ::Thin::Backends::TcpServer
  def initialize(host, port, options)
    super(host, port)
    @ssl = true
    @ssl_options = options
  end
end

configure do
  set :environment, :production
  set :bind, '0.0.0.0'
  #:set :port, 443
  set :server, "thin"
  class << settings
    def server_settings
      {
          :backend          => MyThinBackend,
          :private_key_file => File.dirname(__FILE__) + "/pkey.pem",
          :cert_chain_file  => File.dirname(__FILE__) + "/cert.crt",
          :verify_peer      => false
      }
    end
  end
end

get '/' do
  File.read('intercom.html')
end

get '/home' do
  "Welcome Back"
end

get '/callback' do
  code = params[:code]
  state = params[:state]
  puts "CODE: #{code}"
  puts "STATE:#{state}"
  redirect '/home'
end

The full code example can be found here. You can copy the Intercom JS to a file and reference it in a page where a user can click through to provide authorization. Then you would need to have a route for the callback you provided (or the test one you specified via your redirect_uri).

Remember, your callback URL needs to be a HTTPS endpoint so ensure you have followed the step above to generate a Key and Cert to use. When you have this setup run the ruby server and you should when you click through and authorize the user you should see something similar output on the terminal:

> ruby ssl_server.rb
== Sinatra (v1.4.7) has taken the stage on 4567 for production with backup from Thin
Thin web server (v1.6.4 codename Gob Bluth)
Maximum connections set to 1024
Listening on 0.0.0.0:4567, CTRL+C to stop
[05/May/2016:10:15:44 +0000] "GET / HTTP/1.1" 200 512 0.0036
CODE: XXXXXXXXXXXXXXXXXXXXXXXXX
STATE:example
89.101.228.226 - - [05/May/2016:10:15:49 +0000] "GET /callback?code=XXXXXXXXXXXXXXXXXX&state=example HTTP/1.1" 302 - 0.0008
[05/May/2016:10:15:49 +0000] "GET /home HTTP/1.1" 200 12 0.0005

3. Get the Access Token

Now that we have the Code we can exchange this for the Access Token, which will then allow you to get the authorized information on behalf of your user.

For the purposes of our simple example, we can perform a Post to the Intercom Eagle endpoint to get the relevant data. Note that we are simplifying this for our example purposes here, so you should store the "Code" and "Access Token" so that you do not need to make these calls each time.

Also, you should not hardcode your "Client ID" or "Client Secret" information in any code you may commit to something like GitHub. If you are using Rails for example, you should use your "secrets.yml" file to store this information. For now we will just keep it simple so we can understand the OAuth flow. So add the following code to you callback route:

  #We can do a Post now to get the access token
  uri = URI.parse("https://api.intercom.io/auth/eagle/token")
  response = Net::HTTP.post_form(uri, {"code" => params[:code],
                                       "client_id" => "XXXXXXXXXXXX",
                                       "client_secret" => "YYYYYYYYYYYYY"})

  #Break Up the response and print out the Access Token
  rsp = JSON.parse(response.body)
  puts "ACCESS TOKEN: #{rsp["token"]}"
#!/usr/bin/env ruby
#
# This code snippet shows how to enable SSL in Sinatra+Thin.
#

require 'sinatra'
require 'thin'
require 'json'
require 'slim'
require 'json'
require "net/http"
require "uri"

class MyThinBackend < ::Thin::Backends::TcpServer
  def initialize(host, port, options)
    super(host, port)
    @ssl = true
    @ssl_options = options
  end
end

configure do
  set :environment, :production
  set :bind, '0.0.0.0'
  #:set :port, 443
  set :server, "thin"
  class << settings
    def server_settings
      {
          :backend          => MyThinBackend,
          :private_key_file => File.dirname(__FILE__) + "/pkey.pem",
          :cert_chain_file  => File.dirname(__FILE__) + "/cert.crt",
          :verify_peer      => false
      }
    end
  end
end

get '/' do
  File.read('intercom.html')
end

get '/home' do
  "Welcome Back"
end

get '/callback' do
  #Get the Code passed back to our redirect callback
  @code = params[:code]
  @state = params[:state]
  puts "CODE: #{@code}"
  puts "STATE:#{@state}"

  #We can do a Post now to get the access token
  uri = URI.parse("https://api.intercom.io/auth/eagle/token")
  response = Net::HTTP.post_form(uri, {"code" => params[:code],
                                       "client_id" => "XXXXXXXXXXXXX",
                                       "client_secret" => "YYYYYYYYYYYY"})

  #Break Up the response and print out the Access Token
  rsp = JSON.parse(response.body)
  puts "ACCESS TOKEN: #{rsp["token"]}"
  redirect '/home'
end

#post '/callback' do
#  push = JSON.parse(request.body.read)
#  puts "I got some JSON: #{push.inspect}"
#end

When you run your server and click through to authorize the user you should now also see the "Access Token" output on the terminal:

ruby ssl_server.rb
== Sinatra (v1.4.7) has taken the stage on 4567 for production with backup from Thin
Thin web server (v1.6.4 codename Gob Bluth)
Maximum connections set to 1024
Listening on 0.0.0.0:4567, CTRL+C to stop
[05/May/2016:10:45:32 +0000] "GET / HTTP/1.1" 200 512 0.0041
CODE: XXXXXXXXXXXXXXXXXXXXX
STATE:example
ACCESS TOKEN: YYYYYYYYYYYYYYYYYYYYYYYYYY
[05/May/2016:10:45:36 +0000] "GET /callback?code=XXXXXXXXXXXXXXXXXXXX&state=example HTTP/1.1" 302 - 0.7180
[05/May/2016:10:45:36 +0000] "GET /home HTTP/1.1" 200 12 0.0004

4. Use your Token

Now that we have the authorized token we can use this to execute some action on behalf of our user. So let's just use the Intercom-Ruby library to query for a user with the Access Token:

> require 'intercom'
 => true
> intercom = Intercom::Client.new(token: '<ACCESS TOKEN>')
> user = intercom.users.find(:user_id => "11")
 => #<Intercom::User:0x000000026a6998 @changed_fields=#<Set: {}>, @custom_attributes={}, @id="571921c8cbc37c3717000004", @user_id="11", @anonymous=false, @email="nietzche@existentialist.com", @name=" Fred", @pseudonym=nil, @avatar=#<Intercom::Avatar:0x000000026a0868 @changed_fields=#<Set: {}>, @image_url=nil>, @app_id="a86dr8yl", @companies=[], @location_data={}, @last_request_at=nil, @last_seen_ip=nil, @created_at=1461264840, @remote_created_at=nil, @signed_up_at=nil, @updated_at=1461933410, @session_count=0, @social_profiles=[], @unsubscribed_from_emails=false, @user_agent_data=nil, @tags=[], @segments=[#<Intercom::Segment:0x0000000266ce00 @id="5720e6ac7175427af100001b", @changed_fields=#<Set: {}>>]>
> user.email
 => "nietzche@existentialist.com"

Now you should be able to use the authorized tokens you receive from your users.

5. Alternatively, you can use OmniAuth Intercom

We have added support for Intercom to number of OAuth libraries. It makes the setup process much easier, so it is a good way to setup OAuth for your app.

Setting up OAuth