← Crystapool

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_api

Las 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/pools

Devuelve 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-31

Devuelve 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-30

Serie 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ódigoSignificado
400Parámetros incorrectos o faltantes.
401Clave de API ausente o inválida.
403La clave no tiene acceso a ese recurso.
404Recurso no encontrado.
429Demasiadas peticiones. Límite: 100 por minuto.
500Error 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.