Authentication
Exchange your client credentials for a short-lived Bearer token using the OAuth 2.0 client credentials grant.
The API uses the OAuth 2.0 client credentials grant. You hold a client_id and client_secret, exchange them for a short-lived Bearer token, and send that token on every request. There is no user login, no redirect and no refresh token — this is a machine-to-machine flow.
Getting Credentials
Credentials are issued per district by Instructure. Ask your MasteryConnect representative or Instructure Support, and state which scopes your integration needs.
You will receive:
client_id
Identifies your integration. Not secret.
client_secret
Proves it is you. Secret — treat it like a password.
The client_secret is shown once, at creation. Store it in a secrets manager, never in source control, a browser, or a mobile app. Anything that holds it can read your district's data. If it leaks, ask Support to revoke the credential — revocation is immediate and invalidates every token already issued from it.
Credentials may carry an expiry date. Once past it, the token endpoint returns expired_client and no new tokens can be minted.
Requesting a Token
curl -X POST https://api.masteryconnect.com/api/v2/token \
-H 'Content-Type: application/json' \
-d '{
"grant_type": "client_credentials",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}'All three parameters are required. grant_type must be exactly client_credentials; any other value is a 422.
Response
access_token
The Bearer token. Send it on every subsequent request.
token_type
Always Bearer.
scope
Space-delimited list of the scopes actually granted.
expires_in
Seconds until the token expires.
Using a Token
Send it in the Authorization header:
Token Lifetime
Tokens last 2 hours, and never outlive the credential that minted them — if your credential expires in 30 minutes, so does a token issued now, and expires_in will say 1800.
Tokens are opaque and verified against the database on every request, so revocation takes effect immediately rather than at expiry.
Handling Expiry
Reuse a token until it expires; do not fetch a fresh one per request. The token endpoint is rate limited far more tightly than the data endpoints, and a token-per-request pattern will trip it.
The robust pattern:
Cache the token and the moment it expires (
now + expires_in).Reuse it while valid, refreshing a little early — 60 seconds of margin avoids a race with a token expiring mid-flight.
On a
401with codeinvalid_token, fetch a new token once and retry the request. If the retry also401s, stop and surface the error — retrying further will not help and will burn your token budget.
Scopes
Each endpoint requires one scope. All scopes are read-only.
districts:read
The district
schools:read
Schools
sections:read
Sections
classrooms:read
Classrooms
teachers:read
Teachers
materials:read
Materials
assessments:read
Assessments
items:read
Assessment items
objectives:read
Objectives (standards)
class_objectives:read
Class objectives
banks:read
Item banks
questions:read
Questions
passages:read
Passages
curriculum_maps:read
Curriculum maps
pathways:read
Pathways
reports:read
Reports
Request the narrowest set that does the job. A credential scoped to what it actually needs limits the damage if it is ever exposed.
Nested Endpoints Need the Child's Scope
For a nested route, the scope that matters is the one governing the data being returned — not the parent in the path:
/api/v2/banks/{bank_id}/questions
questions:read
/api/v2/materials/{material_id}/items
items:read
/api/v2/curriculum_maps/{id}/objectives
objectives:read
/api/v2/trackers/{tracker_id}/assessments
assessments:read
Calling with only the parent's scope returns 403 insufficient_scope.
Authentication Errors
401
invalid_token
Bad credentials at the token endpoint, or a missing, malformed, expired or revoked Bearer token.
401
expired_client
The credential itself has passed its expiry date.
401
revoked_credential
The credential has been revoked.
401
unknown_district
The credential's district is no longer resolvable.
403
insufficient_scope
Valid token, but it lacks the scope this endpoint requires.
403
feature_disabled
The API is not enabled for this district.
422
validation_error
grant_type missing or not client_credentials.
See Errors for the full envelope.
Last updated
Was this helpful?