OAuth Authorization

Thinkific uses the OAuth 2.0 authorization framework to issue access tokens on behalf of Thinkific Sites.

A detailed explanation of the OAuth options and steps is provided below. For a quick overview of the endpoints refer to our OAuth API Reference.

Note: If you are building a private app for a single Thinkific Site you may be able to use API Key Authorization instead. For help understanding the difference see Using the API.

On this page:

OverviewLink

When building Apps, you must authorize users using the Authorization Code Flow shown below. This flow can be extended with PKCE (Proof Key for Code Exchange) for scenarios where Client Secret cannot be safely stored.

authorization code flow

Note: This flow only supports authorization to access Thinkific API's on behalf of a Thinkific Site. To identify the current user and access their profile data, the flow should be extended with OpenID Connect.

For more information about each flow:

App CredentialsLink

In order to use this your App, you will need the app credentials (Client ID and Client Secret). You can collect these by registering an app with Thinkific.

See Building Apps in Thinkific to learn more.

UsersLink

During Authorization, User Roles help to determine whether the user is permitted to install and access an App's functionality.

Installing AppsLink

Only users that have the role of Site Owners, Site Admins, or Partners will be able to install an App.

User flowLink

Upon clicking ‘Install’ in the app store listing for your app, the customer must next be taken to the Authorization page. This allows them to review permissions and details about the apps before finalising the authentication and is a common experience that builds trust across all apps in the app store.

Upon clicking ‘Accept & Install’ on this screen, they can then be redirected to your app for account creation.

After Installation on a Thinkfic SiteLink

Once an App has been installed on a Thinkific Site, users of all roles (including students) will be granted an access token when going through the OAuth Flow.

The issued access token is scoped to the users appropriate role. For example, if the user is a student, their access token will return an unauthorized error when making requests to any of the Admin APIs, however they will be able to make successful calls to the Teaching API which returns data scoped to their role.

Before authorizing a user to access your appLink

When building an app, you should confirm the users level of access before granting access to your App's Admin tools.

To do so, once you receive an access token from an OAuth flow, you should make a call to the Admin API using the Access Token granted to that user. (to something like /api/public/v1/users) If the user is an admin they will receive a successful response, if they are a student they will receive an unauthorized response and should not be granted access.

In addition to this, you can gain more contextual information about the user by leveraging OpenID Connect.

Authorization Code FlowLink

The authorization code flow returns a refresh token that can require the user to grant access once.

Step 1: Ask for permissions from the Thinkific Site OwnerLink

In order to gain the necessary permissions for a Thinkific site, you'll need to redirect the Site Owner to the authorization flow by constructing the following URL:

https://{subdomain}.thinkific.com/oauth2/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_mode=query&response_type=code&state={state}

where:

ValueDescriptionsubdomain:The Subdomain for the Thinkific Site where the app will be installed.client_idYour App's client ID. (Retrieved in Step 1).redirect_uriOne of the authorized redirect URIs you've configured in your App. (Completion of this authorization will redirect back to this uri)stateA unique and non-guessable value which will be sent back to the authorization code request. (Optional, but highly recommended to mitigate CSRF attacks)response_typeWhen using Authorization code flow, this value should always be code.response_modeWhen using Authorization code flow, the default value, if blank is "query", but "form_post" can also be used

Note: Only the Site Owner can complete this authorization, Course & Site Admins are not able to grant access to apps.

Step 2: Confirm authorization codeLink

Once the Site Owner grants access by installing the app, Thinkific will redirect the user back to the informed redirect_uri using the following format:

{redirect_uri}?code={authorization_code}&subdomain={subdomain}&state={state}

where:

ValueDescriptionauthorization_codeA randomly generated code that expires in 60 secondssubdomainThe Subdomain for the Thinkific Site where the app is being installed.stateThe value (if any) provided in the previous request using the state value.

The app should receive Thinkific's request and then make the final request to retrieve the access token using the authorization code.

Step 3: Retrieving access tokenLink

Upon receiving the authorization code, the app should perform one last request to retrieve the access token, a POST request using basic authentication.

Endpoint:Link

POST https://{subdomain}.thinkific.com/oauth2/token

Basic Authentication:Link

Basic Authentication can be generated by encoding a username and a password in base64.

If using a tool that handles encoding for you (like Postman), input the username and password with the following values.

KeyValueDescriptionUsernameclient_idYour app's client IDPasswordclient_secretYour apps's client secret

When encoding authentication in base64 manually, use the folowing format:

base64(client_id:client_secret)

The resulting example should be something like:

Authorization: Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=

Request parameters:Link

In the body of the request, two values are expected:

ValueDescriptiongrant_typeValue should be "authorization_code"codeThe authorization code provided in the previous step

