Authorization

The first step of the OAuth 2.0 flow is to ask the user to grant your App access to their data.

Direct the user’s browser to visit our authorization endpoint, /oauth2/authorize.

A full example authorization request URL looks like:

https://app.usecanopy.com/oauth2/authorize?client_id=b59b2c0f-ddd1-4d45-afdb-219ed1b3448d&redirect_uri=https://example.com/result&scope=read:pulls&response_type=code&code_challenge_method=S256&code_challenge=2qOwsVaysuEcxkCvkOO8q8OY0WtF8jRANW4Gow0wCiJvhpjpPHE3fdaejA&state=219ed1b3448d

Request Parameters

ParameterDescriptionType
client_idThe Client ID you were assigned when Creating Your App.Required
redirect_uriWhere to return the user to your App once access has been granted or denied. This must match one of the Redirect URIs given when Creating Your App.Required
scopeA space-separated list of Scopes representing the permissions required by your App.Required
response_typeThis must be set to code, meaning you will be given an Access Token upon completing the OAuth flow.Required
code_challenge_methodSee code_challenge for more details. We strongly recommend using S256 but will accept a plain challenge if necessary.Required
code_challengeWe enforce the use of Proof Key for Code Exchange (PKCE) to protect the integrity of the OAuth 2.0 authorization flow. Example code is provided later on this page.Required
stateYou can optionally provide an arbitrary state value which we will provide unchanged when redirecting the user back to your redirect_uri. See State below.Recommended
response_modeHow you would like the authorization data sent when we return the user to your redirect_uri. This can be query (default), fragment, or form_post. See below for more information.Optional

Proof Key for Code Exchange (PKCE)

We require the use of PKCE to protect our mutual user during the OAuth exchange. We will allow the plain PKCE Challenge Method but strongly recommend the use of S256 (SHA-256) as described below.

Each time you start an OAuth request your App should generate a random Code Verifier of at least 32 bytes, and encode it using base64url. You will need to store this to be used later when requesting an Access Token.

You should then use the SHA-256 hash function on the Code Verifier, and again use base64url encoding to produce a Code Challenge to send with the authorization request.

The following example shows how to achieve this in a Node.js app:

import { createHash, randomBytes } from "node:crypto";

// Create a 32-octet random sequence to use as the code_verifier. We need to
// remember this as we’ll use it in the token request later.
const codeVerifier = randomBytes(32).toString("base64url");

// Use the code_verifier to generate a code_challenge to use in the
// authorization request now.
const codeChallenge = createHash("sha256")
  .update(codeVerifier)
  .digest("base64url");

const url = new URL("https://app.usecanopy.com/oauth2/authorize");
url.searchParams.set("code_challenge_method", "S256");
url.searchParams.set("code_challenge", codeChallenge);

// … add the other OAuth params and redirect the user to this URL …

State

You can pass a state value containing any arbitrary data and we will include it in the URL when we redirect the user back to your application.

This can be used to add a “nonce” value to help prevent Cross-Site Request Forgery (CSRF) attacks.

You can also use it to store any other data (eg. in a JSON-encoded string) if you need to maintain some state between sending the user to our site to grant authorization and us returning them to your site.

Response Mode

The response_mode determines how the auth data will be provided when we return the user to your redirect_uri.

  • When omitted or set to query the auth data will be in the GET request URL query parameters.
  • When set to fragment the auth data will be encoded as URL query parameters but placed at the end of the URL in the #fragment.
  • When set to form_post the auth data will be in an application/x-www-form-urlencoded POST request body.

Response Data

Success

If the authorization request is successful the user will be returned to your redirect_uri as per your chosen response_mode, along with an authorization code and any state value you provided.

A full example success authorization response URL looks like:

https://example.com/result?state=219ed1b3448d&code=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJDYW5vcHkiOiJDb25uZWN0IiwiVGhpcyBpcyBqdXN0IG1lYW50IjoiYXMgYW4gZXhhbXBsZSIsIk5vc2V5IG9uZSI6ImFyZW7igJl0IHdlPyDwn5iJIn0.rrWzhN6Xg5z6deK6x9VT65Mu3fJk-SQgDregj2u3C6c

Failure

If the user denies your authorization request, or there is an error with your request, they will instead be returned to your redirect_uri with any state you provided, an error code, and possibly an explanatory error_description value.

Please note that for some errors, such as providing a non-whitelisted redirect_uri in your authorization request, we will instead display an error message to the user and not return them to your App.