Clever Developer Docs

Clever's Data Model

Here, we'll walk you through how records are related in our data model. You can query for related records using relative links returned in the response unless otherwise noted. For example, /schools/{id}/sections will return all sections whose primary school is {id} The diagram for each record type lists associated records. Associated records connected with a solid line have their IDs listed in the record object; records connected with a dotted line must be accessed through a relative link or other endpoint.

Schema

Below each object, we've added a sample record with available fields - we've sorted the fields for clarity, but they may be returned in any order. Please note the table as well, which outlines which fields are (and are not) guaranteed.

Field formats

  • Object ID: All Clever IDs take the ObjectID format. We guarantee that ObjectIDs are globally unique across districts and User objects.
  • String: Clever's strings have no maximum length - if you have to set maximum character lengths for fields, we recommend setting the max to 255 characters for safety.
  • Date: We normalize dates in Clever to YYYY-MM-DD: "2015-08-25"
  • Timestamp: Timestamps are expressed in this format: "2015-08-25T00:00:00.000Z"
  • Boolean: Booleans have a value of either "Y" or "N"

Links

Relative links are one way to discover and navigate to related data.

Let's examine the tail end of the JSON response to /me while using a student instant login token. Here's an example links node:

"links":
  [
    { "rel":"self","uri":"/me" },
    { "rel":"canonical","uri":"/v3.0/users/4fee004cca2e43cf2700028b" },
    { "rel":"district","uri":"/v3.0/districts/4feecb637de9810111e000002" }
  ]

Each relative link is structured:

rel - a string containing a keyword describing why you might be interested in the uri part
uri - a string containing the path component of a Clever API request

The rel keyword you're most interested in while handling this step is canonical. This is a fancy way of saying that the primary way to retrieve information about the object described in your API request is by requesting the path in the uri key.

To use that uri, you would attach the path component to https://api.clever.com. In the above canonical example, that would be https://api.clever.com/v3.0/users/4fee004cca2e43cf2700028b. This path will be accessible using the same instant login token or the appropriate district bearer token.

We strongly recommend following relative links to access related pieces of data. Constructing URLs by hand can be prone to errors and by following relative links, you'll be more resilient to access pattern changes in the Clever API.

Districts

Clever has a district-centric data model – our top level object is the district. Districts contain schools, terms, courses, sections, and users.

District object

"data":{
    "district_contact":"string",//Object ID: Globally unique and stable ID for district
    "error":"string",// String: Error state
    "id":"string",// ObjectID: Globally unique and stable ID for district created by Clever
    "last_sync":"string",
    "launch_date":"string",
    "login_methods":[
        // List of supported login types
    ],
    "mdr_number":"string",// String: MDR number
    "name":"string",// String: Name provided by district
    "nces_id":"string",//Federal NCES id for district
    "pause_end":"string",// Date: When district's data will be unpaused
    "pause_start":"string",// Date: When district's data will be paused
    "portal_url":"string",//String: URL where users log in to Clever
    "sis_type":"string",// String: Type of SIS district data originates from
    "state":"running",// String: District's sync status
}

Guaranteed fields

  • id
  • name
  • state - Possible values: ["running", "pending", "error", "paused", "success", ""] Pending means there is an error that the district can fix; Error means there is an error that Clever can fix. Paused means that the district's sync is paused to reflect last year's data.
  • last_sync - Populated as long as the district has synced data
  • launch_date
  • goals_enabled
  • portal_url
  • login_methods

Optional fields

  • mdr_number
  • nces_id
  • error - User-facing string describing a district error state. Typically useful only for district administrators. Should not be used to programmatically determine district status.
  • sis_type - Indicates the type of SIS this district's data originates from. "sftp" is returned when district data is synced via SFTP or CSV upload. Other string values vary.
  • pause_start
  • pause_end
  • district_contact

Related objects

The district object itself has only the name, Clever id, mdr_number, and nces_id (if assigned) of the district in question. You'll need to use separate endpoints to access the district's data. For example, since each token will give you access to only a single district, you should use https://api.clever.com/v3.0/schools. While courses, terms, and users with roles of contacts, school admins, and district admins are associated with a district, there is no relative link returned for these users on the district endpoint.

Instead, you can use:

Schools

While schools are not the highest-level object in Clever's data model, every user, term, course, and section must be associated with at least one school. User records can be associated with multiple schools!

School objects

"data":{
  "created":"string",// Timestamp: Resource creation date
  "district":"string",// ObjectID: Globally unique and stable ID for school's district
  "ext": {
    "": "" // String: Extension field names and values are defined by the district
  },
  "high_grade":"string",// String: School's exit grade level
  "id":"string",// ObjectID: Globally unique and stable ID for school created by Clever
  "last_modified":"string",// Timestamp: Last time resource was updated.
  "location": {
    "zip": "string", // String: School's zip code
    "address": "string", // String: School's street address
    "city": "string", // String: School's city
    "state": "string" // String: School's state
  },
  "low_grade":"string",// String: School's beginning grade level
  "mdr_number":"string",// String: School MDR number
  "name":"string",//String: Name provided by district
  "nces_id":"string",// String: School NCES ID
  "phone":"string",// String School's phone number
  "principal": { 
    "email": "string", // String: School's principal's email address
    "name": "string" // String: School's principal's name
  },
  "school_number":"string",// String: School identifier used by district or county
  "sis_id":"string",// String: Internal school identifier from SIS
  "state_id":"string"// String: State school identifier
}

