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.

What you’ll need

  • A Gist account
  • Your API key

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.

Even if you’re intending to use OAuth 2 later, you may still want to use your API key to start writing code against the Gist API more quickly; using the 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
  2. The user will login to Gist, reviews the requested permissions and authorizes your application
  3. Then Gist will then redirect the user back to your redirect URI 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

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 resources (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.

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 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 Yes The slug secret of the project your application is requesting access for. 4rtjrhbh

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

// Build the auth URL
const authUrl =
  '' +
  `?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 OAuth 2 server sends a GET request 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.

app.get('/oauth-callback', 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 and refresh token by sending a URL-form encoded POST request to with the values shown below.

grant_type Must be authorization_code authorization_code 7fff1e36-2d40-4ae1-bbb1-5266d59564fb
client_id Your app's client ID 7fff1e36-2d40-4ae1-bbb1-5266d59564fb read_contacts
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 = "4rtjrhbh" # Slug of the project
  query_params = "response_type=code&client_id=#{GIST_CLIENT_ID}&redirect_uri=#{OAUTH_CALLBACK}&scope=#{GIST_SCOPES}&state=#{workspace_id}"
  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']
  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:<workspace_id>

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: