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."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
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"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
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."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
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"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
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.