Build a Student-Facing Roster App

Use Clever SSO and Secure Sync to authenticate students and retrieve their roster data.

Build a student-facing app that uses Clever SSO to identify a student and Secure Sync to retrieve that student’s classes, teachers, and contacts when needed.

Prerequisites

  1. Configure SSO and Secure Sync for your application.
  2. Configure a production HTTPS redirect URI.
  3. Store the district-app token for each connected district.

1. Authenticate and identify the student

Use the OAuth authorization-code flow, then call /v3.0/me with the user access token. Establish your app session with the returned Clever user ID and district ID.

Confirm the signed-in user has the student role before showing a student experience. Use a district-app token to retrieve the complete user record when role-aware routing is required.

2. Retrieve the student record

Call GET /v3.1/users/{student_id} with the district-app token. Follow the student’s relationship links to retrieve sections, teachers, and contacts when your product needs them.

Use the district-app token for these calls. The OAuth user access token only identifies the signed-in user and does not provide full roster access.

3. Support multiple classes and schools

A student can have multiple sections and can attend sections outside their primary school. Build a multi-class experience, or define a clear selection strategy that remains correct when enrollment changes.

Do not assume each student has a class. Render an empty state for students with no shared sections.

4. Handle contacts and sensitive fields carefully

Contacts are not guaranteed, their types vary by SIS, and a contact’s full name is stored in last_name. Contacts without sis_id can receive a new Clever ID when their data changes.

Sensitive student fields require district and application opt-in. Do not assume iep_status, ell_status, or frl_status are present.

5. Render the student experience

Use Clever IDs as primary keys. If a shared record returns 404, archive the local record if it exists or skip it if it does not, then continue processing.

Related documentation


Did this page help you?