Build an integration

Canvas objects

Gist API Quick Start

OAuth 2 authentication provides developers with a secure way to access Gist API data on behalf of other Gist users. Most commonly, OAuth 2 authentication is useful to set up integrations between third-party applications and Gist. Popular integrations include WooCommerce, Jira, and Stripe.

You might use OAuth 2 authentication to set up integrations that help you:

  • Sync your application data with Gist so Gist can send marketing and transactional email

  • Keep your audiences up-to-date and synced with your CRM, where you maintain a list of contacts

In this guide, we’ll walk through how to set up OAuth 2 to authenticate users of your app, then demonstrate how to make a call to the Gist API using an OAuth 2 access token.

When not to use OAuth 2

Before doing the work of setting up authentication with OAuth 2, it’s worth understanding when you don’t need to use OAuth 2, and should use your API key instead.

Simply put: Use your API key if you’re writing code that tightly couples your application’s data to your Gist workspace’s data. If you ever need to access someone else’s Gist workspace’s data, you should be using OAuth 2.

Note: We strongly discourage asking your users to copy and paste their API key into your application or integration. Not only is it less secure than using OAuth 2 it’s also prone to errors.

Tip: If you decide your app requires OAuth authentication, you may still use your API key to start building your app or integration with Gist REST API more quickly. As using an API key doesn’t require a server to handle the OAuth 2 flow, so you can start writing application code first, then switch to OAuth 2 further along in your development.

OAuth 2 workflow overview

Even if you’ve used OAuth 2 in the past, workflows can differ slightly, so here’s a quick overview of Gist’s OAuth 2 workflow (which conforms to the Authorization Code flow).

