Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/GianlucaBessone/HDB-Service/llms.txt

Use this file to discover all available pages before exploring further.

HDB Service uses a four-level organizational hierarchy: Client → Plant → Sector → Location. A client represents a business account. Each client has one or more plants (physical sites). Plants can be subdivided into sectors (logical zones), and each sector contains locations — the precise spots where water dispensers are installed. Locations carry a globally unique, user-defined ID that is printed on QR codes attached to each dispenser mounting point. All endpoints require an authenticated session. Access is automatically scoped by the RBAC system: CLIENT_RESPONSIBLE and CLIENT_REQUESTER roles can only read data belonging to their own client or assigned plants, and cannot create or modify records.

GET /api/clients

Returns all active clients visible to the authenticated user. CLIENT_RESPONSIBLE and CLIENT_REQUESTER users receive only their own client record. Each client object includes a _count summary with the number of associated plants and users. Required permission: clients:read
id
string
Client ID.
nombre
string
Client display name.
email
string
Contact email (nullable).
telefono
string
Contact phone number (nullable).
direccion
string
Physical address (nullable).
active
boolean
Whether the client is active.
createdAt
string
ISO 8601 creation timestamp.
_count
object
curl -X GET "https://your-domain.com/api/clients" \
  -H "Cookie: sb-access-token=<token>"
Error responses:
StatusDescription
401Not authenticated.
403Insufficient permission (clients:read required).
500Internal server error.

POST /api/clients

Creates a new client. The nombre field is required; all other fields are optional. Creation is idempotent via the Idempotency-Key header — sending the same key twice returns the first response without creating a duplicate. The action is written to the audit log. Required permission: clients:write
nombre
string
required
Client display name. Cannot be blank.
email
string
Contact email address.
telefono
string
Contact phone number.
direccion
string
Physical address.
id
string
Newly created client ID.
nombre
string
Client display name.
email
string
Contact email (nullable).
telefono
string
Contact phone (nullable).
direccion
string
Physical address (nullable).
active
boolean
Always true on creation.
createdAt
string
ISO 8601 creation timestamp.
curl -X POST "https://your-domain.com/api/clients" \
  -H "Content-Type: application/json" \
  -H "Cookie: sb-access-token=<token>" \
  -d '{
    "nombre": "Acme Corporation",
    "email": "ops@acme.com",
    "telefono": "+54 11 4000-0000",
    "direccion": "Av. Corrientes 1234, Buenos Aires"
  }'
Error responses:
StatusDescription
400nombre is missing or blank.
401Not authenticated.
403Insufficient permission (clients:write required).
500Internal server error.

GET /api/clients/[id]

Returns a single client by ID, including its active plants (each with a count of locations), the total number of associated users, and the client’s SLA configuration if one exists. Returns 403 if the authenticated user does not have access to this client. Required permission: clients:read
id
string
Client ID.
nombre
string
Client display name.
email
string
Contact email (nullable).
telefono
string
Contact phone (nullable).
direccion
string
Physical address (nullable).
active
boolean
Whether the client is active.
plants
array
_count
object
slaConfig
object
SLA configuration object (nullable). See SLA Config schema for full field list.
curl -X GET "https://your-domain.com/api/clients/client_abc" \
  -H "Cookie: sb-access-token=<token>"
Error responses:
StatusDescription
403Authenticated user does not have access to this client.
404Client not found.
401Not authenticated.
500Internal server error.

PUT /api/clients/[id]

Updates one or more fields on an existing client. Only fields present in the request body are updated; omitted fields are left unchanged. Setting active: false effectively deactivates the client. All changes are recorded in the audit log. Required permission: clients:write
nombre
string
New client display name.
email
string
New contact email. Pass null to clear.
telefono
string
New contact phone. Pass null to clear.
direccion
string
New physical address. Pass null to clear.
active
boolean
Set to false to deactivate the client.
id
string
Client ID.
nombre
string
Updated display name.
email
string
Updated email (nullable).
telefono
string
Updated phone (nullable).
direccion
string
Updated address (nullable).
active
boolean
Current active state.
updatedAt
string
ISO 8601 last-updated timestamp.
curl -X PUT "https://your-domain.com/api/clients/client_abc" \
  -H "Content-Type: application/json" \
  -H "Cookie: sb-access-token=<token>" \
  -d '{"telefono": "+54 11 9999-0000"}'
