MENU navbar-image

Introduction

API for the Acquanet app, authenticated with a per-user API key.

This documentation aims to provide all the information you need to work with our API.

Authenticating requests

To authenticate requests, include a X-API-Key header with the value "{YOUR_API_KEY}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

API keys are created by a superuser under Admin → API keys. Every request is handled as the user the key belongs to.

Clients

List clients

requires authentication

Returns the user's own client and all of its child clients that have control boxes, each with its control boxes (masters) and their slaves.

Example request:
curl --request GET \
    --get "https://acqua-net.online/app_api/clients?limit=10&page=1" \
    --header "X-API-Key: {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://acqua-net.online/app_api/clients"
);

const params = {
    "limit": "10",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "page": 1,
    "limit": 10,
    "total": 1,
    "clients": [
        {
            "id": 2,
            "name": "Meridian Swimming Pool",
            "masters": [
                {
                    "id": 1,
                    "name": "Women's Locker Room",
                    "ip": "",
                    "firmware": "1.14",
                    "online": true,
                    "last_contact": "2026-10-03T06:38:45.000000Z",
                    "slave_count": 2,
                    "slaves": [
                        {
                            "id": 1,
                            "name": "Shower 1",
                            "temperature": 21.7,
                            "type": "shower"
                        },
                        {
                            "id": 2,
                            "name": "Shower 2",
                            "temperature": 38.5,
                            "type": "shower"
                        }
                    ],
                    "last_syncs": {
                        "eventlogs": "2026-10-01T05:30:00.000000Z",
                        "hot_cycle": "2026-10-01T05:30:00.000000Z",
                        "mixed_cycle": null,
                        "settings": "2026-10-03T06:42:45.000000Z"
                    }
                }
            ],
            "online": true
        }
    ]
}
 

Example response (401):


{
    "message": "Unauthorized"
}
 

Example response (422):


{
    "message": "The given data was invalid.",
    "errors": {
        "page": [
            "The page must be a number."
        ]
    }
}
 

Request      

GET app_api/clients

Headers

X-API-Key        

Example: {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

limit   number  optional    

Number of clients per page. Defaults to 10. Example: 10

page   number  optional    

Page number. Defaults to 1. Example: 1

Response

Response Fields

page   integer     

The requested page.

limit   integer     

The requested page size.

total   integer     

Number of clients the user can access.

clients   object[]     

The clients the user can access.

id   integer     

Client ID.

name   string     

Client name.

online   boolean     

Whether the client is online.

masters   object[]     

The client's control boxes.

id   integer     

Control box ID.

name   string     

Control box alias.

ip   string     

IP address of the control box (currently always empty).

firmware   string     

Firmware version of the control box.

online   boolean     

Whether the control box is online.

last_contact   string     

ISO 8601 time of the last check-in, or null if it never checked in.

slave_count   integer     

Number of slaves on the control box.

slaves   object[]     

The control box's slaves.

id   integer     

Slave ID.

name   string     

Slave alias.

temperature   number     

Last measured temperature in °C.

type   string     

One of: generic, shower, group shower, faucet, urinal.

last_syncs   object     

ISO 8601 times of the last received data per type; null if never received.

eventlogs   string     

Last event log.

hot_cycle   string     

Last hot cycle temperature log.

mixed_cycle   string     

Last mixed cycle temperature log.

settings   string     

Last settings update.

Client details

requires authentication

Returns a single client the user has access to, with its control boxes (masters) and their slaves.

Example request:
curl --request GET \
    --get "https://acqua-net.online/app_api/clients/2/details" \
    --header "X-API-Key: {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://acqua-net.online/app_api/clients/2/details"
);

const headers = {
    "X-API-Key": "{YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "id": 2,
    "name": "Meridian Swimming Pool",
    "masters": [
        {
            "id": 1,
            "name": "Women's Locker Room",
            "ip": "",
            "firmware": "1.14",
            "online": true,
            "last_contact": "2026-10-03T06:38:45.000000Z",
            "slave_count": 2,
            "slaves": [
                {
                    "id": 1,
                    "name": "Shower 1",
                    "temperature": 21.7,
                    "type": "shower"
                },
                {
                    "id": 2,
                    "name": "Shower 2",
                    "temperature": 38.5,
                    "type": "shower"
                }
            ],
            "last_syncs": {
                "eventlogs": "2026-10-01T05:30:00.000000Z",
                "hot_cycle": "2026-10-01T05:30:00.000000Z",
                "mixed_cycle": null,
                "settings": "2026-10-03T06:42:45.000000Z"
            }
        }
    ],
    "online": true
}
 

Example response (401):


{
    "message": "Unauthorized"
}
 

Example response (404):


{
    "message": "Not Found"
}
 

Request      

GET app_api/clients/{client}/details

Headers

X-API-Key        

