Skip to main content
The Directory and DataExport APIs use OAuth 2.0 with the Client Credentials flow. This flow is designed for server-to-server communication where no end-user context is required — your application authenticates directly using its client credentials to obtain a short-lived access token.

Obtaining an access token

Send a POST request to the token endpoint with your client_id and client_secret:
POST https://api.meitner.se/oauth/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET
The response contains the access token and its lifetime in seconds:
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600
}

Using the access token

Include the token in the Authorization header of every API request:
GET /directory/v1/school HTTP/1.1
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

Handling token expiry

Tokens are valid for the duration specified in expires_in (seconds). The Client Credentials flow does not issue refresh tokens — when your token expires, request a new one using the same client credentials.
import requests

def get_access_token(client_id, client_secret):
    response = requests.post("https://api.meitner.se/oauth/token", data={
        "grant_type": "client_credentials",
        "client_id": client_id,
        "client_secret": client_secret,
    })
    data = response.json()
    return data["access_token"], data["expires_in"]

token, expires_in = get_access_token("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET")

headers = {"Authorization": f"Bearer {token}"}
response = requests.get("https://api.meitner.se/directory/v1/school", headers=headers)
Track expires_in in your application and proactively refresh the token before it expires to avoid failed requests.
If you are using the Directory API SDK, token refresh is handled automatically — you don’t need to manage token expiry yourself.