Introduction
The HTTP API of Kadi4Mat makes it possible to programmatically interact with most of the resources that can be managed via the graphical user interface by sending suitable HTTP requests to the different endpoints (i.e. URLs) the API provides.
Tip
In parallel to the API itself, a Python wrapper library called kadi-apy is also available, which can be used as a higher-level alternative to using the API directly. However, it is still recommended to read through the following sections.
Using the API
All API endpoints start with the /api
prefix, e.g.
http://kadi4mat.example.edu/api
. This prefix can optionally be followed by a
version, e.g. /api/v1
, which specifies an explicit API version to use. When omitting
this version, the latest stable version will be used by default. Please see the
Endpoints section for a list of supported API versions.
Note
Specifying an explicit (stable) API version is recommended to ensure that applications or scripts that make use of the API do not break unexpectedly in case backwards incompatible changes to the latest (in development) API are introduced.
Interacting with the API requires a suitable client that can handle HTTP requests. Some examples include simple command line tools such as curl, graphical tools such as Postman or most programming languages, either natively or via third-party libraries, such as the popular requests library for Python.
Tip
For some endpoints (namely, all endpoints supporting GET
requests), the normal
web browser can be used as well by simply typing the corresponding URL in the
browser’s address bar. This is an easy way to get familiar with the API. Please note
that this requires being logged in to Kadi4Mat.
Common request/response formats
As is the case for many HTTP APIs, the JSON format is used for all requests where data
needs to be sent as part of the request body. Accordingly, the Content-Type
header
should be set to application/json
, which many clients will handle automatically. A
notable exception are file uploads, where the application/octet-stream
content type
is used instead.
The JSON format is also used for all responses that return any data, except for
endpoints returning actual file data. Generally, there are endpoints that return a
single deserialized resource, i.e. a single JSON object, or a list of multiple resources
wrapped inside an items
property, which itself is an array of JSON objects. In the
latter case, most endpoints return paginated data, i.e. instead of returning all
requested resources at once, only a chunk of them is returned. In this case, the
response includes a _pagination
property like the following:
{
"items": [
// The actual data.
],
"_pagination": {
"page": 2,
"per_page": 10,
"total_pages": 3,
"total_items": 25,
"_links": {
"prev": "https://...?page=1&...",
"self": "https://...?page=2&...",
"next": "https://...?page=3&..."
}
}
}
Two other common properties include the _links
property and the _actions
property. These properties consist of different endpoints that can be used to either get
additional information about a resource (typically via a GET
request) or to perform
certain actions related to a resource. Both properties can either be included as an
additional property of each resource, or as an additional meta property, including as
part of the _pagination
property like in the example above. This is mostly for
convenience, so any related endpoints can be retrieved from the data itself without
needing to construct them manually.
Whenever some error occurs, i.e. a status code greater than or equal to 400
is
returned, a corresponding error object will be returned as well. This object always
includes at least the status code, a message and a description about the error. The
following example shows a generic error object for the status code 400
:
{
"code": 400,
"description": "The browser (or proxy) sent a request that this server could not understand.",
"message": "Bad Request"
}
Common error status codes
In the following, some common error status codes are listed, which can be returned by most endpoints.
- 400 (Bad Request)
This status code is relevant for any endpoint that requires data to be sent in the HTTP request body as JSON. It will be returned whenever the body is either missing, has a syntax error or includes any invalid keys or values. In the latter case, additional information about the errors will be included as part of the error response object in the
errors
property.- 401 (Unauthorized)
This status code will be returned if either no valid access token is included in the request, it has expired or its scope is insufficient for the requested endpoint. In the latter case, all scopes the endpoint requires will be included as an array as part of the error response object in the
scopes
property. The status code may also be returned if the user associated with an access token is currently not authorized to use the API at all, e.g. if the corresponding account is inactive.- 403 (Forbidden)
This status code is relevant for any endpoint that requires certain permissions to create, retrieve or update data. It will be returned if the permissions of the user associated with the provided access token are insufficient.
- 404 (Not Found)
This status code will be returned if a specific resource, usually requested via a corresponding dynamic endpoint, does not exist. Furthermore, the same status code will be returned for non-API endpoints or endpoints that do not exist at all.
- 405 (Method Not Allowed)
This status code will be returned if the HTTP method used for a request is not supported by the requested endpoint.
- 429 (Too Many Requests)
This status code will be returned if a rate limit configured in the application has been reached, i.e. too many requests have been sent in too short a time. In addition to the usual error response, an additional HTTP header
Retry-After
will be returned, which specifies the amount of seconds to wait until another request may be sent.