Our Clever Users
The Friendship of Clever and Khan Academy

Khan Academy, by the valiant efforts of Coach and Class, is on its way to becoming an Instant Login Provider for Clever. Here is a summary of why we’re doing this, how things are going, and some technical details on how it all works.
Clever, for those unfamiliar, is a FERPA-compliant platform for modern learning software that magically works with many legacy Student Information Systems (SIS) — making it easy for school districts to provision student accounts with applications on Clever’s platform. With the release of “Clever Instant Login,” this process is made even easier by freeing students and teachers the burden of memorizing dozens of separate passwords.
Applications built to support Clever Instant Login suddenly open their doors to students and teachers from over 30,000 schools in the US. About one in five. Khan Academy is now one such application.
So what does the integration look like?
We start at the Instant Login Portal for a given student. Students (or teachers) will see applications here that have been enabled by their district manager.

Clicking this application brings the student to the Clever onboarding process, where we give them the option to log in to their existing account to link their classroom from Clever. Otherwise, we provision a new account for them before linking any classroom data.

Clicking no displays a text box and prompts for the user’s email address (or, if they’re under the age of 13, their parent’s email address). We do this solely for account recovery purposes — in case the student switches school districts and can no longer access this account through their Clever dashboard.


Of course, students and teachers can entirely skip this process either by clicking either “Not now” or “I don’t know their email.” If that’s the case, we’ll ping them later on the site through a thin notification bar at the top of the screen.
Either way, the Clever user can now use Khan Academy without the need to remember a password.

Back to the original “Do you have an account?” prompt: Clicking yes displays a log in form, plus some additional links if they’ve forgotten a password or decided they don’t actually have an account. We also show an option to log in with either Facebook or Google/Gmail.


Going through this process signs our student or teacher in as usual, and in the background takes care of importing any classroom data from Clever. This includes the user’s clever ID, their district’s ID, and some data on what classrooms they are in. We use this data to build coach-student relationships that the students and teachers have already established in their Student Information System.
From the point of view of the student or teacher, this onboarding step is just a few short clicks to a new Khan Academy account, or bringing in some classroom data to an existing one.

When a Clever student or teacher decides to return, clicking the Khan Academy application from their Instant Login Portal logs them into the account they created or linked earlier, with no onboarding process necessary. We’ll sync their classroom data with Khan Academy on each subsequent login if anything has changed.
What is this “classroom data” you speak of?
Accessing Khan Academy through Clever Instant Login follows a traditional OAuth flow, and as such allows us to access some of the user’s data from Clever via an access token. We use this access token to fetch data from a custom, “anonymized” Instant Login API that Clever has built for us. In particular, we grab the following for students logging in:
- First name
- Date of birth
- Their Clever ID, as well as their district’s Clever ID
And for teachers logging in:
- First and last name
- Their Clever ID, as well as their district’s Clever ID
We also import section data for both students and teachers. This is what allows us to establish coach-student relationships on Khan Academy from those which already exist in the district’s SIS.
At its core, the Sections API returns a list of classrooms with the teacher’s Clever ID, the name of the class, and — depending on who’s asking — the list of students in the class. From this we extract coach-student pairs which, when “acknowledged” from both sides, turn into coach-student relationships on Khan Academy. This means coaches can track student progress, monitor student activity, and recommend skills for them to practice.
Teachers logging in will see their classrooms from Clever (which, again, come from the district’s SIS), full of “Clever Student” placeholders. These entries will slowly populate into student usernames as they log in, or might already show up if the students have logged in first.