Error responses:
StatusDescription
404Client not found.
401Not authenticated.
403Insufficient permission (clients:write required).
500Internal server error.

DELETE /api/clients/[id]

Soft-deletes a client by setting active: false. The client record and all related data are retained in the database. The action is recorded in the audit log. Required permission: clients:write
id
string
Client ID.
active
boolean
Always false after a successful delete.
updatedAt
string
ISO 8601 timestamp of deactivation.
curl -X DELETE "https://your-domain.com/api/clients/client_abc" \
  -H "Cookie: sb-access-token=<token>"
Error responses:
StatusDescription
401Not authenticated.
403Insufficient permission (clients:write required).
500Internal server error.

GET /api/plants

Returns all active plants visible to the authenticated user. CLIENT_RESPONSIBLE users see only plants belonging to their client. CLIENT_REQUESTER users see only plants they have been explicitly granted access to via UserPlantAccess. Each plant includes a reference to its parent client and a count of locations. Required permission: plants:read
clientId
string
Filter plants by client ID.
id
string
Plant ID.
clientId
string
Owning client ID.
nombre
string
Plant display name.
direccion
string
Physical address (nullable).
lat
number
Latitude coordinate (nullable).
lng
number
Longitude coordinate (nullable).
active
boolean
Whether the plant is active.
createdAt
string
ISO 8601 creation timestamp.
client
object
_count
object
curl -X GET "https://your-domain.com/api/plants?clientId=client_abc" \
  -H "Cookie: sb-access-token=<token>"
Error responses:
StatusDescription
401Not authenticated.
403Insufficient permission (plants:read required).
500Internal server error.

POST /api/plants

Creates a new plant under an existing client. Requires both clientId and nombre. The optional lat / lng fields enable map-based features in the UI. Creation is idempotent via Idempotency-Key. The action is recorded in the audit log. Required permission: plants:write
clientId
string
required
ID of the parent client.
nombre
string
required
Plant display name. Cannot be blank.
direccion
string
Physical address of the plant site.
lat
number
Latitude coordinate for map display.
lng
number
Longitude coordinate for map display.
id
string
Newly created plant ID.
clientId
string
Parent client ID.
nombre
string
Plant display name.
direccion
string
Physical address (nullable).
lat
number
Latitude (nullable).
lng
number
Longitude (nullable).
active
boolean
Always true on creation.
createdAt
string
ISO 8601 creation timestamp.
curl -X POST "https://your-domain.com/api/plants" \
  -H "Content-Type: application/json" \
  -H "Cookie: sb-access-token=<token>" \
  -d '{
    "clientId": "client_abc",
    "nombre": "Planta Norte",
    "direccion": "Ruta 9, Km 42, Córdoba",
    "lat": -31.4201,
    "lng": -64.1888
  }'
Error responses:
StatusDescription
400clientId or nombre is missing.
401Not authenticated.
403Insufficient permission (plants:write required).
500Internal server error.

PUT /api/plants/[id]

Updates one or more fields on an existing plant. Only fields present in the request body are updated. Setting active: false effectively deactivates the plant. All changes are recorded in the audit log. Required permission: plants:write
nombre
string
New display name.
direccion
string
New address. Pass null to clear.
clientId
string
Reassign to a different client.
active
boolean
Set to false to deactivate the plant.
id
string
Plant ID.
nombre
string
Updated display name.
active
boolean
Current active state.
updatedAt
string
ISO 8601 last-updated timestamp.
curl -X PUT "https://your-domain.com/api/plants/plant_xyz" \
  -H "Content-Type: application/json" \
  -H "Cookie: sb-access-token=<token>" \
  -d '{"nombre": "Planta Norte II"}'
Error responses:
StatusDescription
404Plant not found.
401Not authenticated.
403Insufficient permission (plants:write required).
500Internal server error.

DELETE /api/plants/[id]