Guaranteed fields

  • id
  • district
  • name
  • created
  • last_modified - Initializes to created date
  • sis_id
  • school_number

Optional fields

  • state_id
  • nces_id
  • mdr_number
  • low_grade - Possible values [ "1", … ,"13", "PreKindergarten", "TransitionalKindergarten", "Kindergarten", "InfantToddler", "Preschool", "PostGraduate", "Ungraded", "Other", ""]
  • high_grade - Possible values [ "1", … ,"13", "PreKindergarten", "TransitionalKindergarten", "Kindergarten", "InfantToddler", "Preschool", "PostGraduate", "Ungraded", "Other", ""]
  • principal
  • location
  • phone
  • ext

Related objects

To access the sections, courses, terms, or users associated with a school, use these endpoints:

Terms

Terms are an optional data type - these are only created if a district sends us term information.

Term objects

"data": {
   "id": "string", // ObjectID: Globally unique and stable ID for the term
   "district": "string", // ObjectID: Globally unique and stable ID for the term's district
   "name": "string", // String: Name provided by district
   "start_date": "string", // Date: Term's start date
   "end_date": "string" // Date: Term's end date
 }

Guaranteed fields

  • id
  • district
  • At least one of the optional fields listed below

Optional fields

  • name
  • start_date
  • end_date

Related objects

To retrieve a list of the section objects associated with a term, use /terms/{id}/sections.

Courses

Courses are an optional data type - courses are only created if a district chooses to sync course information to Clever.

Course objects

"data": {
    "id": "string", // ObjectID: Globally unique and stable ID for the course
    "district": "string", // ObjectID: Globally unique and stable ID for the course's district
    "name": "string", // String: name provided by district
    "number": "string" // String: course number provided by district
}

Guaranteed fields

  • id
  • district
  • At least one of the optional fields listed below

Optional fields

  • name
  • number

Related objects

To retrieve a list of the section objects associated with a course, use /courses/{id}/sections.

Sections

Sections (analagous to classes) tie teachers and students together.

Section objects

"data":{
  "course":"string",// ObjectID: Globally unique and stable ID for section's course
  "created":"string",// Timestamp: Resource initialization date
  "district":"string",// ObjectID: Globally unique and stable ID for section's district
  "ext":{
    // String: Extension field names and values are defined by the district
  },
  "grade":"string",// String: Grade associated with section
  "id":"string",// Globally unique and stable ID for the section
  "last_modified":"string",// Timestamp: Last time resource was updated
  "name":"string",// String: Name provided by district or generated by Clever
  "period":"string",// String: Bell schedule information for the section   
  "school":"string",// ObjectID: Globally unique and stable ID for section's school
  "section_number":"string",// String: Section number set by school or district
  "sis_id":"string",// String: Internal section identifier from SIS
  "students":[""],// List of ObjectIDs: List of IDs of students enrolled in section
  "subject":"string",// String: Subject associated with section
  "teacher":"string",// ObjectID: Globally unique and stable ID for section's primary teacher
  "teachers":[""],// List of ObjectIDs: List of IDs of teachers assocated with section,
  "term_id":"string"// ObjectID: Globally unique and stable ID for section's term
}

Guaranteed fields

  • id
  • district
  • school
  • created
  • last_modified
  • name - Clever generates a section name by concatenating "course_name" "- teacher_last_name" and "- period", e.g. Algebra - Smith - Period 3. If course name is not present, the section name from the source system is used.
  • sis_id
  • subject - Possible values: ["english/language arts","math","science","social studies","language","homeroom/advisory", "interventions/online learning","technology and engineering","PE and health","arts and music","other",""]
  • students
  • teacher
  • teachers

Optional fields

  • grade - Possible values [ "1", … ,"13", "PreKindergarten", "TransitionalKindergarten", "Kindergarten", "InfantToddler", "Preschool", "PostGraduate", "Ungraded", "Other", ""]
  • course
  • term
  • section_number
  • period
  • ext

Related objects

Each section has a primary school and contains students and teacher objects. But be careful, the students and teachers may have a different primary school than the section. For example, an elementary student may be enrolled in a middle school math class.

You'll notice that the section has a teacher field as well as a list of teachers. If a section has more than one teacher, additional teachers are listed in the teachers array. We recommend importing all teachers, not just the primary teacher.

Users

User objects

The User object is a brand new object within Clever's Data Model, and is reflected in updates to other objects and endpoints as well. The User object consolidates all user types, namely students, teachers, contacts, district admins, and staff.