Example:

{
  "grant_type": "authorization_code",
  "code": "5a3c34512703ee80eb006dd255c0345a"
}

Response parameters:Link

Upon recipt of a successful request, Thinkific will respond with a HTTP status 200 with the following attributes:

ValueDescriptionaccess_tokenAn access token to make secure requests. This token expires after 24 hours.refresh_tokenA refresh token to request a new access token.token_typeValue should be "bearer"gidGlobal id to uniquely identify a Thinkific Siteexpires_inNumber of seconds until the access_token will become invalid.

Example:

{
  "access_token": "5a16505d-5ee5-4853-8cb9-41b63a13a291",
  "token_type": "bearer",
  "refresh_token": "3cb103dd-f05f-43a9-aa51-c33b8f1f2546",
  "expires_in": 86399,
  "gid": "703ca109-741c-40d2-9cf0-3ac51c63086b"
}

ErrorsLink

Invalid CredentialsLink

If the client_id or client_secret are invalid, Thinkific will respond with a HTTP 401 Status:

{
"error": "invalid credentials"
}
Invalid CodeLink

If the authorization code is incorrect or no longer valid, Thinkific will respond with a HTTP 401 status:

{
"error": "invalid code"
}

Step 4: Making secure requestsLink

Now that you have a valid access token, you can begin making authorized requests to Thinkific's APIs using Bearer Token Authorization.

Example Request:

curl -H 'Authorization: Bearer 386ea500-fc01-45e9-8914-f53e3b7c0ed5' \
-H 'Content-Type: application/json' \
https://api.thinkific.com/api/public/v1/users

Step 5: Refreshing tokenLink

Access tokens expire after 24 hours, and will need to be refreshed in order to continue accessing the Thinkific API.

Apps can use the refresh_token that is provided when it received the current access token to request a new valid access token with the following API call:

Endpoint:

POST https://{subdomain}.thinkific.com/oauth2/token

Once again, this endpoint uses the Basic Authorization method, so be sure to follow this structure.

Request parameters:Link

While the first time the request parameters included a "code" value, during the refresh call we will insted now pass a grant_type of refresh_token.

ValueDescriptiongrant_typeValue should be "refresh_token"refresh_tokenRefresh token to request a new access token

example:

{
"grant_type": "refresh_token",
"refresh_token": "0d8dcc00-a6e7-450c-baef-6f27bb07e36c"
}

Response parameters:Link

Upon successful refresh of the access_token, Thinkific will respond with a HTTP status 200 with the following attributes:

ValueDescriptionaccess_tokenA new access token to make secure requests.refresh_tokenA new refresh token to request a new access token.token_typeValue should be "bearer""gidGlobal id to uniquely identify a Thinkific Siteexpires_inNumber of seconds until the access_token will become invalid

example:

{
  "access_token": "4a6cb9f1-3b1a-449f-bf57-5ec5db7272b8",
  "token_type": "bearer",
  "refresh_token": "e1963268-7687-4c69-a7c9-96957dca4550",
  "expires_in": 86399,
  "gid": "703ca109-741c-40d2-9cf0-3ac51c63086b"
}

ErrorsLink

Invalid CredentialsLink

If the client_id or client_secret are invalid, Thinkific will respond with a HTTP 401 Status:

{
"error": "invalid credentials"
}
Invalid Refresh TokenLink

If the refresh token is incorrect or no longer valid, Thinkific will respond with a HTTP 401 status:

{
"error": "invalid refresh token"
}

Note: Every time an access_token is generated, a new refresh token is also generated and the previous become invalid.

Authorization Code Flow with PKCELink

Proof Key for Code Exchange or just PKCE, is an extension to the Authorization Code flow that helps to prevent certain attacks and to be able to securely perform the OAuth exchange from an App. It is a best practice for Apps that cannot store the Client Secret, since it's replaced by a one time code challenge.

Looking for a quickstart? Follow this link for a detailed starter using Vue.JS

Step 1: Generate code verifier, code challenge method and code challengeLink

The code verifier and code challenge should be generated by the App for the OAuth requests.

ValueDescriptioncode_verifierA dynamically created cryptographically random key and it should be unique for every authorization request.code_challenge_methodIs used to generate the code challenge, "S256" is the standard at Thinkific.code_challengeIs a hashed version of the code verifier, using the code challenge method algorithm and base64url-encoded.

Step 2: Ask for permissions from the Thinkific Site Owner with code challenge and code challenge methodLink

In order to gain the necessary permissions for a Thinkific site, you'll need to redirect the Site Owner to the authorization flow by constructing the following URL.

Code Verifier and Code ChallengeLink

