School Passport API (SSO API)

In this article

Revisions

1. OAuth 2 authorization

1.1. Resource owner authorization

1.1.1. Authorization Code Grant type

1.1.1.1. Authorization request

1.1.1.2. Access token request

1.1.2. Implicit grant

1.1.3. Resource Owner Password Credentials Grant

1.2. Service level authorization

1.3. OAuth 2 API authorization - “Client credentials” grant

1.4. Structure of Passport’s auth_token's claims

1.5. Refresh token

2. Access to user's identity information

3. Obtain metadata of SSO Passport for a user

4. Execute Single Sign-on

5. Log out

6. “Login with Google or Azure” functionality

6.1. Resource owner authorization

Revisions

Document Version

Change Description

Effective Date

1.1

“іnvalidate” & “orgGuid” parameters are added for #1.1.1.1 & #1.1.2

Apr 03, 2020

1.0

“username” attribute added in response for #2

Aug 11, 2020

1. OAuth 2 authorization

GG4L provides its institutional tenants with the web-based Single Sign-On (SSO) Platform, called Passport. Each tenant can have its custom domain name for API and web-based UI (e.g. schoolA.edu, mydistrict.edu.ca, etc). 

There are two distinct scenarios for integration that rely on Passport’s OAuth Identity Provider service:

  • “Login with Passport” is when a Service Provider (your application) allows users to authenticate using Passport’s OAuth service. Identity of Organization can be submitted when redirecting a user to Passport’s SSO Platform to eliminate the need for a user to select organization from UI of Passport (see API documentation for further details).

  • “Passport initiated SSO to a Service Provider” is when a user requests access to your service from Passport’s SSO Platform (being already authenticated in Passport). In a typical workflow, the Service Provider would provide an endpoint that redirects browser agent back to Passport’s OAuth service (as per #1.1.1.1 below, for example). This redirect should use the hostname of the originating SSO request (e.g. schoolA.edu or myschool.edu.ca etc). The Service Provider should derive the value of hostname from SSO request (either using “Referrer” header or Passport can include that value as a parameter). An alternative simplified workflow can be considered as well. For example, Passport can start SSO by sending OAuth code or OAuth access token.

  • By default, OAuth access_token is valid for 12 hours and refresh_token is valid for 30 days. 

1.1 Resource owner authorization

1.1.1 Authorization Code Grant type

1.1.1.1 Authorization request

GET

/account/default/authorize?response_type={responseType}&client_id={clientId}&redirect_uri={redirectUri}

The endpoint to authenticate a user. Uses for login via OAuth.
GET

/oauth/auth?response_type={responseType}&client_id={clientId}&redirect_uri={redirectUri}

The endpoint to authenticate a user. Uses for login thought ETX.

Parameters:

Parameter

Mode

Type

Description

response_type

Required

String

The type of the response (should be: code)

client_id

Required

String

OAuth client identifier registered with SSO Platform 

redirect_uri

Required

String

The URI for redirection after successful authentication (the value should match one of the registered in SSO Platform)

state

Optional

String

This parameter will be returned to a requester after successful authentication of a user

orgGuid

Optional

String

An identifier of the organization (typically of a district). This value corresponds to the value of GUID that consumers of roster data receive from GG4L. GG4L will prepopulate “Organization selector” in the Login page based on the provided value of orgGuid.

invalidate

Optional

boolean

The default value is “false”. Set the value to “true” to invalidate any active web session and OAuth tokens associated with that session.

prompt

Optional

String

Set the value to “login” to invalidate any active web session. Refer to Learn more about OAuth2 Refresh Token.

org_guid

Optional

String

An identifier of the organization (typically of a district). This value corresponds to the value of GUID that consumers of roster data receive from GG4L. GG4L will prepopulate “Organization selector” in the Login page based on the provided value of orgGuid.

Example of request (response_type=code):

https://{hostname}/oauth/auth?response_type=code&client_id={clientId}&redirect_uri=https://{partner’s_hostname}

Example of response (after successful authentication):

Redirect to redirect_uri (as provided in the request)

https://{partner’s_hostname}/?code=GmUGCD&state={state}

Errors:

Error message

Code

Description

{redirectUri}?error=unsupported_response_type&error_description=Unsupported+response+types%3A+%5B{not_valid_response_type}%5D

302

Response type is not valid or unsupported or missing

{"error":"Client is not registered"}

400

Client_id is not valid or not found

{"error":"Invalid redirect: https://not_valid_uri does not match one of the registered values: [https://valid_uri]"}

400

Redirect URI is not valid or not registered for specified client_id

{"error":"A client id must be provided"}

400

Client_id parameter is missing

{"error":"A redirect_uri must be supplied."}

400

Redirect_uri parameter is missing


1.1.1.2 Access token request

POST

/oauth/token?grant_type=authorization_code&code={code}&redirect_uri={redirect_uri}

The endpoint to obtain access_token

The request must contain WWW BASIC authorization with client_id and client secret key in the request header:

 ‘Authorization’: ‘Basic {data}’

where:

data = Base64.encode(‘{client_id}:{client secret}’)

Example:

Method

POST

URL

https://{hostname}/oauth/token

Body

grant_type=authorization_code&code=GmUGCD&redirect_uri=https://{partner’s_hostname}/

Headers

Authorization: Basic Y2xpZW50aWQ6Y2xpZW50c2VjcmV0

Response:

The API returns the following response on successful authentication:

{
  "access_token": "...",
  "token_type": "bearer",
  "refresh_token": "...",
  "expires_in": 43199,
  "scope": "user.profile",
  "auth_token": "..."
}

Field

Type

Description

access_token String OAuth 2.0 Access Token
token_type String Type of token - always bearer
expires_in Integer Expiration time in seconds
scope String An optional list with scopes that define granted data access
state String The value provided in request
auth_token String JWT Token with brief information about a user.
Signature is created with secret key as per
http://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-07
refresh_token String OAuth 2.0 Refresh Token. Valid for 30 days (by default).

Errors:

Error message

Code

Description

{ "error":"invalid_grant", "error_description":"Unauthorized grant type: not_valid_grant"}

400

Grant type is not valid

{"error":"invalid_grant",
"error_description":"Invalid authorization code: not_valid_code"}

400

Authorization code is not valid or used repeatedly

{"error": "redirect_uri_mismatch",
"error_description": "Redirect URI mismatch."}

400

Redirect uri is not valid or not registered for specified client_id

{"error":"authentication failed"}

400

Client_id or client secret value or host parameter is not valid

{"error":"invalid_request",
"error_description":"Missing grant type"}

400

Grant type parameter is missing

{"error":"invalid_request",
"error_description":"Missing 'code' parameter"}

400

Code parameter is missing


1.1.2. Implicit grant

GET

/oauth/auth?response_type={responseType}&client_id={clientId}&redirect_uri={redirectUri}

The endpoint to authenticate a user

Parameters:

Parameter

Mode

Type

Description

sponse_type

Required

String

The type of the response (should be: token)

client_id

Required

String

The identifier of the client registered on the server

redirect_uri

Required

String

The URI for redirection after successful authentication (the value gets validated if is registered in SSO Platform)

state

Optional

String

This parameter will be returned to requester after successful authentication of user

orgGuid 

Optional

String

An identifier of the organization (typically of a district). This value corresponds to the value of GUID that consumers of roster data receive from GG4L. GG4L will prepopulate “Organization selector” in the Login page based on the provided value of orgGuid.

іnvalidate 

Optional

Boolean

The default value is “false”. Set the value to “true” to invalidate any active web session and OAuth tokens associated with that session.

prompt

Optional

String

Set the value to “login” to invalidate any active web session. Learn more about OAuth2 Refresh Token

org_guid

Optional

String

An identifier of the organization (typically of a district). This value corresponds to the value of GUID that consumers of roster data receive from GG4L. GG4L will prepopulate “Organization selector” in the Login page based on the provided value of orgGuid.

Example of request:

https://{hostname}/oauth/auth?response_type=token&client_id={clientId}&redirect_uri=https://{partner’s_hostname}

Response (after successful authentication): 

redirect to redirect_uri (as provided in the request)

 https://{partner’s_hostname}#access_token=...&token_type=bearer&expires_in=43199&scope={scopes}&auth_token=...

Field

Type

Description

access_token

String

OAuth 2.0 Access Token

token_type

String

Token's type. Always bearer

expires_in

Integer

Expiration time in seconds

scope

String

An optional list of scopes that define granted data access

state

String

The value provided in request

auth_token

String

Optional JWT Token with brief information about the user.

Signature is created with a secret key as per OAuth JWT Assertion Profiles.

Errors:

Error message

Code

Description

{redirectUri}?error=unsupported_response_type&error_description=Unsupported+response+types%3A+%5B{not_valid_response_type}%5D

302

Response type is not valid or unsupported or missing

{"error":"Client is not registered"}

400

Client_id is not valid or not found

{"error":"Invalid redirect: https://not_valid_uri does not match one of the registered values: [https://valid_uri]"}

400

Redirect URI is not valid or not registered for specified client_id

{"error":"A client id must be provided"}

400

Client_id parameter is missing

{ "error":"A redirect_uri must be supplied."}

400

Redirect_uri parameter is missing


1.1.3. Resource Owner Password Credentials Grant

GET/ POST /oauth/token?grant_type=password&username={username}&password={password}&_orgId={orgId} The endpoint to authenticate a user

The request must contain WWW BASIC authorization with client_id and client secret key in request header:

‘Authorization’: ‘Basic {data}’

where

data = Base64.encode(‘{client_id}:{client secret}’)

Parameters:

Parameter

Mode

Type

Description

grant_type

Required

String

The type of the grant (should be: password)

username

Required

String

Credential username

password

Required

String

Credential password

org_id

Required

String

ID of organization hosted on SSO Platform

Example of request:

https://{hostname}/oauth/token?grant_type=password&username=user1&password=1234&_orgId=123456

Response:

{
  "access_token":"...",
  "token_type":"bearer",
  "refresh_token":"...",
  "expires_in":43199,
  "auth_token":"..."
}

1.2. Service level authorization

Where applications need to obtain an access_token without user interaction, application should provide a signed JWT.

Service level authorization diagram

POST

/oauth/token

The endpoint returns the access_token

Parameters:

Parameter

Mode

Type

Description

auth_token

Required

String

The signed JWT

grant_type

Required

String

Must be “jwt-bearer”

Structure of JWT

Field

Mode

Description

iss

Required

The issuer of the secret key. Must be "oauth.edutone.com"

aud

Required

The hostname where JWT will be verified

sub

Required

The client_id issued for secret key by SSO Passport

exp

Required

The time window in seconds while token is valid

iat

Required

The time in seconds from 1 Jan 1970 GMT when JWT is created

pid

Required/Optional

The identifier of the user in SSO Passport for whom the access_token to be created. Should be provided for existing user and if prn value is not provided

prn

Required/Optional

The email of the user for whom access_token to be created. Should be provided for existing user and if pid value is not provided. 

The following fields must be filed to create (if pid/prn aren’t provided) or update (if pid/prn are provided) an account on the fly. For an account creation all the “required” fields must be presented otherwise non personalized access_token is granted. For account update only new (not empty) field values must be provided.

first

Required/Optional

First name

last

Required/Optional

Last name

email

Optional

Email address

school

Required/Optional

Identifier of the school associated with the user. Cannot be updated.

role

Required/Optional

Role of the user

type

Required/Optional

User's type - one of the following values: 

“school_admin”, ”teacher ”, ”student”,”parent”, “contact”

external_id

Required/Optional

Identifier of the user in the external system (SIS/LMS etc). Used as a unique user’s key within school thus forbidding creation of accounts with the same external_id value.  External ID is forbidden for update

grade

Optional

Grade of the student (ignored for non “student” user types) - range of values from “-3” to “15”

 

Response:

{
    "access_token": "eyJraWQiOiIxIi...MbJ0Q",
    "token_type": "Bearer",
    "refresh_token": "2MLNxp6QiOiI...eP9gSlCi2LNxp6FaIg",
    "expires_in": 300,
  "scope": "profile",
    "id_token": "eyJraWQiOiI...eP9gSlCi2MLNxp6FaIg"
}

Field

Type

Description

access_token

String

OAuth 2.0 Access Token

token_type

String

Type of token - always bearer

expires_in

Integer

Expiration time in seconds

scope

String

An optional list with scopes that define granted data access

auth_token

String

Optional JWT Token with brief information about the user.

Signature is created with secret key as per

http://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-07

refresh_token

String

OAuth2 Refresh Token.  Valid for 30 days (by default)

Errors:

Error message

Code

Description

{"error":"untrusted issuer [iss=<...>]"}

400

Issuer value differs from "oauth.edutone.com"

{"error":"invalid client"}

400

Client_id not found

{"error":"invalid signature"}

400

Invalid secret or invalid JWT signature

{"error":"token has expired"}

400

JWT token has expired

{"error":"user not found"}

400

User not found by pid or prn

{"error":"insufficient jurisdiction”}

400

User found but belongs to a different organization hierarchy

{"error":"email address conflict”}

400

More than one users found with provided prn address (within organization hierarchy)

{"error":"uuid conflict”}

400

More than one users found with provided pid (within organization hierarchy) 

1.3 OAuth 2 API authorization - “Client credentials” grant

The request must contain WWW BASIC authorization with client_id and client secret key in request header: ‘Authorization’: ‘Basic {data}’, where data = Base64.encode(‘{client_id}:{client secret}’)

With  “client_credentials” OAuth grant type, a "userToken" parameter should be used when invoking Passport API in the context of a specific user account (for example, to retrieve user profile details or to invoke SSO etc). Contact GG4L for further information. 

POST /oauth/token The endpoint returns the access_token

Parameters:

Parameter

Mode

Type

Description

grant_type

Required

String

Must be “client_credentials”

Example:

Method POST
URL /oauth/token HTTP/1.1
Host host.gg4l.com
Headers Basic mF_9.B5f-4.1JqM


Response  (on successful authentication):

{
"access_token": "...",
"token_type": "bearer",
"refresh_token": "...",
"expires_in": 43199
}

Errors:

Error message

Code

Description

{"error":"invalid_grant", "error_description":"Unauthorized grant type: not_valid_grant"}

400

Grant type is not valid

{"error":"authentication failed"}

400

Client_id or client secret value or host parameter is not valid

{"error":"invalid_request",
"error_description":"Missing grant type"}

400

Grant type parameter is missing

1.4. Structure of Passport’s auth_token's claims

New attributes can be added to JSON response. Client side implementation should not rely on the order of the attributes.

JWT's claims:

{
  "sub": "808980",
  "ctx": "personal",
  "roles": [
    "TEACHER"
  ],
  "iss": "https://sso.gg4l.com/account",
  "client_id": "PTRYQPSEIH",
  "aud": "PTRYQPSEIH",
  "nbf": 1637782955,
  "org_id": 348970,
  "scope": "profile",
  "username": "sslaylock",
  "guid": "ff3801b6-3ac1-345d-7211-6dbe9213a233",
  "exp": 1637784755,
  "iat": 1637782955,
  "jti": "cd4901c9-4ac0-475a-8a59-5dbe9213a00f"
}

Field

Type

Description

iss

String

Unique identifier for the entity that issued the JWT - always “oauth.edutone.com”

sub

GUID

Internal unique identifier of the user

aud

String

Identifies the authorization server as an intended audience. The hostname that processed the request

exp

Integer

Time window in seconds during which the JWT can be used

iat

Integer

The time at which the JWT was issued (seconds from  1 Jan 1970)

district

GUID

The unique id of user’s district in SSO Platform

school

GUID

The unique id of user’s organization in SSO Platform

type

String

User's type - one of the following values: “district_admin”, “school_admin”, ”teacher”, ”student”, “contact”

last_modified

BigInteger

The time in seconds from 1 Jan 1970 GMT when attributes of the user were modified (reserved for future use)

1.5. Refresh token

POST /oauth/token The endpoint returns the access_token

The request must contain WWW BASIC authorization with client_id and client secret key in request header: ‘Authorization’: ‘Basic {data}’, where data = Base64.encode(‘{client_id}:{client secret}’)

Parameters:

Parameter

Mode

Type

Description

refresh_token

Required

String

The refresh token value

grant_type

Required

String

Must be “refresh_token”

Response:

{
  "access_token": "...",
  "token_type": "bearer",
  "refresh_token": "...",
  "expires_in": 43199,
  "scope": "user.profile"
}

Field

Type

Description

access_token

String

Token value that can be included in requests to API either as parameter “access_token” or as header “Authorization” (as per  OAuth 2.0 specification).

refresh_token

String

OAuth 2.0 Refresh Token

token_type

String

Always “bearer”

expires_in

Integer

Time window in seconds while access_token is valid

scope

String

An optional list of scopes that define granted data access

Errors:

Error message

Code

Description

{"error":"invalid_grant",
"error_description":"Unauthorized grant type:
not_valid_grant"}

400

Grant type is not valid

{"error":"Refresh token is mandatory"}

400

Token value is not specified 

{"error":"authentication failed"}

400

Client_id or client secret value or host parameter is not valid

{"error":"invalid_request",
"error_description":"Missing grant type"}

400

Grant type parameter is missing

{"error":"invalid_request"}

 

Token value is not valid

2. Access to user's identity information

New attributes can be added to JSON response. Client side implementation should not rely on the order of the attributes. 

Additional data related to a user account (e.g. information about schools/sections/ students related to a teacher account) are available through Data API (documentation is available upon request).

GET /services/v1.4/users/me The endpoint returns identity information for a user account

Access token to be supplied in authorization header as per RFC 6750

Response:

{
  "data": {
    "district": "4dff2226-er45-48c5-a9ef-82c529b02000",
    "school": "332628ca-fghj-4291-8ddd-f4c31a05a032",
    "id": "cba90bc1-941e-4247-uj89-288aca16500b",
    "type": "student",
    "email": "test@edutone.org",
    "first": "First",
    "last": "Last"
  }
}

Field

Type

Description

district

GUID

Identifier of the district associated with the user

school

GUID

Identifier of the school associated with the user

id

GUID

Identifier of the user in SSO Platform

type

String

User's type - one of the following values: “district_admin”, “school_admin”, ”teacher ”, ”student”, “contact”

email

String

Email of the user

first

String

First name of the user

last

String

Last name of the user

last_modified

BigInteger

The time in seconds from 1 Jan 1970 GMT when attributes of the user were modified (reserved for future use)

Example:

Method GET
URL /services/v1.4/users/me HTTP/1.1
Body host.gg4l.com
Headers

Authorization: Bearer mF_9.B5f-4.1JqM

Response:

{
  "data": {
    "district": "4dff2226-er45-48c5-a9ef-82c529b02000",
    "school": "332628ca-fghj-4291-8ddd-f4c31a05a032",
    "id": "cba90bc1-941e-4247-uj89-288aca1650bb",
    "type": "student",
    "email": "test@edutone.org",
    "first": "First",
    "last": "Last"
  }
}

Errors:

Error message

Code

Description

{"requestId":"id",
"messageId":"AccessDeniedException",
"description":"Access Denied"}

400

Access token parameter is missing

{"requestId":"id",
"messageId":"AccessDeniedException",
"description":"invalid signature"}

400

Access token value is not valid

{"requestId":"id",
"messageId":"AccessTokenExpiredException",
"description":"Access token is expired"}

400

Access token value is expired

3. Obtain metadata of SSO Passport for a user

3.1 Metadata for a User (Role)

New attributes can be added to JSON response. Client side implementation should not rely on the order of the attributes.

GET /services/passport?ownerId={ownerId}access_token={valueOfAccessToken} The endpoint to retrieve metadata about content of user's SSO Passport

Response:

{
  "ownerId": 2282419,
  "children": [
 {
   "assetId": 564838,
   "ownerId": 2282416,
   "type": "FOLDER",
   "parentId":,
   "name": "School Resources",
   "children": [
     {
       "assetId": 564844,
       "ownerId": 2282416,
       "type": "SSOLINK",
       "parentId": 564838,
       "name": "Curriki",
       "children":,
       "sizex": 2,
       "sizey": 2,
       "position": 1,
       "image": "curriki.png",
       "applicationId": "Curriki"
     },
     {
       "assetId": 590744,
       "ownerId": 2282416,
       "type": "BKM",
       "parentId": 564838,
       "name": "Google",
       "children":,
       "url": "https://www.google.com",
       "sizex": 2,
       "sizey": 2,
       "position": 2,
       "image": "upload/2282412/ahCKGAjAWGDX.png"
     }
   ],
   "sizex": 2,
   "sizey": 2,
   "position": 1
 }
  ],
  "resourcesStorage": {
 "baseUrl": "https://graphics.gg4l.com/p/content/images/"
  }
}

 

Field

Type

Description

assetId

BigInteger

A unique identifier of the asset

ownerId

BigInteger

A unique identifier of the owner of the assets in SSO Passport. Owner of the asset has administrative rights on the respective asset.

parentId

BigInteger

The unique identifier of the Asset that is a containers for the given resource

type

String

The type of the Asset:

  • FOLDER - folder (a container for other assets)
  • SSOLINK - an SSO enabled asset
  • BKM - a bookmark that does not requires authorization (SSO) through GG4L

url

String

The URL of the Asset (applies to asset with the type of “BKM”)

image

String

The URI of the image that represents an Asset in the Passport. Can be an absolute path or a value that needs to be concatenated with the value of “resourcesStorage”

position

Integer

Used order of assets in layout of SSO Passport

sizex

Integer

Horizontal size (relative units from 1 to 5)

sizey

Integer

Vertical size (relative units from 1 to 5)

Example:

https://{hostname}/services/passport?access_token=509615e8a-3ead-487d-afeb-01972c71e78b

Errors:

Error message

Code

Description

{"requestId":"id",
"messageId":"AuthenticationCredentialsNotFoundException",
"description":"AnAuthentication object was not found in the SecurityContext"}

400

Access token parameter is missing

{"requestId":"id",
"messageId":"AccessDeniedException",
"description":"invalid signature"}

400

Access token value is not valid

{"requestId":"id","messageId":"AccessTokenExpiredException",
"description":"Access token is expired"}

400

Access token value is expired

4. Execute Single Sign-on

GET /services/idm/sso/{applicationId}?access_token={valueOfAccessToken} The endpoint to invoke Single Sign-on to the Application

Parameters:

Parameter

Mode

Type

Description

applicationId

required

String

The unique identifier of the Application

Example:

https://{hostname}/services/idm/sso/PowerSchool?access_token=509615e8a-3ead-487d-afeb-01972c71e78b

Errors:

Error message

Code

Description

{"requestId":"id",
"messageId":"NullPointerException",
"description":null}

400

Access token parameter is missing

{"requestId":"id","messageId":"AccessDeniedException",
"description":"invalid signature"}

400

Access token value is not valid

{"requestId":"id","messageId":"AccessTokenExpiredException",
"description":"Access token is expired"}

400

Access token value is expired

{"error":"IdmObject doesn't exist [dname=invalid_applicationId]"}

400

Application id value is not valid

5. Log out

GET, POST /oauth/loginwith/logout?redirect_uri={redirect_uri} The endpoint logouts current user and performs redirecting to {redirect_uri}

Parameters:

Parameter

Mode

Type

Description

redirect_uri

Optional

String

The URL of external resource

6. “Login with Google or Azure” functionality

A. "Login with Google or Azure" request to GG4L should contain OrgID. 

B. "Login with Google or Azure" will be successful only for a user account that has email in GG4L address that matches G Suite or Azure AD account. 

C. OAuth token gets returned immediately after authentication. Redirect_uri should be registered in GG4L.

 6.1 Resource owner authorization

Method GET
Endpoint /oauth/google/auth?school_guid={externalId}&client_id={clientId}&redirect_uri={redirectUri}
Headers The endpoint to authenticate a user via Google
Method GET
Endpoint /oauth/ad/auth?school_guid={externalId}&client_id={clientId}&redirect_uri={redirectUri}
Headers The endpoint to authenticate a user via Azure AD
Parameters:

Parameter

Mode

Type

Description

school_guid

optional/required

String

GG4L GUID of a school to which user belongs. 

Either school_guid or school_external_id is required. School_guid has preference over school_external_id.

school_external_id

optional/required

String

External Id of a school to which user belongs.

Either school_guid or school_external_id is required. School_guid has preference over school_external_id.

client_id

required

String

OAuth client identifier registered with SSO Platform 

redirect_uri

required

String

The URI to which authentication result is sent (the value should match one of the registered in SSO Platform).

state

optional

String

This parameter is returned back to a requester

Example of request (response_type=code):

https://{hostname}/oauth/google/auth?school_external_id=332628ca-fghj-4291-8ddd-f4c31a05a032&client_id=clientId&redirect_uri=https://{partner’s_hostname}

Response:

The API returns the following response on successful authentication: redirect to redirect_uri (as provided in the request)

Redirect to https://{partner’s_hostname}?code=GmUGCD&state={state}

Errors:

Error message

Code

Description

{"error":"Google/Azure user not found"}

400

User has failed to login into Google or Azure

{"error":"User not found"}

400

Google or Azure AD account is not linked with ETA account

{"error":"A school_guid or school_external_id must be supplied"}

400

Either school_guid or school_external_id is required

{"error":"School not found"}

400

School not found by the specified school_guid and school_external_id

{"error":"Client is not registered"}

400

Client_id is not valid or not found

{"error":"A client id must be provided"}

400

Client_id parameter is missing

{"error":"Invalid redirect: https://not_valid_uri does not match one of the registered values: [https://valid_uri]"}

400

Redirect uri is not valid or not registered for the specified client_id

{"error":"A redirect_uri must be supplied"}

400

Redirect_uri parameter is missing