Appearance
Apps SDK — User and Auth API
Get Canva User Token
API reference for the auth.getCanvaUserToken method.
Returns a JSON Web Token (JWT) that contains information about the current user.
This token must be decoded and verified via the app's backend.
The verified token is an object with the following properties:
aud- The ID of the app.brandId- The ID of the user's team.userId- The ID of the user.
To learn how to decode and verify JWTs, see JSON Web Tokens.
Usage: Get a JWT that contains information about the current user
typescript
import { auth } from '@canva/user';
const token = await auth.getCanvaUserToken();Returns
A JSON Web Token (JWT) that contains information about the current user.
Promise<CanvaUserToken>
Rate limit
This method has a rate limit of 10 requests every 10 seconds.
Init OAuth
API reference for the auth.initOauth method.
Initializes an OAuth client for a multi account.
Parameters
<Prop.List> <Prop name="options" required type="InitMultiAccountOauthOptions" sourceLineNumbers={[99]}> Options for initializing the oauth client
<PillAccordion defaultExpanded={true} title={<>Properties of <strong>options</strong></>}>
<Prop.List>
<Prop name="provider" required type="string" sourceLineNumbers={[283]}>
The provider to initialize the oauth client for
</Prop>
<Prop name="type" required type="string" sourceLineNumbers={[287]}>
The type of oauth client to initialize
The only valid value is `"multi_account"`.
</Prop>
</Prop.List>
</PillAccordion>
</Prop> </Prop.List>
Returns
A client for authorizing users with OAuth.
<Prop.List> <Prop name="requestAuthorization" required type="function" sourceLineNumbers={[485]}> Starts an OAuth authorization flow.
**Parameters**
<Prop.List>
<Prop name="request" type="AuthorizationRequest<T>" sourceLineNumbers={[485]}>
Options for configuring the authorization flow.
<PillAccordion defaultExpanded={false} title={<>Properties of <strong>request</strong></>}>
<Prop.List>
<Prop name="queryParams" type="ExcludeKeys<T, ForbiddenKey>" sourceLineNumbers={[136]}>
Query parameters to append to the URL of the request.
The following keys are not allowed in this object:
* `"client_id"`
* `"redirect_uri"`
* `"scope"`
* `"state"`
* `"response_type"`
* `"code_challenge"`
* `"code_challenge_method"`
* `"client_secret"`
</Prop>
<Prop name="scope" type="Set<string>" sourceLineNumbers={[140]}>
The list of scopes to request access to.
</Prop>
</Prop.List>
</PillAccordion>
</Prop>
</Prop.List>
**Returns**
The result of the authorization flow. This is a `Promise` that resolves with the following object:
<Tabs>
<Tab name="AuthorizationCompleted">
The result when a user successfully completes an OAuth authorization flow.
<Prop.List>
<Prop name="status" required type="string" sourceLineNumbers={[121]}>
The status of the authorization flow.
The only valid value is `"completed"`.
</Prop>
<Prop name="scope" required type="Set<string>" sourceLineNumbers={[125]}>
The scopes associated with the user.
</Prop>
</Prop.List>
</Tab>
<Tab name="AuthorizationAborted">
The result when a user fails to complete an OAuth authorization flow.
<Prop.List>
<Prop name="status" required type="string" sourceLineNumbers={[110]}>
The status of the authorization flow.
The only valid value is `"aborted"`.
</Prop>
</Prop.List>
</Tab>
</Tabs>
<Prop.Extras>
**Examples**
**Start an authorization flow**
```ts
import { auth } from "@canva/user";
// Initialize an OAuth client
const oauth = auth.initOauth({ type: 'multi_account' });
// Start an authorization flow
const response = await oauth.requestAuthorization();
```
**Start an authorization flow with specific scopes**
```ts
import { auth } from "@canva/user";
// Initialize an OAuth client
const oauth = auth.initOauth({ type: 'multi_account' });
// Define the scopes to request
const scope = new Set(['PLACEHOLDER_SCOPE_1', 'PLACEHOLDER_SCOPE_2']);
// Start an authorization flow with specific scopes
const response = await oauth.requestAuthorization({ scope });
```
**Start an authorization flow with custom query parameters**
```ts
import { auth } from "@canva/user";
// Initialize an OAuth client
const oauth = auth.initOauth();
// Define the query parameters to append to the URL of the request
const queryParams = new Map([['custom_param', 'custom_value']]);
// Start an authorization flow with custom query parameters
const response = await oauth.requestAuthorization({ queryParams });
```
**Handle the result of a authorization flow**
```ts
import { auth } from "@canva/user";
// Initialize an OAuth client
const oauth = auth.initOauth();
// Start an authorization flow
const response = await oauth.requestAuthorization();
if (response.status === 'completed') {
// The user completed the authorization flow
}
if(response.status === 'aborted') {
// The user did not complete the authorization flow
}
```
</Prop.Extras>
</Prop>
<Prop name="getAccounts" required type="function" sourceLineNumbers={[486]}> Returns
The result of requesting a list of accounts. This is a `Promise` that resolves with the following object:
<Prop.List>
<Prop name="accounts" required type="OauthAccount[]" sourceLineNumbers={[272]}>
A client for managing a single OAuth account.
<PillAccordion defaultExpanded={false} title={<>Properties of <strong>accounts</strong></>}>
<Prop.List>
<Prop name="id" required type="string" sourceLineNumbers={[649]}>
The ID of the account.
</Prop>
<Prop name="displayName" required type="string" sourceLineNumbers={[657]}>
The display name of the account.
</Prop>
<Prop name="expired" required type="boolean" sourceLineNumbers={[665]}>
Whether the access token for the account has expired and there is no associated refresh token.
</Prop>
<Prop name="getAccessToken" required type="function" sourceLineNumbers={[726]}>
Gets the access token and scopes for the current OAuth account.
* When a token expires, it's automatically refreshed by Canva.
* The token is cached by Canva, so the app's frontend shouldn't store the token.
**Parameters**
<Prop.List>
<Prop name="request" type="AccessTokenRequest" sourceLineNumbers={[726]}>
Options for requesting an access token for the current OAuth account.
<PillAccordion defaultExpanded={false} title={<>Properties of <strong>request</strong></>}>
<Prop.List>
<Prop name="forceRefresh" type="boolean" sourceLineNumbers={[12]}>
If `true`, the access token will be refreshed, even if it hasn't expired.
By default, access tokens are automatically refreshed after expiry.
</Prop>
<Prop name="scope" type="Set<string>" sourceLineNumbers={[16]}>
The scopes associated with the access token.
</Prop>
</Prop.List>
</PillAccordion>
</Prop>
</Prop.List>
**Returns**
The access token and scopes for the current OAuth account, or `null` if the account isn't authorized. This is a `Promise` that resolves with either `undefined` or the following object:
<Prop.List>
<Prop name="token" required type="string" sourceLineNumbers={[30]}>
The access token for the current user.
</Prop>
<Prop name="scope" required type="Set<string>" sourceLineNumbers={[34]}>
The scopes associated with the current user's access token.
</Prop>
</Prop.List>
<Prop.Extras>
**Examples**
**Get the access token of the current OAuth account**
```ts
import { auth } from "@canva/user";
// Initialize an OAuth client
const oauth = auth.initOauth({ type: 'multi_account' });
// Get the account
const account = await oauth.getAccount({ accountId: '123' });
// Get an access token for the account
const token = await oauth.getAccessToken();
```
**Check if the account is authorized**
```ts
import { auth } from "@canva/user";
// Initialize an OAuth client
const oauth = auth.initOauth({ type: 'multi_account' });
// Get an access token for the account
const account = await oauth.getAccount({ accountId: '123' });
const token = await account.getAccessToken();
if (token) {
// The account is authorized
} else {
// The account is not authorized
}
```
**Forcefully refresh an access token**
```ts
import { auth } from "@canva/user";
// Initialize an OAuth client
const oauth = auth.initOauth({ type: 'multi_account' });
// Get the account
const account = await oauth.getAccount({ accountId: '123' });
// Forcefully refresh an access token
const token = await account.getAccessToken({ forceRefresh: true });
```
</Prop.Extras>
</Prop>
<Prop name="deauthorize" required type="function" sourceLineNumbers={[748]}>
Deauthorizes the account.
**Returns**
An empty `Promise` that resolves once the account is deauthorized.
`Promise<void>`
<Prop.Extras>
**Example: Deauthorize an authorized account**
```ts
import { auth } from "@canva/user";
// Initialize an OAuth client
const oauth = auth.initOauth({ type: 'multi_account' });
// Get the account
const account = await oauth.getAccount({ accountId: '123' });
// Deauthorize the account
await account.deauthorize();
```
</Prop.Extras>
</Prop>
<Prop name="principal" type="string" sourceLineNumbers={[653]}>
The principal of the account (e.g., email, username).
</Prop>
<Prop name="avatarUrl" type="string" sourceLineNumbers={[661]}>
The avatar URL of the account.
</Prop>
</Prop.List>
</PillAccordion>
</Prop>
</Prop.List>
</Prop>
<Prop name="getAccount" required type="function" sourceLineNumbers={[487]}> Parameters
<Prop.List>
<Prop name="request" required type="GetAccountRequest" sourceLineNumbers={[487]}>
Options for requesting a single OAuth account.
<PillAccordion defaultExpanded={false} title={<>Properties of <strong>request</strong></>}>
<Prop.List />
</PillAccordion>
</Prop>
</Prop.List>
**Returns**
The result of requesting a single account. This is a `Promise` that resolves with the following object:
<Prop.List>
<Prop name="account" required type="OauthAccount" sourceLineNumbers={[264]}>
A client for managing a single OAuth account.
<PillAccordion defaultExpanded={false} title={<>Properties of <strong>account</strong></>}>
<Prop.List>
<Prop name="id" required type="string" sourceLineNumbers={[649]}>
The ID of the account.
</Prop>
<Prop name="displayName" required type="string" sourceLineNumbers={[657]}>
The display name of the account.
</Prop>
<Prop name="expired" required type="boolean" sourceLineNumbers={[665]}>
Whether the access token for the account has expired and there is no associated refresh token.
</Prop>
<Prop name="getAccessToken" required type="function" sourceLineNumbers={[726]}>
Gets the access token and scopes for the current OAuth account.
* When a token expires, it's automatically refreshed by Canva.
* The token is cached by Canva, so the app's frontend shouldn't store the token.
**Parameters**
<Prop.List>
<Prop name="request" type="AccessTokenRequest" sourceLineNumbers={[726]}>
Options for requesting an access token for the current OAuth account.
<PillAccordion defaultExpanded={false} title={<>Properties of <strong>request</strong></>}>
<Prop.List>
<Prop name="forceRefresh" type="boolean" sourceLineNumbers={[12]}>
If `true`, the access token will be refreshed, even if it hasn't expired.
By default, access tokens are automatically refreshed after expiry.
</Prop>
<Prop name="scope" type="Set<string>" sourceLineNumbers={[16]}>
The scopes associated with the access token.
</Prop>
</Prop.List>
</PillAccordion>
</Prop>
</Prop.List>
**Returns**
The access token and scopes for the current OAuth account, or `null` if the account isn't authorized. This is a `Promise` that resolves with either `undefined` or the following object:
<Prop.List>
<Prop name="token" required type="string" sourceLineNumbers={[30]}>
The access token for the current user.
</Prop>
<Prop name="scope" required type="Set<string>" sourceLineNumbers={[34]}>
The scopes associated with the current user's access token.
</Prop>
</Prop.List>
<Prop.Extras>
**Examples**
**Get the access token of the current OAuth account**
```ts
import { auth } from "@canva/user";
// Initialize an OAuth client
const oauth = auth.initOauth({ type: 'multi_account' });
// Get the account
const account = await oauth.getAccount({ accountId: '123' });
// Get an access token for the account
const token = await oauth.getAccessToken();
```
**Check if the account is authorized**
```ts
import { auth } from "@canva/user";
// Initialize an OAuth client
const oauth = auth.initOauth({ type: 'multi_account' });
// Get an access token for the account
const account = await oauth.getAccount({ accountId: '123' });
const token = await account.getAccessToken();
if (token) {
// The account is authorized
} else {
// The account is not authorized
}
```
**Forcefully refresh an access token**
```ts
import { auth } from "@canva/user";
// Initialize an OAuth client
const oauth = auth.initOauth({ type: 'multi_account' });
// Get the account
const account = await oauth.getAccount({ accountId: '123' });
// Forcefully refresh an access token
const token = await account.getAccessToken({ forceRefresh: true });
```
</Prop.Extras>
</Prop>
<Prop name="deauthorize" required type="function" sourceLineNumbers={[748]}>
Deauthorizes the account.
**Returns**
An empty `Promise` that resolves once the account is deauthorized.
`Promise<void>`
<Prop.Extras>
**Example: Deauthorize an authorized account**
```ts
import { auth } from "@canva/user";
// Initialize an OAuth client
const oauth = auth.initOauth({ type: 'multi_account' });
// Get the account
const account = await oauth.getAccount({ accountId: '123' });
// Deauthorize the account
await account.deauthorize();
```
</Prop.Extras>
</Prop>
<Prop name="principal" type="string" sourceLineNumbers={[653]}>
The principal of the account (e.g., email, username).
</Prop>
<Prop name="avatarUrl" type="string" sourceLineNumbers={[661]}>
The avatar URL of the account.
</Prop>
</Prop.List>
</PillAccordion>
</Prop>
</Prop.List>
</Prop> </Prop.List>
Rate limit
This method has a rate limit of 10 requests every 10 seconds.
Monetization Is Enabled
API reference for the monetization.isEnabled method.
<Note> This API is only available to apps that have been accepted into the Premium Apps Program. </Note>
Note: This API is strictly for UI-related checks and should not be used for backend authorization or verification purposes.
Usage: Check if a billable action is enabled
typescript
import { auth } from '@canva/user';
const isEnabled = await monetization.isEnabled('MY_BILLABLE_ACTION');
if (isEnabled) {
// Show premium UI elements
} else {
// Show upgrade prompt
}Parameters
<Prop.List> <Prop name="action" required type="BillableAction" sourceLineNumbers={[333]}> The billable action to verify.
<Prop.Extras>
**Available values**:
* `"modify_image"`
* `"modify_video"`
* `"modify_audio"`
* `"modify_text"`
* `"import_image"`
* `"import_video"`
* `"import_audio"`
* `"import_text"`
* `"generate_image"`
* `"generate_video"`
* `"generate_audio"`
* `"generate_text"`
</Prop.Extras>
</Prop> </Prop.List>
Returns
A promise that resolves to true if the action can be tracked (i.e., premium features are enabled for the user), or false if the action cannot be tracked (i.e., non-premium).
Promise<boolean>
Open Tracking Session
API reference for the monetization.openTrackingSession method.
<Note> This API is only available to apps that have been accepted into the Premium Apps Program. </Note>
Starts a new tracking session for a billable action or resumes an existing one.
Usage
Start a tracking session for a billable action
typescript
import { auth } from '@canva/user';
const session = await auth.monetization.openTrackingSession({
action: 'MY_BILLABLE_ACTION'
});
try {
// Perform billable action
} finally {
// Always close the session when done
await session.close();
}Resume a tracking session for a billable action
typescript
import { auth } from '@canva/user';
const session = await auth.monetization.openTrackingSession({
id: 'EXISTING_SESSION_ID'
});
try {
// Continue billable action
} finally {
await session.close();
}Parameters
<Prop.List> <Prop name="opts" required type="OpenTrackingSessionOptions" sourceLineNumbers={[374]}> Options to either start a new session or resume an existing session.
* `action`: The billable action to be tracked (if starting a new session).
* `id`: The ID of an existing session to resume (if resuming a session).
<PillAccordion defaultExpanded={true} title={<>Properties of <strong>opts</strong></>}>
<Prop.List>
<Prop name="action" required="At least one of `action` or `id` is required" type="BillableAction" sourceLineNumbers={[854]}>
Represents the possible billable actions that can be tracked.
<Prop.Extras>
**Available values**:
* `"modify_image"`
* `"modify_video"`
* `"modify_audio"`
* `"modify_text"`
* `"import_image"`
* `"import_video"`
* `"import_audio"`
* `"import_text"`
* `"generate_image"`
* `"generate_video"`
* `"generate_audio"`
* `"generate_text"`
</Prop.Extras>
</Prop>
</Prop.List>
</PillAccordion>
</Prop> </Prop.List>
Returns
An object containing the session's unique id and a method to close the session. This is a Promise that resolves with the following object:
<Prop.List> <Prop name="id" required type="TrackingId" sourceLineNumbers={[875]}> Unique identifier for tracking sessions associated with billable actions. </Prop>
<Prop name="closeTrackingSession" required type="function" sourceLineNumbers={[876]}> Returns
`Promise<void>`
</Prop> </Prop.List>
Request Enable Billable Action
API reference for the monetization.requestEnableBillableAction method.
<Note> This API is only available to apps that have been accepted into the Premium Apps Program. </Note>
Prompts the user to enable access to a billable action.
Use this method when a user without premium access requests a premium feature. If the action is already enabled, the method will resolve with a granted status, allowing the app to proceed. Otherwise, the user will be prompted to enable access.
Usage: Prompt the user to enable premium access
typescript
import { auth } from '@canva/user';
const response = await auth.monetization.requestEnableBillableAction('MY_BILLABLE_ACTION');
if (response === 'granted') {
// User has access, proceed with premium feature
const session = await auth.monetization.openTrackingSession({
action: 'MY_BILLABLE_ACTION'
});
} else {
// User declined access, show alternative content
}Parameters
<Prop.List> <Prop name="action" required type="BillableAction" sourceLineNumbers={[404]}> The BillableAction that triggered the request.
<Prop.Extras>
**Available values**:
* `"modify_image"`
* `"modify_video"`
* `"modify_audio"`
* `"modify_text"`
* `"import_image"`
* `"import_video"`
* `"import_audio"`
* `"import_text"`
* `"generate_image"`
* `"generate_video"`
* `"generate_audio"`
* `"generate_text"`
</Prop.Extras>
</Prop> </Prop.List>
Returns
A promise that resolves with an EnableBillableActionResponse:
granted: if the action is enabled or the user successfully enables it.denied: if the user refuses to enable access. This is aPromisethat resolves with the following object:
<Tabs> <Tab name="EnableBillableActionGranted"> Represents the result when a user successfully enables a billable action.
<Prop.List>
<Prop name="status" required type="string" sourceLineNumbers={[205]}>
The status indicating that the billable action was successfully enabled.
The only valid value is `"granted"`.
</Prop>
</Prop.List>
</Tab>
<Tab name="EnableBillableActionDenied"> Represents the result when a user is denied access to a billable action.
<Prop.List>
<Prop name="status" required type="string" sourceLineNumbers={[194]}>
The status indicating that the billable action was denied.
The only valid value is `"denied"`.
</Prop>
</Prop.List>
</Tab> </Tabs>
User Type Declarations
TypeScript type definitions for the @canva/user package.
Tip: You can download the TypeScript types for the @canva/user package here.
User API Changelog
The latest changes for the Canva Apps SDK @canva/user package.
2.2.0 - 2026-03-10
Added
- Promotes multi-account and multi-provider OAuth APIs from beta to public status.
- Promotes Monetization APIs from alpha to public status.
2.1.3 - 2026-02-16
Fixed
- Fixed a duplicate declaration error caused by scope hoisting
2.1.2 - 2025-12-18
Added
- Added a CHANGELOG.md to track changes.
Fixed
- Corrected documentation for
getCanvaUserTokenmethod to reflect that the JWT containsbrandIdandaudclaims, instead ofteamIdandappId.
2.1.1 - 2025-07-08
Other
- Inline documentation improvements.
2.1.0 - 2024-12-15
Added
- Introduced a test harness to allow for unit testing of the package.
2.0.0 - 2024-09-23
Changed
- Breaking: See Apps SDK Migration Guide for full list of changes.
1.0.0 - 2023-12-12
Added
- Introduced the
@canva/userpackage which contains methods for authenticating users in Canva Apps.