NextSchoolNextSchool Data API

Authentication

JWT authentication flow — login, token refresh, and logout

Authentication

The API uses JWT (JSON Web Token) authentication with a two-token system:

  • Access Token — Short-lived (15 minutes), used for API requests
  • Refresh Token — Long-lived (7 days), used to obtain new access tokens

Token Lifecycle

┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│    Login     │────▶│ Access Token │────▶│  API Request │
│              │     │  (15 min)    │     │              │
└──────────────┘     └──────┬───────┘     └──────────────┘
       │                    │
       │              Token Expired?
       │                    │
       ▼                    ▼
┌──────────────┐     ┌──────────────┐
│Refresh Token │────▶│ New Access   │
│  (7 days)    │     │   Token      │
└──────────────┘     └──────────────┘

Login

Obtain access and refresh tokens by providing your credentials.

mutation {
  login(username: "your_username", password: "your_password") {
    accessToken
    refreshToken
    expiresIn
    user {
      id
      username
      name
      email
    }
  }
}

Response:

{
  "data": {
    "login": {
      "accessToken": "eyJhbGciOiJIUzI1NiIs...",
      "refreshToken": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "expiresIn": 900,
      "user": {
        "id": 42,
        "username": "api_user",
        "name": "API User",
        "email": "api@school.ac.th"
      }
    }
  }
}
FieldTypeDescription
accessTokenStringJWT token for authenticating requests
refreshTokenStringToken for obtaining new access tokens
expiresInIntAccess token lifetime in seconds (900 = 15 min)
userAuthUserAuthenticated user information

Using the Access Token

Include the access token in the Authorization header of every request:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

The JWT payload contains:

{
  "sub": "42",
  "username": "api_user",
  "email": "api@school.ac.th",
  "schoolId": 123,
  "iss": "ns-data",
  "iat": 1700000000,
  "exp": 1700000900
}

Refresh Token

When the access token expires, use the refresh token to get a new one without re-authenticating:

mutation {
  refreshToken(refreshToken: "a1b2c3d4-e5f6-7890-abcd-ef1234567890") {
    accessToken
    expiresIn
  }
}

Response:

{
  "data": {
    "refreshToken": {
      "accessToken": "eyJhbGciOiJIUzI1NiIs...(new token)",
      "expiresIn": 900
    }
  }
}

Note: The refresh token itself is not rotated — you keep using the same refresh token until it expires (7 days) or you logout.


Logout

Invalidate a specific refresh token:

mutation {
  logout(refreshToken: "a1b2c3d4-e5f6-7890-abcd-ef1234567890")
}

Logout All Sessions

Invalidate all refresh tokens for your account (requires authentication):

mutation {
  logoutAll
}

This removes all active sessions across all devices.


Error Responses

Error CodeDescription
UNAUTHENTICATEDInvalid or missing access token
FORBIDDENUser not assigned to a school
Invalid credentialsWrong username or password
Invalid or expired refresh tokenRefresh token is invalid or has expired

On this page