Developer
News and Updates
Get Support
Sign in
Get Support
Sign in
DOCUMENTATION
Cloud
Data Center
Resources
Sign in
Sign in
DOCUMENTATION
Cloud
Data Center
Resources
Sign in
Capabilities
Client Library
Color Theme Compliance (Beta)
UI Functions
Last updated Sep 14, 2026

OAuth 2.0 API Client

The OAuth 2.0 API client helps with OAuth 2.0 authorization in your Power-Ups. When you supply your client ID and redirect URI, you can use the client's helper functions to authorize users, obtain access tokens, and refresh your access tokens.

Note that the API client is not yet compatible with confidential OAuth 2.0 clients, and only compatible with public clients. See our OAuth 2.0 client configuration for more information about public and confidential OAuth 2.0 clients.

For an introduction on OAuth 2.0 in Trello as well as an example Power-Up using the OAuth 2.0 API client, see our getting started page.

Getting the API Client Instance

The API client instance is available by calling getOAuth2ApiClient() on the Trello Power-Up client library instance, commonly referred to as simply t. There are two main places you can call it.

In the Power-Up initialization function:

1
2
3
4
5
6
7
8
9
window.TrelloPowerUp.initialize({
  'card-buttons': (t) => {
    const client = t.getOAuth2ApiClient()
    // more logic here...
}, {
  clientId: YOUR_OAUTH_2_CLIENT_ID,
  redirectUri: YOUR_AUTHORIZATION_REDIRECT_URL
});

Or in your Power-Up's iframes:

1
2
3
4
5
6
7
const t = window.TrelloPowerUp.iframe({
  clientId: YOUR_OAUTH_2_CLIENT_ID,
  redirectUri: YOUR_AUTHORIZATION_REDIRECT_URL,
});

const client = t.getOAuth2ApiClient();

For both the case of TrelloPowerUp.initialize() or TrelloPowerUp.iframe(), ensure you have passed in your OAuth 2.0 client ID and a valid redirect URI. This information can be found in your app's OAuth 2.0 client configuration.

  • clientId: The ID of your OAuth 2.0 client.
  • redirectUri: The URL that users will be redirected to once they've clicked "allow" in the OAuth 2.0 consent screen. This should be a page you control, as you will need to call client.redirectUriCallback() in that page (see below). This value also must match one of your app's callback URLs.

Once you have your client, you are ready to start using the helper functions!

client.authorize(options)

client.authorize() kicks off the authorization flow by opening the OAuth 2.0 consent screen in a popup to the user. The user must click "allow" in the consent screen to proceed. If the page at your redirectUri is setup correctly, the authorization should be successful, issuing you an access token which you can use to make API requests on your users' behalf. The token is stored in plugin data, and fetched by calling client.getAccessToken() (see below).

Here's some sample code of how it could be used:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// In an iframe where you want to request authorization from your user
const t = window.TrelloPowerUp.iframe({
  clientId: YOUR_OAUTH_2_CLIENT_ID,
  redirectUri: YOUR_AUTHORIZATION_REDIRECT_URL,
});

button.addEventListener("click", async () => {
  const scopes = ["read:board:trello", "write:board:trello"];
  try {
    await t.getOAuth2ApiClient().authorize({ scopes });
    await t.closePopup();
  } catch (err) {
    // handle errors
  }
});

The authorize() function takes in an options object parameter with these fields:

fieldtypedescription
scopesstring[]An array of scopes to request. The scopes you pass in must also be included in the scopes you've set on your app's OAuth 2.0 Client Configuration.

Note that you do not need to add the special scope offline_access, as it is added for you under the hood.
storeInPluginDatabooleanWhether or not to store the resulting auth information in plugin data once the function resolves. The default (and recommended) value is true.
exchangeTrelloTokenbooleanSet to true to migrate an existing user by exchanging their Trello Auth token for OAuth 2.0 tokens instead of opening the consent screen. See Migrating existing users with token exchange below. Defaults to false.
tokenStorageKeystringOptional. Only needed if your Power-Up stores Trello Auth tokens under a custom plugin data key. Used together with exchangeTrelloToken to locate the token to exchange at member/private/<tokenStorageKey>. If omitted, the client library falls back to the default key it uses for Trello Auth tokens.

Remember: You must also call client.redirectUriCallback() inside your redirect URI page for this function to properly return an access and refresh token. See the next section for more details.

If your Power-Up already has users authorized with the legacy Trello Auth flow (via t.getRestApi()), you can migrate them to OAuth 2.0 without making them re-authorize. Calling authorize() with exchangeTrelloToken: true performs a token exchange under the hood: it sends the user's existing Trello Auth token to the token exchange endpoint, stores the new OAuth 2.0 access and refresh tokens in plugin data, and lets the user continue using your Power-Up uninterrupted.

The original Trello Auth token is revoked as part of the exchange and can no longer be used to call the Trello API. After the exchange, all Trello API requests for that user must use the new OAuth 2.0 access token as a bearer token (Authorization: Bearer {access_token}).

Additionally, because Power-Up OAuth 2.0 clients are workspace-restricted, the new OAuth 2.0 token is scoped to the workspace the user is currently in. If they use your Power-Up across multiple workspaces, only the first workspace can be migrated this way. For every other workspace, fall back to the standard authorization flow (call authorize() without exchangeTrelloToken) so the user can consent to that workspace.

Example

1
2
3
4
5
await t.getOAuth2ApiClient().authorize({
  scopes: ["read:board:trello", "write:board:trello"],
  exchangeTrelloToken: true,
});

When authorize() resolves, the new OAuth 2.0 access token is stored in plugin data and the original Trello Auth token has been revoked. Retrieve the new access token the usual way with t.getOAuth2ApiClient().getAccessToken().

If there is no Trello Auth token to exchange or if the stored token is no longer valid (for example, the user already migrated in another workspace), fall back to the standard consent flow:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const oauth2Client = t.getOAuth2ApiClient();

try {
  await oauth2Client.authorize({
    scopes: ["read:board:trello", "write:board:trello"],
    exchangeTrelloToken: true,
  });
} catch (err) {
  // No valid Trello Auth token to exchange, user must re-authorize.
  await oauth2Client.authorize({
    scopes: ["read:board:trello", "write:board:trello"],
  });
}

client.redirectUriCallback()

This function should be called by the page at the redirect URI you specified when setting up your Power-Up client library instance. This is the page your users are redirected to after pressing "allow" in the consent screen popup.

The redirect URI's page must call redirectUriCallback() for client.authorize() to resolve properly.

For example, let's say your redirect URI is https://my-app.com/authorize-redirect.html. The javascript code for that page could look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// inside authorize-redirect.js

const t = window.TrelloPowerUp.iframe({
  clientId: CLIENT_ID,
  redirectUri: `https://my-app.com/authorize-redirect.html`,
});

window.addEventListener("load", async () => {
  try {
    await t.getOAuth2ApiClient().redirectUriCallback();
  } catch (err) {
    // handle errors
  }
});

Under the hood, redirectUriCallback() grabs the authorization code from the URL query params and sends it back to your Power-Up's iframe, so that your client.authorize() call can exchange this code for an access token and refresh token. The access token is then stored in pluginData once authorize() resolves.

client.getAccessToken()

Returns an access token if you had previously authorized with the user using client.authorize(), and the saved refresh token hasn't expired (refresh tokens expire after 90 days). If this function returns null, it means you need to re-authorize your user.

The function automatically handles refreshing access tokens for you when they expire (default expiry is 1 hour).

The access token can be used to make API requests on your user's behalf, as long as the token has the correct scopes. Simply pass in the token in the Authorization header as a "Bearer" token.

Here's an example of how to use call this function and use an access token in an API request:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const t = window.TrelloPowerUp.iframe({
  clientId: CLIENT_ID,
  redirectUri: `https://my-app.com/authorize-redirect.html`,
});

let accessToken;

try {
  accessToken = await t.getOAuth2ApiClient().getAccessToken();
} catch (err) {
  // handle errors
}

const TRELLO_URL = `https://trello.com/1/boards/${boardId}`;
const headers = { Authorization: `Bearer ${accessToken}` };
const resp = await fetch(TRELLO_URL, { headers });
if (resp?.ok) {
  return resp.json();
} else {
  // handle errors
}

Rate this page: