Skip to content

API Integration Guide: OAuth 2.0 & Canvas LMS

The OAuth 2.0 protocol provides a secure mechanism for a third-party application (the Client) to access user information stored in Canvas LMS without requiring the user to share their Canvas credentials directly.

When an instructor links their account with a third-party application, they are redirected to the Canvas SSO login page. Upon successful authentication and consent, the application is granted authorized access to the instructor’s Canvas data. This linked state enables core integrations, such as importing student rosters and exporting grades seamlessly.


Understanding OAuth 2.0 requires defining the specific roles each system component plays:

TermDefinition & Context
Resource OwnerThe end-user (e.g., the instructor) who grants access to their data.
ClientYour application requesting access to the user’s information.
Authorization ServerThe system that authenticates the user and issues access tokens. Canvas LMS acts as the authorization server.
Authorization GrantA credential representing the resource owner’s consent. The client exchanges this grant for an access token.
Access Token (Bearer)The secure key used by the client to access protected resources on behalf of the user.
Resource ServerThe system hosting the protected user accounts and information. It verifies the access token before responding.
Redirect URIThe pre-registered destination where the authorization server sends the user after granting consent.
ScopeThe specific permissions granted by the end-user (e.g., reading course lists, fetching enrollments).
Client ID & SecretThe unique credentials used to identify and authenticate your application to the authorization server.

Canvas LMS implements the Authorization Code Flow, which is the most common and secure OAuth 2.0 flow for server-side applications. The process is divided into front-channel (browser-based) and back-channel (server-to-server) communications.

Section titled “1. Requesting User Consent (Front-Channel)”

To begin the flow, your application redirects the user’s browser to the Canvas authorization endpoint: GET https://<canvas-instance>/login/oauth2/auth

Include the following query parameters:

  • client_id: Your application’s unique ID.
  • response_type: Set to code.
  • redirect_uri: The endpoint in your application that will handle the callback.
  • scope: (Optional) A space-separated list of required scopes.

The user logs into Canvas and is prompted to authorize the application. Upon consent, Canvas redirects the user back to the redirect_uri, appending a temporary authorization code to the URL query string (?code=...).

2. Exchanging the Code for a Token (Back-Channel)

Section titled “2. Exchanging the Code for a Token (Back-Channel)”

Your application extracts the authorization code and securely sends a background POST request to the Canvas token endpoint: POST https://<canvas-instance>/login/oauth2/token

Include the following URL‑encoded form data (not JSON):

  • grant_type=authorization_code
  • client_id=YOUR_CLIENT_ID
  • client_secret=YOUR_CLIENT_SECRET
  • redirect_uri=YOUR_REDIRECT_URI
  • code=AUTHORIZATION_CODE_FROM_REDIRECT

Note: Replace <canvas-instance> throughout this guide with the actual domain of your Canvas LMS instance (e.g., canvas.instructure.com).

Canvas validates the credentials and returns a JSON response containing the access_token, a refresh_token, and the expires_in duration (typically 3600 seconds).

Your application stores these tokens securely and utilizes the access_token in the Authorization header of subsequent API requests to the Canvas Resource Server.

GET /api/v1/courses HTTP/1.1
Host: <canvas-instance>
Authorization: Bearer <access_token>

Access tokens possess a limited lifespan. Before making API calls, your application should validate the token’s temporal validity. If the token is expired, issue a refresh request to the token endpoint: POST https://<canvas-instance>/login/oauth2/token

Include the following payload:

  • grant_type: Set to refresh_token.
  • client_id: Your application’s unique ID.
  • client_secret: Your application’s secure secret key.
  • refresh_token: The refresh token received in step 2.

Upon success, the new access_token and updated expiration timestamp should be persisted to your database.


To execute the back-channel token exchange, you can make a standard POST request to the token endpoint.

Because the OAuth 2.0 specification requires token requests to be formatted as form data (rather than JSON), ensure you use the -d flag in your curl command to send the payload as application/x-www-form-urlencoded.

Terminal window
curl -X POST https://canvas.instructure.com/login/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "redirect_uri=https://api.your-app.com/oauth/callback" \
-d "code=AUTHORIZATION_CODE_FROM_REDIRECT"

Example Response:

{
"access_token": "8489~TOKEN_STRING",
"token_type": "Bearer",
"user": {
"id": 12345,
"name": "Jane Doe"
},
"refresh_token": "8489~REFRESH_TOKEN_STRING",
"expires_in": 3600
}