Introduction
STUDENT QUERY
query {
Me {
first_name
last_name
Person {
... on Student {
gender
middle_names
}
}
}
}
STUDENT RESPONSE
{
"data": {
"Me": {
"first_name": "GraphiQL",
"last_name": "Explorer",
"Person": {
"gender": "male",
"middle_names": "Chris"
}
}
}
}
Welcome to the Wonde GraphQL API documentation.
This Wonde API utilises GraphQL to allow you to write powerful, targeted queries which get you to the data you require, in the format you specify.
The simple example query and response alongside is just a starting point. Once you learn the basics, you will be able to write queries which return complex sets of data which would previously have required multiple calls to different REST endpoints.
For more general details on GraphQL, the following pages are a good starting point:
The API documentation will start with a general overview about the design and technology that has been implemented, followed by reference information about specific objects which can be returned via GraphQL.
Examples & Explorer
To help you get started with the Single Sign-On API as quickly as possible we have produced a few examples:
OAuth Examples
GraphQL Explorer
Once you have your access token you can use it to call the GraphQL API. You can explore the available datasets with the Wonde API explorer.
Below you will find a few example queries you can run on the SSO API:
- Student with groups and classes
- Contact with associated children
- Employee with associated classes and groups
Scopes
After authorisation, the data available is dependant on your active scopes. Scopes are specific to your access token and the school being accessed (if applicable).
Scopes exist for objects and their properties. Not having an active scope for a property's value will be either omit the property (if an object), or return it as null
(if a value).
Errors
ERROR RESPONSE
"data": {
...
"errors": [
{
"message": "An error has occurred."
}
]
}
If you are familiar with REST API's you might expect to use the HTTP status code of a response to decide whether the response is successful, not found, has errors, is unauthorised etc.
This is not the case with a GraphQL API. Your response will always have a 200
(successful) status code, and will only return data which you are authorised to receive.
In addition, any errors will be presented in an errors
element separate to the rest of the query result.
OAuth2 Overview
OAUTH 2 is used to manage access to the API.
Note: Before you can access the API, you will need to add your application via the Wonde dashboard. This will also create an Oauth2 client, and you will be provided with your Oauth2 credentials. The client secret should never be made public.
OAuth2 Flow
OAuth2 allows users to authenticate access to your application, which then receives an authorisation token, which is exchanged for an access token prior to use. The steps involved in this process are detailed below.
An example of each step is included as well, which should be adapted for your choice of language. Note that the tokens in these examples have been truncated - they will normally be large, secure strings.
1: User authorise
https://wonde_edu/oauth/authorize?
client_id=YOUR_CLIENT_ID&
redirect_uri=YOUR_REDIRECT_URI&
state=YOUR_STATE&
response_type=code&
scope=
The user should be redirected to Wonde for them to authenticate (login), and authorise the requested access.
You can create test accounts to allow you to login as the various user types while developing your application.
The state parameter is optional and can be used by your application to store request-specific data and/or prevent CSRF attacks. The authorization server will return the unmodified state value back to your application appended to your redirect uri.
2: Redirect back
https://YOUR_REDIRECT_URI/callback?code=YOUR_AUTH_CODE&state=YOUR_STATE
They will be redirected back to your application, along with an authorisation code.
3: Request access token
curl -X POST -H "Content-Type: application/json" -d '{
"grant_type": "authorization_code",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"redirect_uri": "YOUR_REDIRECT_URI",
"code": "YOUR_AUTH_CODE"
}' "https://wonde_api/oauth/token"
{
"token_type": "Bearer",
"expires_in": 31536000,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"refresh_token": "def50200393d994205d8ae0f..."
}
Your application can now make a POST request to Wonde, along with the authorisation code retrieved in the previous step. This will return an access token, and a refresh token.
4: Access API
curl -X POST https://wonde_api/graphql/me \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGc... \
-d '{ "query": "{ Me { id } }" }'
You can now access the API using the access token retrieved in the previous step, by including the retrieved token in your request header.
5: Refresh access token
curl -X POST -H "Content-Type: application/json" -d '{
"grant_type": "refresh_token",
"refresh_token": "def50200393d994205d8ae0f...",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}' "https://wonde_api/oauth/token"
{
"token_type": "Bearer",
"expires_in": 31536000,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGci...",
"refresh_token": "def50200e0b940a83106d6c9..."
}
You can refresh your access token without requiring the user to re-authorise the access by sending a POST request containing your refresh token. This will then be exchanged for a new new access token.
Test Accounts
To help you develop your application, we provide you with SSO test accounts to represent student, employee and contact users.
To view them, simply visit Settings > SSO > Test Accounts in your Wonde dashboard. For employee and contact accounts, you will need to set a unique email address for each one you want to use.
If you need to create email addresses for this purpose, many options are available.
Credentials
Oauth2 uses a Client ID, Client Secret and Redirect URL as part of the authentication flow.
Your Client ID and Client Secret are available by visiting SSO > Settings in your Wonde dashboard settings, and your Redirect URL can be viewed and updated here also.
Types Overview
This endpoint contains data about the authenticated user. All queries should start with the Me object, with the desired fields and sub-objects specified within.
Make queries at https://wonde_api/graphql/me
Graph Explorer
You can also use the Graph Explorer to explore this endpoint interactively. Examples of each object are included here which you can copy and paste into Graph Explorer when building your queries.
Contact
Contact {
id
type
title
forename
middle_names
surname
gender
upi
created_at
updated_at
date_of_birth
ContactDetails
Students
School
}
Name | Type | Additional |
---|---|---|
id | ID | |
type | PersonType (Enum) |
Possible values:
|
title | String | |
forename | String | |
middle_names | String | |
surname | String | |
gender | Gender (Enum) |
Possible values:
|
upi | String | |
created_at | Date | |
updated_at | Date | |
date_of_birth | Date | |
ContactDetails | ContactContactDetails | |
Students | Array of ContactStudent |
Arguments:
|
School | School |
ContactContactDetails
ContactContactDetails {
telephone
telephone_home
telephone_primary
telephone_work
telephone_mobile
email_home
email_primary
email_work
address_house_number
address_house_name
address_apartment
address_street
address_district
address_town
address_county
address_postcode
address_country
work_address_house_number
work_address_house_name
work_address_apartment
work_address_street
work_address_district
work_address_town
work_address_county
work_address_postcode
work_address_country
email
}
Name | Type | Additional |
---|---|---|
telephone | String | |
telephone_home | String | |
telephone_primary | String | |
telephone_work | String | |
telephone_mobile | String | |
email_home | String | |
email_primary | String | |
email_work | String | |
address_house_number | String | |
address_house_name | String | |
address_apartment | String | |
address_street | String | |
address_district | String | |
address_town | String | |
address_county | String | |
address_postcode | String | |
address_country | String | |
work_address_house_number | String | |
work_address_house_name | String | |
work_address_apartment | String | |
work_address_street | String | |
work_address_district | String | |
work_address_town | String | |
work_address_county | String | |
work_address_postcode | String | |
work_address_country | String | |
String |
ContactDetails
ContactDetails {
telephone
telephone_home
telephone_primary
telephone_work
telephone_mobile
email_home
email_primary
email_work
address_house_number
address_house_name
address_apartment
address_street
address_district
address_town
address_county
address_postcode
address_country
work_address_house_number
work_address_house_name
work_address_apartment
work_address_street
work_address_district
work_address_town
work_address_county
work_address_postcode
work_address_country
email
}
Name | Type | Additional |
---|---|---|
telephone | String | |
telephone_home | String | |
telephone_primary | String | |
telephone_work | String | |
telephone_mobile | String | |
email_home | String | |
email_primary | String | |
email_work | String | |
address_house_number | String | |
address_house_name | String | |
address_apartment | String | |
address_street | String | |
address_district | String | |
address_town | String | |
address_county | String | |
address_postcode | String | |
address_country | String | |
work_address_house_number | String | |
work_address_house_name | String | |
work_address_apartment | String | |
work_address_street | String | |
work_address_district | String | |
work_address_town | String | |
work_address_county | String | |
work_address_postcode | String | |
work_address_country | String | |
String |
ContactStudent
ContactStudent {
id
type
forename
middle_names
surname
gender
created_at
updated_at
date_of_birth
ContactDetails
Photo
Groups
Classes
School
}
Name | Type | Additional |
---|---|---|
id | ID | |
type | PersonType (Enum) |
Possible values:
|
forename | String | |
middle_names | String | |
surname | String | |
gender | Gender (Enum) |
Possible values:
|
created_at | Date | |
updated_at | Date | |
date_of_birth | Date | |
ContactDetails | StudentContactDetails | |
Photo | Photo | |
Groups | Array of StudentGroup |
Arguments:
|
Classes | Array of StudentClass |
Arguments:
|
School | School |
Date
Date {
datetime
timezone_type
timezone
}
Name | Type | Additional |
---|---|---|
datetime | String | |
timezone_type | String | |
timezone | String |
Employee
Employee {
id
type
title
forename
middle_names
surname
gender
upi
created_at
updated_at
date_of_birth
ContactDetails
Groups
Classes
Photo
School
}
Name | Type | Additional |
---|---|---|
id | ID | |
type | PersonType (Enum) |
Possible values:
|
title | String | |
forename | String | |
middle_names | String | |
surname | String | |
gender | Gender (Enum) |
Possible values:
|
upi | String | |
created_at | Date | |
updated_at | Date | |
date_of_birth | Date | |
ContactDetails | EmployeeContactDetails | |
Groups | Array of EmployeeGroup |
Arguments:
|
Classes | Array of EmployeeClass |
Arguments:
|
Photo | Photo | |
School | School |
EmployeeClass
EmployeeClass {
id
name
description
created_at
updated_at
Subject
Employees
Students
Lessons
}
Name | Type | Additional |
---|---|---|
id | ID | |
name | String | |
description | String | |
created_at | Date | |
updated_at | Date | |
Subject | Subject | |
Employees | Array of EmployeeEmployee |
Arguments:
|
Students | Array of EmployeeStudent |
Arguments:
|
Lessons | Array of EmployeeLesson |
Arguments:
|
EmployeeContactDetails
EmployeeContactDetails {
telephone
telephone_home
telephone_primary
telephone_work
telephone_mobile
email_home
email_primary
email_work
address_house_number
address_house_name
address_apartment
address_street
address_district
address_town
address_county
address_postcode
address_country
work_address_house_number
work_address_house_name
work_address_apartment
work_address_street
work_address_district
work_address_town
work_address_county
work_address_postcode
work_address_country
email
}
Name | Type | Additional |
---|---|---|
telephone | String | |
telephone_home | String | |
telephone_primary | String | |
telephone_work | String | |
telephone_mobile | String | |
email_home | String | |
email_primary | String | |
email_work | String | |
address_house_number | String | |
address_house_name | String | |
address_apartment | String | |
address_street | String | |
address_district | String | |
address_town | String | |
address_county | String | |
address_postcode | String | |
address_country | String | |
work_address_house_number | String | |
work_address_house_name | String | |
work_address_apartment | String | |
work_address_street | String | |
work_address_district | String | |
work_address_town | String | |
work_address_county | String | |
work_address_postcode | String | |
work_address_country | String | |
String |
EmployeeEmployee
EmployeeEmployee {
id
type
title
initial
surname
role
created_at
updated_at
}
Name | Type | Additional |
---|---|---|
id | ID | |
type | PersonType (Enum) |
Possible values:
|
title | String | |
initial | String | |
surname | String | |
role | String | |
created_at | Date | |
updated_at | Date |
EmployeeGroup
EmployeeGroup {
id
name
code
type
description
notes
created_at
updated_at
Employees
Students
}
Name | Type | Additional |
---|---|---|
id | ID | |
name | String | |
code | String | |
type | GroupType (Enum) |
Possible values:
|
description | String | |
notes | String | |
created_at | Date | |
updated_at | Date | |
Employees | Array of EmployeeEmployee |
Arguments:
|
Students | Array of EmployeeStudent |
Arguments:
|
EmployeeLesson
EmployeeLesson {
id
period_instance_id
created_at
updated_at
start_at
end_at
Period
Room
Employee
}
Name | Type | Additional |
---|---|---|
id | ID | |
period_instance_id | String | |
created_at | Date | |
updated_at | Date | |
start_at | Date | |
end_at | Date | |
Period | Period | |
Room | Room | |
Employee | EmployeeEmployee |
EmployeeStudent
EmployeeStudent {
id
type
forename
middle_names
surname
gender
created_at
updated_at
date_of_birth
}
Name | Type | Additional |
---|---|---|
id | ID | |
type | PersonType (Enum) |
Possible values:
|
forename | String | |
middle_names | String | |
surname | String | |
gender | Gender (Enum) |
Possible values:
|
created_at | Date | |
updated_at | Date | |
date_of_birth | Date |
Me
Me {
id
first_name
last_name
email
mobile
School
Students
Person
People
LinkedAccounts
}
Note that the Person field is a Union type, so you should query it using the GraphQL fragment syntax.
UNION EXAMPLE
Me {
Person {
...on Student {
Classes
}
...on Contact {
work_email
}
...on Employee {
Lessons
}
}
}
Name | Type | Additional |
---|---|---|
id | ID | |
first_name | String | |
last_name | String | |
String | ||
mobile | String | |
School | School | |
Students | Array of ContactStudent |
Arguments:
|
Person | PersonTypes (Union) |
Possible types: |
People | Array of PeopleTypes | |
LinkedAccounts | Array of Me |
Period
Period {
id
start_time
end_time
name
day
created_at
updated_at
}
Name | Type | Additional |
---|---|---|
id | ID | |
start_time | String | |
end_time | String | |
name | String | |
day | String | |
created_at | Date | |
updated_at | Date |
Photo
Photo {
id
content
created_at
updated_at
}
Name | Type | Additional |
---|---|---|
id | ID | |
content | String |
Base64 encoded file |
created_at | Date | |
updated_at | Date |
Room
Room {
id
name
code
created_at
updated_at
}
Name | Type | Additional |
---|---|---|
id | ID | |
name | String | |
code | String | |
created_at | Date | |
updated_at | Date |
School
School {
id
name
mis
la_code
establishment_number
urn
active
la_name
phase_of_education
address_line_1
address_line_2
address_town
address_postcode
country
}
Name | Type | Additional |
---|---|---|
id | String | |
name | String | |
mis | String | |
la_code | String | |
establishment_number | String | |
urn | String | |
active | Boolean | |
la_name | String | |
phase_of_education | String | |
address_line_1 | String | |
address_line_2 | String | |
address_town | String | |
address_postcode | String | |
country | String |
Student
Student {
id
type
forename
middle_names
surname
gender
upi
created_at
updated_at
date_of_birth
ContactDetails
Groups
Classes
Photo
School
}
Name | Type | Additional |
---|---|---|
id | ID | |
type | PersonType (Enum) |
Possible values:
|
forename | String | |
middle_names | String | |
surname | String | |
gender | Gender (Enum) |
Possible values:
|
upi | String | |
created_at | Date | |
updated_at | Date | |
date_of_birth | Date | |
ContactDetails | ContactDetails | |
Groups | Array of StudentGroup |
Arguments:
|
Classes | Array of StudentClass |
Arguments:
|
Photo | Photo | |
School | School |
StudentClass
StudentClass {
id
name
description
created_at
updated_at
Subject
Employees
Lessons
}
Name | Type | Additional |
---|---|---|
id | ID | |
name | String | |
description | String | |
created_at | Date | |
updated_at | Date | |
Subject | Subject | |
Employees | Array of StudentEmployee |
Arguments:
|
Lessons | Array of StudentLesson |
Arguments:
|
StudentContact
StudentContact {
id
title
initial
surname
relationship
created_at
updated_at
}
Name | Type | Additional |
---|---|---|
id | ID | |
title | String | |
initial | String | |
surname | String | |
relationship | String | |
created_at | Date | |
updated_at | Date |
StudentContactDetails
StudentContactDetails {
telephone
telephone_home
telephone_primary
telephone_work
telephone_mobile
email_home
email_primary
email_work
address_house_number
address_house_name
address_apartment
address_street
address_district
address_town
address_county
address_postcode
address_country
work_address_house_number
work_address_house_name
work_address_apartment
work_address_street
work_address_district
work_address_town
work_address_county
work_address_postcode
work_address_country
email
}
Name | Type | Additional |
---|---|---|
telephone | String | |
telephone_home | String | |
telephone_primary | String | |
telephone_work | String | |
telephone_mobile | String | |
email_home | String | |
email_primary | String | |
email_work | String | |
address_house_number | String | |
address_house_name | String | |
address_apartment | String | |
address_street | String | |
address_district | String | |
address_town | String | |
address_county | String | |
address_postcode | String | |
address_country | String | |
work_address_house_number | String | |
work_address_house_name | String | |
work_address_apartment | String | |
work_address_street | String | |
work_address_district | String | |
work_address_town | String | |
work_address_county | String | |
work_address_postcode | String | |
work_address_country | String | |
String |
StudentEmployee
StudentEmployee {
id
title
initial
surname
role
created_at
updated_at
}
Name | Type | Additional |
---|---|---|
id | ID | |
title | String | |
initial | String | |
surname | String | |
role | String | |
created_at | Date | |
updated_at | Date |
StudentGroup
StudentGroup {
id
name
code
type
description
notes
created_at
updated_at
Employees
}
Name | Type | Additional |
---|---|---|
id | ID | |
name | String | |
code | String | |
type | GroupType (Enum) |
Possible values:
|
description | String | |
notes | String | |
created_at | Date | |
updated_at | Date | |
Employees | Array of StudentEmployee |
Arguments:
|
StudentLesson
StudentLesson {
id
period_instance_id
created_at
updated_at
start_at
end_at
Period
Room
Employee
}
Name | Type | Additional |
---|---|---|
id | ID | |
period_instance_id | String | |
created_at | Date | |
updated_at | Date | |
start_at | Date | |
end_at | Date | |
Period | Period | |
Room | Room | |
Employee | StudentEmployee |
Subject
Subject {
id
name
code
created_at
updated_at
}
Name | Type | Additional |
---|---|---|
id | ID | |
name | String | |
code | String | |
created_at | Date | |
updated_at | Date |