"data":{
    "created":"string",// ObjectID: Globally unique and stable ID for student
    "district":"string",// ObjectID: Globally unique and stable ID for users' district
    "email":"string",//String: Email address provided by district
    "id":"string",//ObjectID: Globally unique and stable ID for User
    "last_modified":"string",// Timestamp: Last time resource was modified
    "name":{
      "first":"string",// String: First name provided by district
      "last":"string",// String: Last name provided by district
      "middle":"string"// String: middle name provided by district
    },
    "roles":{
      "contact":{
        "legacy_id":"string",// Former Clever ID for User record
        "phone":"string",// String: Contact phone number
        "phone_type":"Cell",// String: Phone number type
        "sis_id":"string",// String: Internal identifier for contact assigned by SIS
        "student_relationships":[
          // String: Students the contact has a relationship with
        ]
      },
      "district_admin":{
        "legacy_id":"string",// Former Clever ID for User record
        "title":"string"// String: Title provided by district
      },
      "staff":{
        "credentials": {
          "district_username": "" // String: District-specified username
        },
        "department":"string",// String: Department provided by district
        "ext": {
          // String: Extension field names and values are defined by the district
        },
        "legacy_id":"string",// Former Clever ID for User record
        "roles":[
          "string" // Staff role, either PortalOnly or SchoolTechLead
        ],
        "schools":[
          "string" // All schools this User is associated with
        ],
        "staff_id":"string",// String: Identifier provided by district
        "title":"string",// String: Title provided by district
      },
      "student":{
        "created":"string",// Timestamp: Resource creation date
        "credentials":{
            "district_username":"string"// String: District-specified student username
        },
        "dob":"string",// String: Student birthdate
        "ell_status":"Y",
        "enrollments": { //For student school enrollment tracking
          "school": "", // ObjectID: Globally unique and stable ID for the school
          "start_date": "", // Date: When student first enrolled in the school in                       Clever
          "end_date": "", // Date: When student's enrollment in the school ended
        },
        "ext": {
          "": "" // String: Extension field names and values are defined by the                             district
        },
        "gender":"M",// String: User gender 
        "grade":"InfantToddler",// String: User grade
        "graduation_year":"string",// String: Graduation year provided by district
        "hispanic_ethnicity":"Y",// Boolean: User's hispanic/latino ethnicity
        "last_modified":"string",// Timestamp: Last time resource was modified
        "legacy_id":"string",// Former Clever ID for User record
        "location": {
          "state": "", // String: User state
          "zip": "", // String: User zip
          "address": "", // String: User street address
          "city": "", // String: User city
          "lat": "", // String: User address latitude (Deprecated)
          "lon": "" // String: User address longitude (Deprecated)
       },
       "race":"Caucasian",// String: User race
       "school":"string",// ObjectID: Globally unique and stable ID for the student's primary school
       "schools":[
        // List of ObjectIDs: List of IDs for schools student is associated with
       ],
       "sis_id":"string",// String: Internal student identifier from SIS
       "state_id":"string",// String: State student identifier
       "student_number":"string",// String: Student number provided by district
      },
      "teacher":{
        "created":"string",// Timestamp: Resource initialization date
        "credentials":{
            "district_username":"string"// String: District-specified username for teacher
       },
        "district":"string",// ObjectID: Globally unique and stable ID for User's district
        "ext": {
          "": "" // String: Extension field names and values are defined by the district
        },
        "last_modified":"string",// Timestamp: Last time resource was updated
        "legacy_id":"string",// Former Clever ID for User record
        "name": {
          "first": "", // String: First name provided by district
          "last": "", // String: Last name provided by district
          "middle": "" // String: Middle name provided by district
        },
        "school":"string",// ObjectID: Globally unique and stable ID for User's primary school
        "schools":[
         // List of ObjectIDs: List of IDs for all schools User is associated with
        ],
        "sis_id":"string",//String: Internal teacher identifier from SIS
        "state_id":"string",// String: State teacher identifier
        "teacher_number":"string",// String: Teacher number provided by district
        "title":"string"// String: Title provided by district
    }
}

Guaranteed fields

  • id
  • district
  • school
  • schools
  • created
  • last_modified
  • sis_id
  • name.first
  • name.last
  • enrollments
  • roles - Possible values: ["contact", "district_admin", "staff", "student", "teacher"]

Optional fields

  • name.middle
  • email
  • student_number
  • state_id
  • credentials.district_username
  • gender - Possible values: ["M", "F"]
  • race - Possible values: ["Caucasian", "Asian", "Black or African American", "American Indian", "Hawaiian or Other Pacific Islander", "Two or More Races","Unknown", ""]
  • hispanic_ethnicity
  • location
  • graduation_year
  • grade
  • home_language
  • ext
  • enrollments

Related objects

📘

Important caveats around using student contact data

While we offer student contact information, it is not normalized in the same way that other data is in Clever. Please note:

  • The quality and formatting of student contact data can vary between SISs
  • Contacts without sis_id populated are not stable - if any data on the contact changes (such as name, email, or phone number), the contact will be deleted and a new one will be created with a new Clever ID.

For more information, check out our page on Contacts

Updated 4 months ago


Clever's Data Model


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.