General

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.0. This way, an explicit API version to use can be specified, which may be useful to ensure that applications or scripts that make use of the API do not break in case backwards incompatible changes to the API are introduced. When omitting the explicit version, the latest version will always be used by default.

Using the API requires a suitable client that can send HTTP requests. Some examples include simple command line tools such as curl, graphical tools such as Postman or any programming language that supports sending HTTP requests either natively or through a third-party library, such as the popular requests library for Python. For some endpoints (namely, all endpoints supporting GET requests), the normal web browser can be used as well, which is an easy way to get accustomed to the API.

While using the API via the browser simply requires being logged in, using it from another client generally requires creating a personal access token (PAT) first. Such a token can be created via the web interface in the menu found in Settings > Access tokens and will operate with the same permissions as the user that created the token. Besides specifying the name of the token, which becomes especially useful when managing multiple tokens, an expiration date can be set. This date can optionally be used to prohibit using the token beyond the specified date. If no date is given, the token will never expire. As another security feature, a token can be limited to one or multiple scopes. Scopes can restrict a token’s access to specific resources or actions, i.e. some endpoints may not be usable at all or they may only return limited information about a resource. If no scopes are selected, the token will have full access by default.

After the PAT has been created, it has to be included as bearer token in an Authorization header for each request that should use the token. In the end, the header should look like the following: Authorization: Bearer <token>. Without this header, including the valid PAT, all endpoints will return a 401 status code. See the section below about other common error status codes.

Common request formats

As is the case for most REST-like HTTP APIs, the JSON format is used for most requests where data needs to be sent as part of the request body. Accordingly, for most requests the Content-Type header has to be set to application/json. When a file should be included in the request, the multipart/form-data content type is used instead, including the actual file data as well as any additional metadata. Note that many clients will set such headers automatically, depending on the request body being sent.

Common response formats

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 resources at once, only a chunk of the resources is returned, e.g. the first 10 requested records ordered by their last modification date. 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 (e.g. _links.revisions to get the revisions of a record) or to perform certain actions relating to a resource (e.g. _actions.delete to delete a record). These properties can either be included as additional property of a resource, or as additional meta property like the _pagination property in the above example, outside of each item. This is mostly for convenience, so any related endpoints can be retrieved from the data itself, instead of building 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 the status code, a message and a description about the error, at the very least. 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 if not all 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 object or form data. It will be returned whenever the body is either missing, has a syntax error or includes any invalid values or keys. For the last case, additional information about the error(s) will be included in the error response object in the errors property.

401 (Unauthorized)

This status code is relevant for every endpoint and will be returned if either no valid PAT is included in the request, it has expired or its scope is insufficient for the requested endpoint.

403 (Forbidden)

This status code is relevant for any endpoint that requires certain permission(s) to create, retrieve or update data. It will be returned if the permissions of the user of the current PAT are insufficient.

404 (Not Found)

This status code is relevant for any endpoint with dynamic URL rules. It will be returned if the requested resource, e.g. given by a certain ID, does not exist. Furthermore, the same status code will be returned for non-API endpoints or, as usual, endpoints that do not exist at all.

405 (Method Not Allowed)

This status code is relevant for every endpoint and will be returned if the HTTP method used for a request is not supported by the requested endpoint.