District SSO with OAuth 2.0

Clever Instant Login allows your application to connect to ADFS, Azure Active Directory, Google, Stoneware, Clever Badges, and more with a single integration. By supporting Instant Login, any Clever user can sign in to your application with the credentials they already know no matter which identity provider their district is using.

In this section, we'll go through how users can log in to your application, the mechanics behind it, and how to set up Instant Login for your application.

Initiating Logins / User Experience

There are three ways a user can log in to your application using Instant Login: the Clever Portal, Instant Login links, and Log in with Clever buttons. Your integration should be able to handle logins from any of these sources.

Clever Portal

Many districts use the Clever Portal as the primary launch point into their applications.

  1. User accesses Clever Portal (ex: https://clever.com/in/demo)
  2. User clicks on the "Log in with {IDP}" button (note in the example above, this does not appear as the district's IDP is Clever-managed Passwords
  • This step is also skipped if the user is already logged in to Clever
  1. User is redirected to their Identity Provider
  2. User enters in their credentials
  3. On successful login, user sees their portal and clicks on an application icon to kick off the login process into the application.

Instant Login Links

Some districts prefer not to use the Clever Portal, but still want to use Instant Login to access their applications. To support this, Clever built Instant Login links which are links that can be embedded anywhere and are used to log a district's users in to a specific application through Instant Login. An example Instant Login link is: https://clever.com/oauth/instant-login?client_id=YOUR_CLIENT_ID&district_id=THE_DISTRICT_ID.

  1. User clicks on an Instant Login link - these are usually embedded in their district's portal or homepage or saved as a bookmark in their browser
  2. User is taken to the Clever login page
  • This step, and steps 3 and 4 are skipped if the user is already logged in to Clever
  1. User clicks on the 'Log In with {IDP}' button - again, this step is skipped for districts that are using Clever-managed Passwords
  2. User enters in their credentials
  3. Clever kicks off the login process into the application.

Log In With Clever

Users will also often attempt to log in from an application's site directly, not using any portal. To allow users to use Instant Login to authenticate, you can embed a "Log in with Clever" (LIWC) button on your website.

A LIWC button is a link to https://clever.com/oauth/authorize with added parameters that define which application Clever should send the user to. The bare minimum of information that should be provided is:

  • Your application's client_id
  • Your application's redirect_uri
  • The type of response anticipated (in almost every case, we expect a code to be returned)

That's it. Here's a sample LIWC URL:


Clicking this link will actually take you to Clever's 'school picker,' which helps students find their district login page by searching for their school name. To reach a sandbox account, you'll actually search by the district ID. If you're using the example link above, you can go ahead and enter 53ee4b8a44abc88c1c00119b in the search box to reach the sandbox district's login page.

If your application has district-specific login pages, you can also add district_idas a parameter on the URL to skip the school picker and go straight to the district's login page. Example:


LIWC Button Assets

207 414 207 414

Instant Login: OAuth2 Authorization Grant Flow

Clever uses OAuth 2.0, an open standard used by many other identity providers (Google, Facebook, etc). If you've already worked with OAuth 2.0 before, you can skip to Setting Up Instant Login in Clever

The OAuth 2.0 specification) defines several methods of getting access to the API – the most common, and the one used here, is the Authorization Grant flow. Clever also supports the Implicit Grant flow, which is documented here.

Here are the steps that are taken once the login is started:

  1. Clever redirects the user to your application's redirect URI with a code appended
  2. Your application POSTs the code back to Clever's Identity API and requests a bearer token
  3. Clever responds with the token for the user
  4. Your application uses the bearer token to GETs https://api.clever.com/v2.1/me to get the IDs and the user's type
  5. Your application uses the token against Clever's Data API to acquire any additional information you need


While Clever's Data API has endpoints for roster information (and more), tokens acquired through the OAuth flow only have access to:

  • /me - provides user's type, Clever id, and district ID
  • /districts/district
  • /types/id (not a typo! type is singular, but the API endpoint uses the plural form. Expected values are student, teacher, school_admin, and district_admin)

Secure Sync allows you to access the entirety of the Data API, our matchmaking tools, and more.

Setting Up Instant Login in Clever


Enabling Instant Login

At the bottom of your application's settings page, you'll see your app's OAuth Settings.


Here, you'll define your Redirect URIs - the URL to which Clever will redirect your users and add a code at the start of the Authorization Grant flow. You can have more than one redirect URI, but please note that Clever will direct users to the first one in the list by default.

Redirect URI Requirements:

  • The redirect URI should point to a location where you expect to receive users' login attempts
  • Development applications can use non-HTTPS URIs, but please note that all production applications are required to use HTTPS URIs

You'll also want to enable Instant Login for users - check the boxes to show which user types your application will support. Your application will only allow logins from users of the selected types. If the box is not checked:

  • Users of the unselected type(s) will see a Clever error message if they attempt to log in through an Instant Login Link or Log In With Clever button.
  • Students & Teachers: the application will not appear in their Clever Portal
  • School & District Admins: the application will appear in their Clever Portal, but will have a flag indicating Instant Login is not supported for their user type. Clicking on the application icon will direct the user to the application's website

Authenticating Users

Acquiring a Code

When a user attempts to log in to your application, Clever will redirect them to your application. If the login is Clever-initiated (Portal or Instant Login Link), this will be your primary redirect URI. If the login is from a LIWC button, you may specify a different redirect_uri.

When a user is redirected to your redirect URI, you'll find the code parameter attached with a variable length string as its value:


At this point, you won't know who the user is or what type of user they are, but grab the code - you won't need to persist it for too long, but you will need it for the next step.

Redirect URI Parameters

Here are the parameters you can expect to see Clever add when redirecting users to your primary or specified redirect URI:

codeYesCode generated by Clever
scopeYesScope assigned to your application by Clever
stateOnly if provided via LIWC linkState value provided by your LIWC link

Exchanging the Code for a Token


It may take your application a few seconds to complete these next steps of the token exchange sequence. We recommend rendering a user interface as quickly as possible while you take care of these server-side steps in the background.

Once you have the code, you should exchange it for a token. To do this, you POST to https://clever.com/oauth/tokens. To assert the identity of your application, you must use your Client ID and Client Secret to formulate an HTTP Authentication header.

Using Basic Authentication

HTTP client libraries offer a few methods to compute basic authentication. If your library supports setting a username and password, you'll want to set the username to your Client ID and the password to your Client Secret.

HTTP Basic auth headers are also easy to compute yourself. Start by constructing a string containing your Client ID followed by a colon (":") character and your Client Secret, then encode that string in Base64. Set your Authorization HTTP header to this encrypted string preceded by the keyword Basic and a space:

basic_auth_header = "Authorization: Basic " + Base64.encode(client_id + ":" client_secret)

Building your POST Body

Clever accepts POSTs to oauth/tokens using both traditional web POST bodies of the application/x-www-form-urlencoded variety in addition to application/json. Make sure to always tell Clever what kind of content you're sending with an explicit Content-Type HTTP header.


Other POST body types, including multipart/form-data, are not accepted. If you receive 'invalid request / invalid content-type' error messages, make sure you're using either application/x-www-form-urlencoded or application/json

Ensure that you're properly escaping values in your POST bodies. In either approach, use UTF-8 characters. Proper URL-encoding is required for application/x-www-form-urlencoded requests.

HTTP libraries typically will take care of computing your Content-Length header β€” it is also required for POST requests.

The body of the request must have the following parameters:

codeheRte321The exchange code received on your redirect URI
grant_typeauthorization_codeThe type of exchange; always authorization_code in this sequence
redirect_urihttps://flightschool.edu/oauthThe exact redirect URI at which the code was received

Here's what a POST looks like using application/x-www-form-urlencode - note that the redirect URI is properly URL encoded:

POST https://clever.com/oauth/tokens
Authorization: Basic YW5WcFkyVnFkV2xqWldwMWFXTmxDZzpjY1hwWTR0cWRZbGVjNHAxYUdsMXVJ
Content-type: application/x-www-form-url-encoded
Content-length: 107

And here it is with application/json

POST https://clever.com/oauth/tokens
Authorization: Basic YW5WcFkyVnFkV2xqWldwMWFXTmxDZzpjY1hwWTR0cWRZbGVjNHAxYUdsMXVJ
Content-type: application/json
Content-length: 113

Acquiring the Token

Clever will respond with a token as long as:

  • client_id and client_secret are valid
  • redirect_uri matches where Clever sent the code
  • code is valid


Codes are valid for one minute, and may only be exchanged once.

The response looks like:

Content-type: application/json
Content-length: 33

After you consume this JSON response and take hold of this access token value in whichever way is appropriate for your environment, you'll want to use it to determine more information about its owner.

Store the token in a temporary location β€” in the next step, we'll receive their unique Clever ID and figure out whether it belongs to a student or teacher. Once we have that information, we'll want to store this access token in a secure place and use it whenever we're making requests on behalf of that user.


Tokens expire after 24 hours and cannot be refreshed - do not store the token for long-term user identification. User sessions expire after 2 hours.

Using the Token

Once the token is acquired, you should that token to GET the https://api.clever.com/v2.0/me endpoint - this endpoint should return the user's Clever id, district ID, and user type

Typically, once you've obtained the access token you will want to immediately determine its owner. Access tokens obtained through Clever SSO grant access to a subset of Clever's Data API.

In this section we will discover the identity of our mysterious user by using the access token we received in the previous step to issue a request to api.clever.com/v2.0/me.

Using bearer tokens

You now have an access token. It is yours to bear. Your application is the bearer of that access token. It is now your bearer token and it symbolizes the relationship between the user and your application.

Bearer tokens are easily used with any HTTP library that allows you to manually specify an HTTP Authorization header.

Your Authorization header value will be a string containing the word Bearer followed by a space character and then the access token value you received after exchanging your code.

If we were to issue a request using the bearer token we received in the last step, jsfUI2131da2f, our authorization header would look something like:

GET https://api.clever.com/some_clever_resource
Authorization: Bearer jsfUI2131da2f

What’s Next

Now that you know how Instant Login works and how it can be implemented, take a look at how to design a robust integration that best suits your application. Or check out a working example app.