Skip to content

Errors and rate limiting

All error types except ValidationError have this structure:

{
"error": {
"type": "NotFound",
"message": "Resource not found.",
"request_id": "req_6b1c9d2e4f3a5078b6c4d2e0"
}
}

The error type ValidationError adds field_errors and non_field_errors:

{
"error": {
"type": "ValidationError",
"message": "One or more fields are missing or have invalid values. See `field_errors` and `non_field_errors` for details.",
"field_errors": {
"due_date": ["This field is required."]
},
"non_field_errors": [],
"request_id": "req_6b1c9d2e4f3a5078b6c4d2e0"
}
}

These error types exist:

Type Status code Description
ValidationError 400 One or more fields are missing or have invalid values. See field_errors and non_field_errors for details.
ParseError 400 The request contains malformed data.
AuthenticationFailed 401 Authentication failed: invalid authorization header or invalid API key.
NotAuthenticated 401 Authentication failed: no API key was provided.
PermissionDenied 403 No permission to perform this action.
NotFound 404 Resource not found.
MethodNotAllowed 405 The HTTP method is not allowed.
NotAcceptable 406 The Accept header of the request could not be satisfied.
UnsupportedMediaType 415 Unsupported media type in the request.
Throttled 429 A rate limit was reached.
InternalServerError 500 An internal server error occurred.

Every API response carries the HTTP header X-Request-ID with a unique ID such as req_6b1c9d2e4f3a5078b6c4d2e0; error responses repeat it as request_id in the body. Include this ID in support inquiries: it lets us look up the exact request in our logs.

Schulungstool applies rate limiting to its API to ensure consistent API performance for all users. By default, every Schulungstool account can make up to 1000 API requests per minute.

Every response reports the current state of the limit in three HTTP headers, so you can pace your requests before a limit is reached:

Header Meaning
X-RateLimit-Limit Maximum number of requests allowed in the current window.
X-RateLimit-Remaining Requests still available in the current window, after this request.
X-RateLimit-Reset Time at which at least one request becomes available again, as a Unix timestamp in seconds.

Exception: responses with status code 401 do not carry these headers, because without a valid API key no account can be associated with the request.

When a limit is reached, you receive an HTTP response with status code 429:

{
"error": {
"type": "Throttled",
"message": "Request was throttled. Expected available in 7 seconds."
}
}

The response includes the HTTP header field Retry-After with the number of seconds to wait, after which a new request can be expected to receive a normal response.

  • Watch X-RateLimit-Remaining: as the value approaches 0, spread further requests out until the time given in X-RateLimit-Reset instead of running into the 429.
  • Retry a request only on status 429 (wait the number of seconds given in Retry-After) and on 5xx errors (with exponential backoff and a limited number of attempts).
  • Do not retry other 4xx errors: the request itself is the problem, and repeating it unchanged fails again. Fix the request based on the error type and message instead, see the table above.