Prior to requesting access, you must generate the code verifier. It's recommended the code verifier to be a string with the size of 43-128 characters.

From the code verifier, you must hash using SHA 256 and encode to a Base 64 URL safe string.

Requesting AccessLink

https://{subdomain}.thinkific.com/oauth2/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_mode=query&response_type=code&state={state}&code_challenge={code_challenge}&code_challenge_method={code_challenge_method}

where:

ValueDescriptionsubdomain:The Subdomain for the Thinkific Site where the app will be installed.client_idYour App's client ID. (Retrieved in Step 1).redirect_uriOne of the authorized redirect URIs you've configured in your App. (Completion of this authorization will redirect back to this uri)stateA unique and non-guessable value which will be sent back to the authorization code request. (Optional, but highly recommended to mitigate CSRF attacks)response_typeWhen using Authorization code flow, this value should always be "code".response_modeWhen using Authorization code flow, the default value, if blank is "query", but "form_post" can also be usedcode_challengeA challenge derived from the code verifier, using SHA 256 and encoded to a Base 64 URL safe string.code_challenge_methodThis is the algorithm used to generate the code_challenge. This value should always be "S256".

Note: Only the Site Owner can complete this authorization, Course & Site Admins are not able to grant access to apps.

Step 3: Confirm authorization codeLink

Once the Site Owner grants access by installing the app, Thinkific will redirect the user back to the informed redirect_uri using the following format:

{redirect_uri}?code={authorization_code}&subdomain={subdomain}&state={state}

where:

ValueDescriptionauthorization_codeA randomly generated code that expires in 60 secondssubdomainThe Subdomain for the Thinkific Site where the app is being installed.stateThe value (if any) provided in the previous request using the state value.

The app should be prepared to receive Thinkific's request and then make the final request to retrieve the access token as described in the next step.

Step 4: Retrieving access tokenLink

Upon receiving the authorization code, the app should perform the token request to retrieve the access token.

Endpoint:Link

POST https://{subdomain}.thinkific.com/oauth2/token

Basic Authentication:Link

The token request should be authenticated by using the Basic Authentication method, using the Client ID and Client Secret encoded in base64.

Please note that Client Secret is optional for the Authorization Code with PKCE, but it's required if you want to receive the refresh token.

If using a tool that handles encoding for you (like Postman), input the username and password with the following values.

KeyValueDescriptionUsernameclient_idYour app's client IDPasswordclient_secretYour app's client secret
base64(client_id:client_secret)

The resulting example should be something like:

Authorization: Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=

Request parameters:Link

In the body of the request, two values are expected:

ValueDescriptiongrant_typeThis value should be "authorization_code"codeThe authorization code provided in the previous stepcode_verifierThe random key generated at the beginning of the flow

Example:

{
  "grant_type": "authorization_code",
  "code": "5a3c34512703ee80eb006dd255c0345a",
  "code_verifier": "l2sdelBTs0cQiUJH-kjVxaxCv994o7gvqATmrGlru78"
}

Response parameters:Link

Upon recipt of a successful request(code verifier validated with the code challenge), Thinkific will respond with a HTTP status 200 with the following attributes:

ValueDescriptionaccess_tokenAn access token to make secure requests. This token expires after 24 hourstoken_typeValue should be "bearer"gidThe Subdomain for the Thinkific Site where the app is being installed.expires_inNumber of seconds until the access_token will become invalid.refresh_tokenA refresh token to request a new access token. Only returned if Client Secret is provided

Example:

{
  "access_token": "5a16505d-5ee5-4853-8cb9-41b63a13a291",
  "token_type": "bearer",
  "refresh_token": "3cb103dd-f05f-43a9-aa51-c33b8f1f2546",
  "expires_in": 86399,
  "gid": "703ca109-741c-40d2-9cf0-3ac51c63086b"
}

ErrorsLink

Invalid CredentialsLink

If the client_id or client_secret are invalid, Thinkific will respond with a HTTP 401 Status:

{
"error": "invalid credentials"
}
Invalid GrantLink

If the code challenge method is not S256 or if the code verifier and code challenge validation fails, Thinkific will respond with a HTTP 401 status:

{
"error": "invalid grant"
}
Invalid CodeLink

If the authorization code is incorrect or no longer valid, Thinkific will respond with a HTTP 401 status:

{
"error": "invalid code"
}

Step 5: Making secure requestsLink

Now that you have a valid access token, you can begin making authorized requests to Thinkific's APIs using Bearer Token Authorization.

Example Request:

curl -H 'Authorization: Bearer 386ea500-fc01-45e9-8914-f53e3b7c0ed5' \
-H 'Content-Type: application/json' \
https://api.thinkific.com/api/public/v1/users