How does this all work?
Here is a technical breakdown of our Clever integration.
We currently have two Clever Instant Login applications: Khan Academy CIL Dev (for development purposes), and Khan Academy Login (our production app). Each has a pair of API keys, and a redirect URI:
(prod) https://www.khanacademy.org/login/clever
(dev) http://localhost:8080/login/clever
We follow a traditional OAuth flow as follows:
- Clicking the application redirects the user to one of the above URIs with a given code (which we use), and a few application scopes (which we ignore).
- We use this one-time code by redeeming it for an access token. To do this we POST to https://clever.com/oauth/tokens with three pieces of data. (1) our code (2) the field “grant_type” set to the string “authorization_code” and (3) the redirect URI which exactly matches the one found in our OAuth application’s settings.
- We receive an OAuth access token, which we can then use to fetch data from the Clever API (as limited by our applications scopes, which I’ll explain later). We store this access token in a cookie.
- Using the access token, we fetch the user’s clever ID and their “role” (student or teacher). If the ID matches that of a user already in our system, we log them in and redirect them to /postlogin?type=clever.
- Otherwise, we prepare the onboarding page for them. To do so we first need to fetch the user’s birthdate (to determine if we should prompt for their email address or their parent’s). We then render the onboarding template with this data.
Which brings us to the front-end. I’ve already posted some screenshots earlier so I will be somewhat brief.
- A prompt is displayed to the user, asking if they already have a Khan Academy account. Clicking “No” then asks them for either their email or their parent’s email for account recovery purposes.
- Entering in their email posts to /login/clever/email. This route firsts fetches the OAuth access token from the cookie, uses it to provision an account, then attaches the provided email as an “UnverifiedAuthEmail” to the newly-created account. The account is then logged in and the client is redirected to /postlogin?type=clever.
- Entering your parent’s email takes a similar path along /login/clever/parentemail, but instead calls either UserData.link_parent or UserData.link_pending_parent on the newly-created account, using the provided email. We also redirect the client to /postlogin?type=clever.
- Recall that our users can skip this step by either clicking “Not now” or “I don’t know their email.” Clicking either of these links brings you to /login/clever/cookie. This route behaves the same way as the ones previously mentioned, in that it uses the access token from the cookie to provision an account, which it then logs the user into before redirecting them to /postlogin?type=clever.
On the other hand, if the user selects “Yes! Sign me in!” to the original prompt…
- We first show them a username/email and password form. This form POSTs to /login with AJAX with a “continue” url property set to /postlogin with the following values: (a) “type” set to “password” (b) “linkclever” set to “1" (c) “isteacher” set to “1" if our user has the teacher role in clever and (d) yet another continue field set to “/”.
This logs the user in with the given credentials and returns a JSON response with a continue URL (or an error message if the credentials were invalid). The original continue URL we sent to /login tells the client to redirect to /postlogin with a few fields. We set the type to “password” this time, since they’re not logging in through clever, but we do populate a new field — “linkclever” — which tells /postlogin to link clever data. I’ll go into more detail later. Lastly, the “isteacher” field sets the “teacher” flag on the logged-in user so that they see the coach homepage. - Below this username/email/password form is a link for users who use a third-party to log in. Clicking this displays Facebook and Gmail (Google) buttons — which are wired up with similar /postlogin URLs (except the “type” is not set to “password” but either “facebook” or “google”).
- There is also a password recovery form in case third-party logins are blocked on our user’s network. This is a simple form which POSTs to /forgotpw with an entered email address.
Now, back to the backend. As the saying goes, “all roads lead to /postlogin,” and our Clever integration is no different. We can arrive here in a number of ways, but we’ll always have either type=clever or linkclever=1 in the request. The former is used for conversions, but having either flag set will trigger a data import from clever, using the hefty CleverOAuthClient.import_classroom_data method. In /postlogin:
- First, we’ll fetch the OAuth access token from the user’s cookies. We have to do this to fetch Clever information because users who link an existing account will never hit one of our /login/clever/* routes (they’ll log in like normal, but with this extra “linkclever” flag).
- We use the token to fetch the user’s Clever ID and role. Then we call CleverOAuthClient.import_classroom_data.
- This method uses Clever’s Section API mentioned earlier to fetch all of the sections for the provided user. We extract teacher-student pairs from this API endpoint, either by iterating through all of a given teacher’s classes, or all the classes a particular student is enrolled in. Before we do this, we check the “last_modified” flag on each of the sections. If this timestamp is less than the “clever_last_sync” field in the current user’s UserDataInfo, we do not attempt to sync the section.
- For each pair, we “acknowledge” a CleverCoachRequest, keeping track of which user logged in to trigger this “acknowledgement.”
- If the CleverCoachRequest does not exist for this pair, we create it and mark that is has been initiated by the user who logged in.
- If the corresponding CleverCoachRequest does in fact exist, we check which party initiated it. If the current user matches the user who initiated the request, we do nothing, because the user has simply logged in twice.
- On the other hand, if the user acknowledging the request did not initiate it, that means both parties have showed intent to connect by logging in through Clever. We then connect the two parties to form a coach-student relationship. Now the teacher can track the student’s progress, monitor their activity, and recommend skills for them to practice. Likewise, the student will now see the teacher in their list of coaches.
Closing notes
The steps outlined above are what it takes to give Clever users access to Khan Academy without the need to remember a password, while allowing them to bring their existing SIS data along with them.
There are a lot of moving parts in this integration, and a lot of deliberation took place to make sure we only receive the data we need (and not a byte more). The folks at Clever have been a dream to work with, their product and developer resources are amazing, and I look forward to continuing on this journey with them.
If you have any questions, comments, or concerns about our new integration with Clever Instant Login, please let me know.
Thanks for reading.