Troubleshooting
A reference for diagnosing and resolving common integration issues. Each entry describes what you observe, why it happens, and how to fix it.
invalid_grant error when obtaining an access token
Section titled “invalid_grant error when obtaining an access token”The token endpoint returns invalid_grant when using the Client Credentials flow.
Cause
The OIDC client secret and the platform-generated password are not interchangeable. Each credential belongs to a specific flow:
| Flow | Credential to use |
|---|---|
| Client Credentials (server-to-server) | Platform-generated password sent via the credentials webhook |
| Authorization Code (SSO / user login) | OIDC client secret from PAM |
Resolution
For the Client Credentials flow, use the password delivered to your endpoint via the Credentials Webhook, not the OIDC client secret.
invalid_client on the first token request after activation
Section titled “invalid_client on the first token request after activation”The very first client_credentials token request made right after a school activates the application fails with 401 invalid_client (“Client authentication failed”). A retry a few seconds later succeeds, and all subsequent token requests work normally.
Cause
The credentials delivered via the Credentials Webhook are only valid once the entire activation process has fully completed on the platform side. If the token endpoint is called immediately after receiving the webhook, activation may not yet be finished, so the credentials are momentarily not yet valid.
Resolution
Add a short delay (1-2 seconds is generally sufficient) after receiving the credentials webhook before making the first token request. See the Activation process - Timing note for details.
Login URL does not start a new authentication flow
Section titled “Login URL does not start a new authentication flow”A user opens the application from the Untis Platform dashboard but is authenticated as a different user from a previous browser session.
Cause
If a partner application skips the authentication flow when a session already exists, and does not verify that the inbound user matches the active session, a different user account may be active than the one who launched the app.
Resolution
Treat every incoming request to your Login URL as the start of a new authentication flow. If your application already has an active session, terminate it and re-initiate the OIDC Authorization Code flow before establishing the new session. This ensures that the user authenticated in your application always matches the user who launched it from the Untis Platform.
OneRoster returns no students, but students exist in masterdata
Section titled “OneRoster returns no students, but students exist in masterdata”Querying the OneRoster API returns no students (or an empty result), even though the school has students in WebUntis.
Cause
The OneRoster API is user-account-centric. It only returns persons who have an active user account in the system. Students who exist in the masterdata but have no user account are not exposed through OneRoster.
Resolution
If you need to access students who do not have user accounts, use the Student Management API, which operates on masterdata rather than user accounts.
students/{id} returns no result
Section titled “students/{id} returns no result”Calling students/{id} returns no result for an ID that is known to exist.
Cause
The {id} path parameter resolves against the externalKey field — the identifier used by upstream school management software — not the internal Untis record ID. The externalKey is not always populated; it is set when data originates from an external source but may be absent for records created directly in WebUntis.
Resolution
To retrieve a student by their internal Untis ID, use the filter query parameter instead:
GET /WebUntis/api/rest/extern/v3/students?filter=id='1'This targets the internal id field directly and works regardless of whether an externalKey is set.
Updating a class by shortName fails when the school year has ended
Section titled “Updating a class by shortName fails when the school year has ended”PUT requests to the Class Management API fail with a VALIDATION_ERROR when updating a class that does not belong to the current school year, but only if shortName is included in the request:
{ "errorCode": "VALIDATION_ERROR", "requestId": "3dfe0d74-7a5a-463f-bb15-53cca9ee565d", "traceId": "", "validationErrors": [ { "errorKey": "entity.notFound", "path": "classes[0].id", "errorMessage": "Class with id [75] does not exists.", "index": 0 } ]}Cause
Classes are identified hierarchically by id, externKey, and shortName, in that order. shortName is only unique within an active school year — once a school year ends and no new school year has been activated yet, there is no active school year to resolve shortName against, so lookup by shortName fails.
id and externKey are not affected, since both are globally unique regardless of school year.
Resolution
When updating classes that may not belong to the current school year (for example, right after a school year has ended), identify the class using id or externKey only, and omit shortName from the request.
WebUntis is rendered a second time inside the iFrame
Section titled “WebUntis is rendered a second time inside the iFrame”Your application is embedded in WebUntis as an iFrame. When the user opens it, the login flow ends with the full WebUntis UI rendered inside the iFrame, nested within the outer WebUntis page, instead of your application.
Cause
The OAuth2 /authorize request was sent directly to WebUntis rather than to the central API gateway.
Resolution
Call all SSO endpoints, including /authorize, through the central API gateway and never on the WebUntis host. See Single Sign-On for the gateway endpoints.