Files
web-hosts/chuckie.coppertone.tech/app/docs/canva/docs_connect_authentication.md
2025-12-26 13:38:04 +01:00

408 lines
15 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Skip navigation
Skip to main content
[](https://www.canva.com/developers/)
* [Home](/)
* Documentation
* Blogs
* [Your apps](https://www.canva.com/developers/apps)
* [Your integrations](https://www.canva.com/developers/integrations)
Getting started
[Overview](/docs/connect/)[Quickstart](/docs/connect/quickstart/)[Creating
integrations](/docs/connect/creating-integrations/)[Dev MCP
server](/docs/connect/mcp-server/)
Fundamentals
[API requests & responses](/docs/connect/api-requests-
responses/)[Authentication](/docs/connect/authentication/)[API
versions](/docs/connect/versions/)[Canva concepts](/docs/connect/canva-
concepts/)[Security](/docs/connect/guidelines/security/)[Shared responsibility
model](/docs/connect/guidelines/shared-responsibility/)
Examples
[Autofill guide](/docs/connect/autofill-guide/)[Return navigation
guide](/docs/connect/return-navigation-guide/)
Guidelines
[Brand](/docs/connect/guidelines/brand/)[Recommended
practices](/docs/connect/guidelines/recommended-practices/)[User
interface](/docs/connect/guidelines/user-interface/)
Distributing integrations
[Submission checklist](/docs/connect/submission-checklist/)[Submitting
integrations](/docs/connect/submitting-integrations/)
API reference
Authentication
Assets
Autofill
Brand templates
Comments
Designs
Design imports
Exports
Folders
Resizes
Users
[Keys](/docs/connect/api-reference/webhooks/keys/)
Webhooks
Webhook notifications
Appendix
[Scopes](/docs/connect/appendix/scopes/)[Capabilities](/docs/connect/capabilities/)[Error
responses](/docs/connect/error-
responses/)[Changelog](/docs/connect/changelog/)[Zapier Canva
MCP](/docs/connect/zapier-mcp/)
# Authentication
Copy page
To start using the Canva Connect APIs, you need to authorize your users using
[OAuth 2.0(opens in a new tab or
window)](https://datatracker.ietf.org/doc/html/rfc6749).
OAuth lets your integration authenticate the user, get their authorization to
access the Connect API endpoints, and then perform actions on their behalf.
Specifically, the Connect APIs use OAuth 2.0 with the [Authorization Code flow
with Proof Key for Code Exchange (PKCE)(opens in a new tab or
window)](https://datatracker.ietf.org/doc/html/rfc7636) using SHA-256.
The authorization and authentication process involves the following steps:
1. Obtain authorization from the Canva user for the scopes that your integration requires. After the user authorizes your integration, you'll receive an authorization code at your specified redirect URL.
2. Use the authorization code to generate access tokens, which lets your integration access Connect API resources. This lets your integration act on the user's behalf.
There are libraries in various languages that provide support for handling the
OAuth process. For more information, see the [OAuth Community Site(opens in a
new tab or window)](https://oauth.net/code/).
You can also use the [Canva Connect API Starter Kit(opens in a new tab or
window)](https://github.com/canva-sdks/canva-connect-api-starter-kit) as a
starting point for an authorization and authentication implementation.
## Prerequisites
Before authenticating to the Canva Connect APIs, you must first create and
configure your integration in the Developer Portal, including:
* Setting an integration name
* Generating and saving a client secret
* Selecting scopes
* Setting at least one authentication redirect URL
For more information, see [Creating integrations](/docs/connect/creating-
integrations/).
## Obtain user authorization
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.
### Create the authorization URL
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>
Copy
In your integration's settings in the [Developer Portal(opens in a new tab or
window)](https://www.canva.com/developers/integrations/), there is an
**Authorization URL generator** tool on the **Authentication** page that pre-
fills most of the parameters for an authorization URL. If you use this tool,
you must still provide your own `code_challenge` and `state` values, as well
as verify the values for the other query parameters.
Create the URL, starting with `https://www.canva.com/api/oauth/authorize?` and
add the following query parameters:
1. **`code_challenge`**
The `code_challenge` string you provide is derived from another string, a
`code_verifier`. You must first create a `code_verifier` value, and then
transform the `code_verifier` into the `code_challenge` string. For more
information, see the [PKCE specification(opens in a new tab or
window)](https://datatracker.ietf.org/doc/html/rfc7636#section-4.1).
1. Create the `code_verifier` string. It must be a high-entropy cryptographically random string that is between 43 and 128 characters long. Only ASCII letters, numbers, and `-`, `.`, `_`, or `~` characters are allowed.
You must securely store the `code_verifier` string in your client, because
you'll use it later to generate an access token.
The `code_verifier` value must not be accessible by the user or their browser.
2. Generate the `code_challenge` string by SHA-256 hashing the `code_verifier` value and then encoding that result into a URL-safe base64 string.
You can use the [sample code shown
below](/docs/connect/authentication/#example-code-for-codeverifier-and-
codechallenge-strings) to generate the `code_verifier` and `code_challenge`
strings.
The `code_verifier` and `code_challenge` values should be unique for each
request.
2. **`code_challenge_method`**
This must be set to `S256` (SHA-256).
3. **`scope`**
This is a space-separated list of [scopes](/docs/connect/appendix/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. For information on setting scopes, see [Creating
integrations](/docs/connect/creating-integrations/#step-3-set-scopes).
You must be explicit when listing scopes.
For example, specifying `asset:write` doesn't grant `asset:read` permissions.
You must specify _both_ in the scope string, for example: `asset:read
asset:write`.
4. **`response_type`**
This must be set to `code`.
5. **`client_id`**
This value is the unique ID that identifies your client. You can get this
value from your integration settings in the [Developer Portal(opens in a new
tab or window)](https://www.canva.com/developers/integrations/connect-api).
6. **`state`** (Optional)
The `state` parameter serves two primary purposes:
* It acts as a countermeasure against [Cross-Site Request Forgery (CSRF)(opens in a new tab or window)](https://en.wikipedia.org/wiki/Cross-site_request_forgery) attacks by maintaining a unique session state between your integration and the Canva API. For more information, see the [OWASP Cross-Site Request Forgery Prevention Cheat Sheet(opens in a new tab or window)](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html).
* It helps preserve the application state through the OAuth flow.
Although this parameter is optional to include in the authorization URL, it's
highly recommended. It makes sure that the response your integration receives
corresponds to the request initiated by the user, thereby preventing bad
actors from forging requests.
When creating the `state` value, it must be a high-entropy random string and
it should be unique for each request. You can use the [sample code shown
below](/docs/connect/authentication/#example-code-for-state-string) to
generate the `state` string.
You must securely store the `state` string in your client, so you can use it
later to verify the response.
The `state` parameter must not be used to store the `code_verifier` value.
7. **`redirect_uri`** (Optional)
This is 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. The URL set in this query parameter must be one that you
have already set in your integration settings.
If you have _only 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
query parameter isn't supplied in the authorization URL, then the first
redirect URL that's set in your integration's settings is used by default.
After adding the preceding query parameters, 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`
#### Example code for `code_verifier` & `code_challenge` strings
You can use the following sample code to generate the `code_verifier` and
`code_challenge` strings.
import crypto from "crypto";
const codeVerifier = crypto.randomBytes(96).toString("base64url");
const codeChallenge = crypto
.createHash("sha256")
.update(codeVerifier)
.digest("base64url");
JS
Copy
#### Example code for `state` string
import crypto from "crypto";
const state = crypto.randomBytes(96).toString("base64url");
JS
Copy
### Send the user to the authorization URL
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](/_next/static/media/authentication_approval.c416eae2.png)
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](/docs/connect/authentication/#generate-access-tokens).
`state```
Optional
The value of the `state` parameter, if it was provided with the initial
request.
To prevent forgery of cross-site requests, you must verify that the received
`state` value matches the one in the authorization URL you sent to the user.
If they don't match, you must stop the authorization flow and return an error
to the user.
## Generate access tokens
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 OAuth 2.0
specification](/_next/static/media/connect_token_flow_1600x976.6d4762db.png)
Token request flow (Adapted from the OAuth 2.0 specification).
Requests that require authenticating with your client ID and client secret
can't be made from a web-browser client. They must come from your backend,
otherwise they'll be blocked by Canva's [Cross-Origin Resource Sharing
(CORS)(opens in a new tab or window)](https://developer.mozilla.org/en-
US/docs/Web/HTTP/CORS) policy.
### Use an authorization code
To exchange an authorization code for an access token, use the [Generate an
access token endpoint](/docs/connect/api-reference/authentication/generate-
access-token/).
Some points to note when using the endpoint with an authorization code:
* Requests to the endpoint must be authenticated, and we recommend using the [basic access authentication(opens in a new tab or window)](https://en.wikipedia.org/wiki/Basic_access_authentication) method. 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](/docs/connect/authentication/#create-the-authorization-url).
* You must provide the authorization code you received after the [user authorized your integration](/docs/connect/authentication/#send-the-user-to-the-authorization-url).
The endpoint reference includes [example request code](/docs/connect/api-
reference/authentication/generate-access-token/#example-request) in various
languages.
A successful response from the endpoint includes the access token, the expiry
time for the token, and a refresh token.
### Use 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.
Refresh tokens can't be used to access resources on protected APIs. They are
only used for generating new access tokens.
To exchange a refresh token for an access token, you again use the [Generate
an access token endpoint](/docs/connect/api-reference/authentication/generate-
access-token/).
Some points to note when using the endpoint with a refresh token:
* Requests to the endpoint must be authenticated, and we recommend using the [basic access authentication(opens in a new tab or window)](https://en.wikipedia.org/wiki/Basic_access_authentication) method. 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.
## Introspect an access token
You can use the [Introspect an access token](/docs/connect/api-
reference/authentication/introspect-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.
## Revoke a token
If necessary, you can use the [Revoke a token](/docs/connect/api-
reference/authentication/revoke-token/) endpoint to revoke an access token or
refresh token.
[Community](https://community.canva.dev/)[Get Help](https://canva-
external.atlassian.net/servicedesk/customer/portal/2/group/2)[GitHub](https://github.com/canva-
sdks/canva-connect-api-starter-kit)
Was this page useful?YesNo
* * *
© 2025 All Rights Reserved. Canva®
[Privacy policy](https://www.canva.com/policies/privacy-
policy/)[Terms](https://www.canva.com/policies/)
[](https://www.facebook.com/canva)[](https://x.com/canva)[](https://www.pinterest.com/canva)[](https://instagram.com/canva)