Skip to content


Session-based Authentication

The Panel uses session-based authentication, which is not really typical for REST APIs, but works best in combination with frontend authentication and is also the most secure way when you don't have control over the backend environment and you cannot work with trusted private keys.

We use sessions purely for authentication to keep communication with the API stateless.

Session-based authentication requires CSRF token validation. The CSRF token has to be sent in the X-CSRF header for every request. A token can be generated with the csrf() helper on the backend.

Sessions also require a correct session cookie for every request to work correctly. Therefore, session-based authentication works best when you make API calls from the frontend of the same site/domain.


Here's a JavaScript example using the new fetch API. This setup assumes that it is running on the same server as the API and that you have access to our csrf() helper. It could be in a Kirby template for example. This is ideal when you want to build a single page application on top of Kirby or if you need to fetch parts of your site dynamically via JavaScript. This could be combined easily with a React or Vue based application.

    <title>API Example</title>

      const csrf = "<?= csrf() ?>";

      fetch("/api/pages/example", {
          method: "GET",
          headers: {
            "X-CSRF" : csrf
        .then(response => response.json())
        .then(response => {
          const page =;
          // do something with the page data
        .catch(error => {
          // something went wrong

HTTP Basic Auth

To enable truly stateless, remote authentication, our API offers HTTP Basic auth as an alternative to sessions. It is particularly useful if you want to make requests from the backend of a different site or in a command line tool.

Basic auth has to be activated in the config:

return [
    'api' => [
        'basicAuth' => true

When Basic auth is activated, you must send an Authorization header with every request.


Here's a simple example of a remote request in PHP with our Remote class.


$response = Remote::get('', [
  'headers' => [
    'Authorization: Basic ' . base64_encode($email . ':' . $password)

$page = json_decode($response->content())->data;

Available Endpoints