When a user indicates that they allow you to authenticate with Gist on their behalf:

  1. Your app opens a browser window to send the user to the Gist OAuth 2 page with required parameters.
  2. The user will login to Gist, reviews the requested permissions and authorizes your application
  3. Gist will then redirect the user back to your redirect URI (configurable when creating app in Gist's developer portal) with an authorization code in the query string
  4. Your server sends a request to the OAuth 2 server to exchange the authorization code for an access token
  5. You can then redirect your user back to your app's integration page within Gist, Replace GIST_APP_ID with your app_id after you create one.

You will want to store the access token in your app so you can use them for all subsequent requests to the Gist API on the user’s behalf.

Quickstart app

If this is your first time using OAuth authentication with Gist's APIs, we strongly recommend checking out the OAuth 2 Quickstart App, written in Ruby. This sample app is designed to get you started using OAuth 2 as quickly as possible by demonstrating all the steps outlined in this guide.

Get it on Github

Register your application

To get the credentials you need in order to set up your OAuth 2 workflow, you’ll first need to register your application with Gist:

  1. Navigate to the Developer Portal in your Gist account
  2. Click Create App
  3. Give your app a name and click Create

After successfully registering your application, you’ll see the client_id and client_secret on the Authentication tab. You’ll need these for the next step.

In order to properly setup OAuth flow for your app, you’ll need to know the Redirect URI for your application. This is the URL that Gist servers will redirect users to after they have consented to giving your application access to their Gist workspace data.

Getting OAuth 2 tokens

Step 1: Create the authorization URL and direct the user to Gist's OAuth 2 server

When sending a user to Gist's OAuth 2 server, the first step is creating the authorization URL ( This will identify your app and define the scopes it's requesting access to on behalf of the user. The query parameters you can pass as part of an authorization URL are shown below.

response_type Yes This tells the authorization server that the application is initiating the authorization code flow. code
client_id Yes The client ID identifies your app. Find it on your app's settings page. 7fff1e36-2d40-4ae1-bbb1-5266d59564fb
scope Yes The oAuth scopes your application is requesting, separated by URL-encoded spaces. read_contacts
redirect_uri Yes The URL that the user will be redirected to after they authorize your app for the requested scopes. For production applications, https is required.
state No A random string generated by your application, which can be verified later. Use a value associated the user you are directing to the authorization URL, for example, a hash of the user's session ID

Once you've created your URL, start the OAuth 2 process by sending the user to it.

// Build the auth URL
const authUrl =
  '' +
  `?response_type=code` +
  `&client_id=${encodeURIComponent(CLIENT_ID)}` +
  `&scope=${encodeURIComponent(SCOPES)}` +
  `&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` +

// Redirect the user
return res.redirect(authUrl);

Gist displays a consent window to the user showing the name of your app and a short description of the Gist API it's requesting permission to access. The user can then grant access to your app.

Your application doesn't do anything at this stage. Once access is granted, the Gist OAuth 2 server will send a request to the redirect URI defined in the authorization URL.

Step 3: Handle the OAuth 2 server response

When the user has completed the consent prompt from Step 2, the page is redirected to the redirect URI specified in your authentication URL. If there are no issues and the user approves the access request, the request to the redirect URI will be returned with a code query parameter attached and the state parameter sent with the authorization url. If the user doesn't grant access, no request will be sent.

// Your server code
app.get('/your-redirect-url', async (req, res) => {
  auth_code = req.query.code
  state = req.query.state
  // implement OAuth token exchange logic

Step 4: Exchange authorization code for access token

After your app receives an authorization code from the OAuth 2 server, it can exchange that code for an access token by sending a URL-form encoded POST request to with the values shown below.

grant_type Must be authorization_code authorization_code
client_id Your app's client ID 7fff1e36-2d40-4ae1-bbb1-5266d59564fb
client_secret Your app's client secret 7c3ce02c-0f0c-4c9f-9700-92440c9bdf2d
redirect_uri The redirect URI from when the user authorized your app
code The authorization code received from the OAuth 2 server 5771f587-2fe7-40e8-8784-042fb4bc2c31
const formData = {
  grant_type: 'authorization_code',
  client_id: CLIENT_ID,
  client_secret: CLIENT_SECRET,
  redirect_uri: REDIRECT_URI,
  code: req.query.code
};'', { form: formData }, (err, data) => {
  // Handle the returned tokens

The body of the token response will be JSON data with the form:

  "access_token": "CN2zlYnmLBICAQIYgZXFLyCWp1Yoy_9GMhkAgddk-zDc-H_rOad1X2s6Qv3fmG1spSY0Og0ACgJBAAADAIADAAABQhkAgddk-03q2qdkwdXbYWCoB9g3LA97OJ9I"

Full Example: Implementing the OAuth 2 workflow on your server

Let’s take a look at some sample server code. We’ll handle each step of the OAuth process:

  1. user authentication
  2. exchanging the code for the access token and
  3. making your first authenticated request on behalf of the user.
require 'gist-api-ruby'
require 'sinatra'
require 'net/http'

OAUTH_CALLBACK = "#{BASE_URL}/oauth/gist/callback"
GIST_SCOPES = "read_contact read_teammates"

gist =

# Basic Sinatra setup
configure do
  set :port, 3000

# 1. Navigate to and click Login
get '/' do
  "<p>Welcome to the sample Gist OAuth app! Click <a href='/auth/gist'>here</a> to log in</p>"

# 2. The login link above will direct the user here, which will redirect
#    to Gist's OAuth login page
get '/auth/gist' do
  workspace_id = "nrrjryb4" # Slug of the project
  query_params = "response_type=code&client_id=#{GIST_CLIENT_ID}&redirect_uri=#{OAUTH_CALLBACK}&scope=#{GIST_SCOPES}&state=abcd1234"
  redirect to("{query_params}")

# 3. Once the user authorizes your app, Gist will redirect the user to
#    this endpoint, along with a code you can use to exchange for the user's
#    access token.
get '/oauth/gist/callback' do
  code = params['code']
  state = params['state'] # value sent along auth url. use this to verify request
  body = "grant_type=authorization_code&client_id=#{GIST_CLIENT_ID}&client_secret=#{GIST_CLIENT_SECRET}&redirect_uri=#{OAUTH_CALLBACK}&code=#{code}"
  uri = URI("")
  response = JSON.parse(, body).body)
  access_token = response['access_token']

  gist = access_token)

  teammates = gist.teammates.find_all

    <p>This user's access token is #{access_token}.</p>

    <p>When hitting the Gist API's teammates endpoint, the server responded:<p>


  # In reality, you'd want to store the access token
  # somewhere in your application.
  # user = fake_db.get_current_user
  # fake_db.store_gist_creds_for_user(user, { access_token: access_token });

This code will handle the entire OAuth workflow, resulting in (but not persisting) an access token you can use to make a request on behalf of the authenticating user. In this case, we’re making a trivial request to the Teammates endpoint, but doing so confirms that the token is working as expected.

Note: All requests to the Gist OAuth 2 endpoints are made over HTTPS. For security, we strongly recommend — but do not enforce — using HTTPS for your redirect_uri.


Read through the code above if you want to understand every detail of the workflow, but briefly, here’s what's happening on your server:

To begin the process, you’ll redirect your user to this URL:<YOUR_USER_BOUND_VALUE>

When the user approves your application, they’ll be sent back to your application with a query string parameter named code you can use to request your access token via a POST request to this URL: