Skip to content

Authentication

Schulungstool uses API keys to grant access to the API. You can generate an API key in your admin area under Settings > Advanced settings > Developer options.

Schulungstool expects the API key in every API request in the HTTP header:

Authorization: Token <API key>

Bearer <API key> is accepted as well.

Example:

Terminal window
curl "https://api.schulungstool.de/v1/users/" \
-H "Authorization: Token <API key>"

Replace <API key> with your API key.

Without a valid key, the API responds with status code 401 and the error type AuthenticationFailed or NotAuthenticated, see Errors and rate limiting.

Every API key carries access scopes that control which endpoints it may call. You choose them per resource when generating a key in the admin area under Settings > Advanced settings > Developer options, and an administrator can change them there at any time; changes take effect immediately. Keys created before access scopes existed have full access.

Scope Grants
users:read / users:write Read and manage users
groups:read / groups:write Read and manage groups and their members
courses:read / courses:write Read and manage courses
course-categories:read / course-categories:write Read and manage course categories
course-ratings:read Read course ratings (the API cannot write them)
participations:read / participations:write Read and manage participations, download certificates
login-links:write Create login links that sign in as a user

write always includes read for the same resource. Login links sign the caller in as the selected user, which is why they are a separate right on purpose: users:write does not include them.

The scope follows the data an endpoint returns, not its URL: for example, GET /v1/groups/{id}/members/ returns user objects and therefore requires users:read. You do not have to work this out yourself; the API reference names the required scope on every endpoint.

If a key lacks the scope an endpoint requires, the API responds with status code 403 and the error type MissingScope. The response names the missing scope in error.required_scope and repeats it in the X-Required-Scope response header:

{
"error": {
"type": "MissingScope",
"message": "This API key does not have the required access for this endpoint. Required scope: `courses:write` (Courses – Read and write). An administrator can grant it in the developer options of the admin area.",
"required_scope": "courses:write",
"doc_url": "https://docs.api.schulungstool.de/guides/authentication/#access-scopes",
"request_id": "req_6b1c9d2e4f3a5078b6c4d2e0"
}
}

GET /v1/me/ works with every valid key regardless of its scopes and returns the key’s name and scopes plus the account it belongs to. Use it as a connection smoke test and to check which rights a key carries:

{
"key": {
"name": "Reporting (read only)",
"uuid": "1e8f2d4c-9b7a-4f3e-8c21-5d6a7b8c9d0e",
"scopes": ["course-ratings:read", "courses:read", "participations:read"]
},
"organization": {
"domain": "demo.schulungstool.de"
}
}
  • Grant each integration only the scopes it actually needs. For reporting or BI integrations that only fetch data, a read-only key is enough; the Set all to read preset in the admin area creates one in a click.
  • Use a separate key per integration, so you can restrict or revoke one integration without affecting the others.
  • The Last used column in the admin area shows when each key last made a request; keys that have been unused for months are candidates for revoking.
  • When requests fail with 403, the API log in the admin area (Settings > Advanced settings > Developer options > API log) shows them with the error type MissingScope, so you can spot a key that is missing a scope at a glance.
  • To restrict an existing key that has full access, start from what it actually uses: in the API log, filter by the key (Show requests in the key’s menu) and look at its successful requests. The API reference names the required scope in the first line of each operation. Grant exactly those scopes via Edit API key and remove the rest. The API log covers the last 30 days, so jobs that run less often do not appear there: check your code for them, or watch for MissingScope after restricting the key.

In the API reference you can send any request straight from your browser via Test Request. Enter your API key in the Auth field: it stays in your browser window only, is never stored, and is gone after you reload the page. Keep in mind that requests go to the production API, so writing calls (such as POST or DELETE) change real data.