Documentación técnica
Integra Crystapool con tus propias herramientas: hoja de cálculo, software de gestión de fincas o cualquier sistema que pueda hacer peticiones HTTP o recibir webhooks.
Autenticación
Todas las peticiones a la API deben incluir una clave de API en la cabeceraAuthorization:
Authorization: Bearer tu_clave_de_apiLas claves se generan desde el panel del administrador de tu empresa mantenedora en Dashboard → Clientes → [cliente] → Claves de API. Cada clave está asociada a un cliente específico y solo permite acceder a los datos de ese cliente.
API REST
La URL base de la API es https://crystapool.es/api/v1. Todas las respuestas son JSON con codificación UTF-8.
Listar piscinas
GET /api/v1/poolsDevuelve todas las piscinas del cliente autenticado.
{
"data": [
{
"id": "clx...",
"name": "Piscina adultos",
"facility": "Urbanización Sol",
"publicSlug": "piscina-adultos-comunidad-sol",
"category": "PRIVATE_COLLECTIVE",
"enclosure": "OUTDOOR",
"seasonality": "SEASONAL",
"chlorinationSystem": "SALINE"
}
]
}Visitas de una piscina
GET /api/v1/pools/:poolId/visits?from=2026-01-01&to=2026-12-31Devuelve las visitas registradas en el rango de fechas indicado (ISO 8601). Si se omiten, devuelve los últimos 90 días.
{
"data": [
{
"id": "clx...",
"checkInAt": "2026-06-15T10:30:00.000Z",
"checkOutAt": "2026-06-15T11:15:00.000Z",
"visitType": "ROUTINE",
"technicianName": "Carlos López",
"measurement": {
"ph": 7.4,
"chlorineFree": 1.2,
"temperature": 26.5
},
"tasks": ["Paso de limpiafondos", "Limpieza de skimmers"],
"products": [
{ "name": "Sal (clorador salino)", "amount": "5 kg" }
],
"photoCount": 2,
"incidentCount": 0
}
],
"range": { "from": "2026-01-01T00:00:00.000Z", "to": "2026-12-31T23:59:59.999Z" }
}Mediciones de una piscina
GET /api/v1/pools/:poolId/measurements?from=2026-06-01&to=2026-06-30Serie temporal de mediciones físico-químicas para la piscina indicada.
{
"data": [
{
"date": "2026-06-15T10:32:00.000Z",
"ph": 7.4,
"chlorineFree": 1.2,
"chlorineTotal": 1.4,
"temperature": 26.5,
"alkalinity": 120
}
]
}Incidencias de una piscina
GET /api/v1/pools/:poolId/incidents{
"data": [
{
"id": "clx...",
"title": "Lluvias intensas",
"description": "Arrastre de hojas y turbidez leve.",
"actionsTaken": "Limpieza de skimmers y cloración de refuerzo.",
"status": "RESOLVED",
"createdAt": "2026-06-10T09:00:00.000Z"
}
]
}Webhooks
Los webhooks permiten que Crystapool notifique a tu sistema en tiempo real cuando ocurre un evento. Configura la URL de destino desde Dashboard → Clientes → [cliente] → Webhook.
Verificación de la firma
Cada petición incluye la cabecera X-Crystapool-Signature con un HMAC-SHA256 del cuerpo de la petición firmado con tu secreto de webhook. Verifica siempre la firma antes de procesar el evento:
// Node.js
const crypto = require('crypto');
function verifySignature(body, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Eventos disponibles
visit.closed
Se dispara cuando un técnico cierra una visita.
{
"event": "visit.closed",
"poolId": "clx...",
"poolName": "Piscina adultos",
"visitId": "clx...",
"checkInAt": "2026-06-15T10:30:00.000Z",
"checkOutAt": "2026-06-15T11:15:00.000Z",
"technicianName": "Carlos López",
"measurement": {
"ph": 7.4,
"chlorineFree": 1.2,
"temperature": 26.5
}
}incident.opened
Se dispara cuando se registra una nueva incidencia.
{
"event": "incident.opened",
"poolId": "clx...",
"poolName": "Piscina adultos",
"incidentId": "clx...",
"title": "Lluvias intensas",
"description": "Arrastre de hojas y turbidez leve.",
"createdAt": "2026-06-10T09:00:00.000Z"
}Reintentos
Si tu endpoint devuelve un código distinto de 2xx, Crystapool reintentará la entrega hasta 3 veces con un intervalo exponencial (1 min, 5 min, 30 min). Pasados los reintentos, el evento se descarta y queda registrado en el log de tu cliente.
Códigos de error
| Código | Significado |
|---|---|
400 | Parámetros incorrectos o faltantes. |
401 | Clave de API ausente o inválida. |
403 | La clave no tiene acceso a ese recurso. |
404 | Recurso no encontrado. |
429 | Demasiadas peticiones. Límite: 100 por minuto. |
500 | Error interno. Contacta con soporte. |
Los errores incluyen siempre un campo message con una descripción legible:
{ "message": "Piscina no encontrada para este cliente." }¿Necesitas ayuda?
Si tienes dudas sobre la integración o quieres que revisemos tu implementación, escríbenos a soporte@crystapool.es.