Authentication

To start using the Canva Connect API, you need to authenticate your users using OAuth 2.0.

OAuth authentication lets your integration authenticate the user, and get their authorization to access the Connect API endpoints and perform actions on their behalf. If you're already familiar with OAuth 2.0 – we're using the Authorization Code flow with PKCE using SHA-256.

An overview of the OAuth authentication process is shown below:

Diagram showing the authentication flow, adapted from RFC 6749
Authentication Code Flow (Adapted from the OAuth 2.0 RFC).

The authentication process involves the following steps:

  1. Obtain authorization from the user for the scopes that your integration requires. After a user authorizes your integration, you'll receive an authorization code at your specified redirect URL.
  2. Use the authorization code to generate access tokens to use in your API requests. This allows your integration to act on the user's behalf.

Before authenticating to the Canva Connect API, you must first create and configure your integration in the Developer Portal, including:

  • Generating and saving a client secret
  • Selecting scopes
  • Setting at least one authentication redirect URL

To obtain user authorization, you must direct your users to Canva's authorization URL. This lets a user review and approve access for your integration.

The authorization URL that you direct users to is in the following format:

https://www.canva.com/api/oauth/authorize?code_challenge=<code challenge string>&code_challenge_method=s256&scope=<list of scopes>&response_type=code&client_id=<client ID>&state=<optional state>&redirect_uri=<redirect uri for your integration>

The URL has the following query parameters:

#code_challenge
Required

Use the following process to generate a code_challenge string. For more information, see the PKCE specification.

  1. Create a random string (excluding any +, /, or = characters) that is between 43 and 128 characters long. Store this value as your code_verifier string.
  2. Generate the code_challenge string by encoding the code_verifier value into an SHA-256 string and then encode that result into a URL-safe base64 string.

You must store the code_verifier string securely (in a database or local storage) as it is required later in the authentication process to generate an access token.

You can use the sample code shown below to generate the code_verifier and code_challenge strings.

#code_challenge_method
Required

Must be set to S256 (SHA-256).

#scope
Required

A space-separated list of scopes requested by your integration.

The scopes you request must already be set in your integration settings in the Developer Portal. You can't request any scopes you haven't set in your integration's settings.

#response_type
Required

Must be set to code.

#client_id
Required

A unique ID string that identifies your client. You can get this value from your integration settings in the Developer Portal.

#state
Optional

If your integration needs to maintain a state through the authorization process, you can provide some data here and it's returned in the authorization response.

#redirect_uri
Optional

The URL to redirect the user to after they authorize your integration. Although this parameter is optional to include in the authorization URL, you must have at least one redirect URL set in your integration settings in the Developer Portal.

This URL must be one that you have already set in your integration settings. If you only have one redirect URL set in your integration settings, you don't need to provide this parameter.

If you have multiple redirect URLs set in your integration settings and this parameter isn't supplied, the first redirect URL that's set in your integration's settings is used by default.

An example authorization URL might look similar to the following:

https://www.canva.com/api/oauth/authorize?code_challenge=eeeAbcdefgh123456789Vz96F9UIv8EHwnmibz3Djx3EE&code_challenge_method=s256&scope=asset:read%20asset:write%20design:meta:read%20folder:read%20comment:write&response_type=code&client_id=OCABC12-DeF

You can use the following sample code to generate the code_verifier and code_challenge strings.

const crypto = require("crypto");
const randomBytes = crypto.randomBytes(32).toString("hex");
const codeVerifier = randomBytes.toString('base64url')
const codeChallenge = crypto.createHash("sha256").update(codeVerifier).digest("base64url")
js

You must direct your users to the authorization URL that you created to get their approval for your integration and the requested scopes.

They will see a prompt similar to the following:

User authorization prompt

After they authorize your integration, they are redirected to your redirect URL with the following query parameters:

#code
Required

The authorization code you can use to generate an access token.

#state
Optional

The value of the state parameter, if it was provided with the initial request.

After you've obtained user authorization and received an authorization code, you can exchange the code for an access token (that lets you act on the user's behalf) and a refresh token (that you can use to get new access tokens).

Because access tokens are only valid for a short period time, you can handle requesting new access tokens using a refresh token instead of having to re-authorize the user to get a new authorization code.

An overview of the token request process is shown in the diagram below:

Diagram showing the token request flow, adapted from RFC 6749
Token request flow (Adapted from the OAuth 2.0 RFC).

To exchange an authorization code for an access token, use the Generate an access token endpoint.

Some points to note when using the endpoint with an authorization code:

  • Requests to the endpoint require basic access authentication with your client ID as the username and your client secret as the password. For basic access authentication, the {credentials} string must be a Base64 encoded value of {client id}:{client secret}.
  • When exchanging an authorization code for an access token, you must set grant_type to authorization_code .
  • You must provide the code_verifier value that you generated when creating the user authorization URL.
  • You must provide the authorization code you received after the user authorized your integration.

The endpoint reference includes example request code in various languages.

A successful response from the endpoint includes the access token, the expiry time for the token, and a refresh token.

When an access token expires or becomes invalid, you can use a refresh token from a previous access token request to get a new access token.

To exchange a refresh token for an access token, you again use the Generate an access token endpoint.

Some points to note when using the endpoint with a refresh token:

  • Requests to the endpoint require basic access authentication with your client ID as the username and your client secret as the password. For basic access authentication, the {credentials} string must be a Base64 encoded value of {client id}:{client secret}.
  • When exchanging a refresh token for a new access token, you must set grant_type to refresh_token.
  • You must provide a refresh token from a previous token request.
  • Each refresh token can only be used once.

A successful response from the endpoint includes a new access token, the expiry time for the new token, and another refresh token.

You can use the Introspect an access token endpoint to see whether an access token or refresh token is valid and active. You can also verify some token properties, such as its claims, scopes, and validity times.

If necessary, you can use the Revoke an access token endpoint to revoke an access token or refresh token.