Soft-deletes a plant by setting active: false. The plant record and all related data are retained in the database. The action is recorded in the audit log. Required permission: plants:write
id
string
Plant ID.
active
boolean
Always false after a successful delete.
updatedAt
string
ISO 8601 timestamp of deactivation.
curl -X DELETE "https://your-domain.com/api/plants/plant_xyz" \
  -H "Cookie: sb-access-token=<token>"
Error responses:
StatusDescription
404Plant not found.
401Not authenticated.
403Insufficient permission (plants:write required).
500Internal server error.

GET /api/locations

Returns all active locations. Results are sorted naturally by plant name then location name. Each location includes its parent plant (with client name), its sector (if assigned), and any dispenser currently in IN_SERVICE status at that location. Required permission: locations:read
plantId
string
Filter locations to a specific plant.
sectorId
string
Filter locations to a specific sector.
id
string
Location ID (user-defined, globally unique).
plantId
string
Parent plant ID.
sectorId
string
Sector ID (nullable).
nombre
string
Location display name.
piso
string
Floor identifier (nullable).
area
string
Area within the sector (nullable).
descripcion
string
Free-text description (nullable).
active
boolean
Whether the location is active.
plant
object
sector
object
dispensers
array
Array of dispensers currently at this location with status: IN_SERVICE. Each entry includes id, marca, modelo, and status.
curl -X GET "https://your-domain.com/api/locations?plantId=plant_xyz" \
  -H "Cookie: sb-access-token=<token>"
Error responses:
StatusDescription
401Not authenticated.
403Insufficient permission (locations:read required).
500Internal server error.

POST /api/locations

Creates a new location. The id field is the globally unique location code printed on QR codes — you may supply your own (e.g., "A-102") or omit it to have the server auto-generate a sequential ID in the format LOC-001, LOC-002, etc. The plantId and nombre are always required. Creation is idempotent via Idempotency-Key. The action is recorded in the audit log. Required permission: locations:write
id
string
User-defined globally unique location ID (e.g., "SECTOR-A-101"). If omitted or blank, the server auto-generates a sequential LOC-NNN ID.
plantId
string
required
ID of the parent plant.
nombre
string
required
Location display name. Cannot be blank.
sectorId
string
ID of the sector this location belongs to.
piso
string
Floor identifier (e.g., "2", "PB", "Mezzanine").
area
string
Area within the sector (e.g., "Sala de reuniones").
descripcion
string
Free-text description for technicians.
id
string
Location ID (user-supplied or auto-generated).
plantId
string
Parent plant ID.
sectorId
string
Sector ID (nullable).
nombre
string
Location display name.
piso
string
Floor (nullable).
area
string
Area (nullable).
descripcion
string
Description (nullable).
active
boolean
Always true on creation.
createdAt
string
ISO 8601 creation timestamp.
curl -X POST "https://your-domain.com/api/locations" \
  -H "Content-Type: application/json" \
  -H "Cookie: sb-access-token=<token>" \
  -d '{
    "plantId": "plant_xyz",
    "sectorId": "sector_admin",
    "nombre": "Recepción Principal",
    "piso": "PB",
    "area": "Hall de Entrada"
  }'
Location IDs are globally unique across all plants and clients. If you supply a custom id that already exists anywhere in the system, the request returns 409 Conflict.
Error responses:
StatusDescription
400plantId or nombre is missing.
409Supplied id already exists in the system.
401Not authenticated.
403Insufficient permission (locations:write required).
500Internal server error.

PUT /api/locations/[id]

Updates one or more fields on an existing location. Only fields present in the request body are modified. Setting active: false deactivates the location. Changes are recorded in the audit log. Required permission: locations:write
nombre
string
New display name.
plantId
string
Reassign to a different plant.
sectorId
string
Reassign to a different sector. Pass null to remove sector assignment.
piso
string
Updated floor. Pass null to clear.
area
string
Updated area. Pass null to clear.
descripcion
string
Updated description. Pass null to clear.
active
boolean
Set to false to deactivate the location.
id
string
Location ID.
nombre
string
Updated display name.
active
boolean
Current active state.
updatedAt
string
ISO 8601 last-updated timestamp.
curl -X PUT "https://your-domain.com/api/locations/LOC-042" \
  -H "Content-Type: application/json" \
  -H "Cookie: sb-access-token=<token>" \
  -d '{"piso": "1", "area": "Comedor"}'