Example: {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

client   integer     

The ID of the client. Example: 2

Response

Response Fields

id   integer     

Client ID.

name   string     

Client name.

online   boolean     

Whether the client is online.

masters   object[]     

The client's control boxes. Each has the same fields as in "List clients".

Control boxes

Control box cycles

requires authentication

Returns the temperature cycles a control box logged after the given date, with the result per shower.

Example request:
curl --request GET \
    --get "https://acqua-net.online/app_api/controlboxes/1/cycles?sincedate=2026-10-03" \
    --header "X-API-Key: {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://acqua-net.online/app_api/controlboxes/1/cycles"
);

const params = {
    "sincedate": "2026-10-03",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


[
    {
        "id": 1834,
        "start_date": "2026-10-03T07:30:00.000000Z",
        "end_date": "2026-10-03T07:30:59.000000Z",
        "sync_date": "2026-10-03T05:30:00.000000Z",
        "successful": false,
        "cycle_conclusions": [
            {
                "name": "Shower 1",
                "success": true
            },
            {
                "name": "Shower 2",
                "success": false
            }
        ],
        "is_mix_cycle": false,
        "cycle_water_usage": {
            " Shower0-1": {
                "name": "Shower 1",
                "usage": 8.36
            },
            " Shower1-2": {
                "name": "Shower 2",
                "usage": 8.36
            }
        },
        "shower_data": [
            {
                "name": "Shower0",
                "start_date": "2026-10-03 07:30:00 UTC",
                "end_date": "2026-10-03 07:30:59 UTC",
                "seconds_over_60": 11,
                "seconds_over_65": 0,
                "seconds_over_70": 0,
                "highest_temp": "63.8"
            },
            {
                "name": "Shower1",
                "start_date": "2026-10-03 07:30:00 UTC",
                "end_date": "2026-10-03 07:30:59 UTC",
                "seconds_over_60": 0,
                "seconds_over_65": 0,
                "seconds_over_70": 0,
                "highest_temp": "41.2"
            }
        ]
    }
]
 

Example response (401):


{
    "message": "Unauthorized"
}
 

Example response (404):


{
    "message": "Not Found"
}
 

Example response (422):


{
    "message": "The given data was invalid.",
    "errors": {
        "sincedate": [
            "The sincedate does not match the format Y-m-d."
        ]
    }
}
 

Request      

GET app_api/controlboxes/{controlbox}/cycles

Headers

X-API-Key        

Example: {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

controlbox   integer     

The ID of the control box. Example: 1

Query Parameters

sincedate   string     

Only cycles logged after this date (Y-m-d) are returned. Must be a valid date in the format Y-m-d. Example: 2026-10-03

Response

Response Fields

id   integer     

ID of the temperature log the cycle was read from.

start_date   string     

ISO 8601 time of the first measurement in the cycle.

end_date   string     

ISO 8601 time of the last measurement in the cycle.

sync_date   string     

ISO 8601 time the control box sent the log.

successful   boolean     

Whether every shower reached the required temperature.

cycle_conclusions   object[]     

Result per shower.

name   string     

Shower name.

success   boolean     

Whether this shower reached the required temperature.

is_mix_cycle   boolean     

Whether this was a mixed (cold/warm) cycle instead of a hot cycle.

cycle_water_usage   object     

Water usage per shower in liters, keyed by the shower's internal column name.

shower_data   object[]     

Temperature statistics per shower.

name   string     

Internal shower name as sent by the control box.

start_date   string     

Time of the shower's first measurement ("Y-m-d H:i:s UTC").

end_date   string     

Time of the shower's last measurement ("Y-m-d H:i:s UTC").

seconds_over_60   integer     

Seconds the shower was above 60 °C.

seconds_over_65   integer     

Seconds the shower was above 65 °C.

seconds_over_70   integer     

Seconds the shower was above 70 °C.

highest_temp   string     

Highest measured temperature in °C.

Users

Current user

requires authentication

Returns the user the API key belongs to.

Example request:
curl --request GET \
    --get "https://acqua-net.online/app_api/me" \
    --header "X-API-Key: {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://acqua-net.online/app_api/me"
);

const headers = {
    "X-API-Key": "{YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "id": 5,
    "name": "Emma Clarke",
    "email": "pool.manager@example.com",
    "role_id": 3,
    "email_verified_at": null,
    "created_at": "2026-08-05T06:42:45.000000Z",
    "updated_at": "2026-08-05T06:42:45.000000Z",
    "client_id": 2,
    "must_change_password": 0,
    "language": "en",
    "receive_notifications": false,
    "isDeveloper": 0,
    "login_driver": "db",
    "hasPwaInstalled": 0,
    "lastTimePwaPopupShown": null
}
 

Example response (401):


{
    "message": "Unauthorized"
}
 

Request      

GET app_api/me

Headers

X-API-Key        

Example: {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Response

Response Fields

id   integer     

User ID.

name   string     

Full name.

email   string     

Email address.

role_id   integer     

ID of the user's role.

client_id   integer     

ID of the client the user belongs to.

language   string     

Preferred language code, e.g. en or nl.

receive_notifications   boolean     

Whether the user receives notification emails.