Error responses:
StatusDescription
404Location not found.
401Not authenticated.
403Insufficient permission (locations:write required).
500Internal server error.

DELETE /api/locations/[id]

Soft-deletes a location by setting active: false. The location record is retained in the database. The action is recorded in the audit log. Required permission: locations:write
id
string
Location ID.
active
boolean
Always false after a successful delete.
updatedAt
string
ISO 8601 timestamp of deactivation.
curl -X DELETE "https://your-domain.com/api/locations/LOC-042" \
  -H "Cookie: sb-access-token=<token>"
Error responses:
StatusDescription
404Location not found.
401Not authenticated.
403Insufficient permission (locations:write required).
500Internal server error.

GET /api/sectors

Returns all active sectors. When plantId is provided, returns only sectors associated with that plant via the PlantSector junction table. Without a plantId, returns all sectors with counts of associated locations and plants. Required permission: sectors:read
plantId
string
Filter to sectors assigned to a specific plant.
id
string
Sector ID.
nombre
string
Sector display name.
descripcion
string
Optional description (nullable).
active
boolean
Whether the sector is active.
createdAt
string
ISO 8601 creation timestamp.
_count
object
Present when no plantId filter is applied.
curl -X GET "https://your-domain.com/api/sectors?plantId=plant_xyz" \
  -H "Cookie: sb-access-token=<token>"
Error responses:
StatusDescription
401Not authenticated.
403Insufficient permission (sectors:read required).
500Internal server error.

POST /api/sectors

Creates a new sector. Sectors are reusable across plants — the same sector can be assigned to multiple plants via the PlantSector join table. Creation is idempotent via Idempotency-Key. The action is recorded in the audit log. Required permission: sectors:write
nombre
string
required
Sector display name. Cannot be blank.
descripcion
string
Optional free-text description.
id
string
Newly created sector ID.
nombre
string
Sector display name.
descripcion
string
Description (nullable).
active
boolean
Always true on creation.
createdAt
string
ISO 8601 creation timestamp.
curl -X POST "https://your-domain.com/api/sectors" \
  -H "Content-Type: application/json" \
  -H "Cookie: sb-access-token=<token>" \
  -d '{
    "nombre": "Administración",
    "descripcion": "Oficinas administrativas y salas de reuniones"
  }'
After creating a sector, assign it to a plant by creating a PlantSector entry. Locations within that plant can then reference the sector by its sectorId.
Error responses:
StatusDescription
400nombre is missing or blank.
401Not authenticated.
403Insufficient permission (sectors:write required).
500Internal server error.

PUT /api/sectors/[id]

Updates one or more fields on an existing sector. Only fields present in the request body are modified. Setting active: false deactivates the sector. Changes are recorded in the audit log. Required permission: sectors:write
nombre
string
New display name.
descripcion
string
Updated description. Pass null to clear.
active
boolean
Set to false to deactivate the sector.
id
string
Sector ID.
nombre
string
Updated display name.
descripcion
string
Updated description (nullable).
active
boolean
Current active state.
updatedAt
string
ISO 8601 last-updated timestamp.
curl -X PUT "https://your-domain.com/api/sectors/sector_admin" \
  -H "Content-Type: application/json" \
  -H "Cookie: sb-access-token=<token>" \
  -d '{"nombre": "Administración Central"}'
Error responses:
StatusDescription
404Sector not found.
401Not authenticated.
403Insufficient permission (sectors:write required).
500Internal server error.

DELETE /api/sectors/[id]

Soft-deletes a sector by setting active: false. The sector record is retained in the database. The action is recorded in the audit log. Required permission: sectors:write
id
string
Sector ID.
active
boolean
Always false after a successful delete.
updatedAt
string
ISO 8601 timestamp of deactivation.
curl -X DELETE "https://your-domain.com/api/sectors/sector_admin" \
  -H "Cookie: sb-access-token=<token>"
Error responses:
StatusDescription
404Sector not found.
401Not authenticated.
403Insufficient permission (sectors:write required).
500Internal server error.

Build docs developers (and LLMs) love