API: consentimiento
El registro de consentimiento es el corazón de CookyCMP. Cada decisión del visitante — aceptar, rechazar, modificar o retirar — se persiste como un evento inmutable: los eventos solo se agregan, nunca se modifican ni se borran. Un retiro de consentimiento genera un evento nuevo; el historial completo queda como evidencia.
El modelo de evento
Sección titulada «El modelo de evento»- Sin datos personales. El visitante se identifica con un UUID anónimo generado por el banner. La dirección IP nunca se persiste: se reduce a código de país antes de guardar, y de ahí se infiere la jurisdicción. El user-agent tampoco se guarda crudo (solo un hash truncado).
- Firma HMAC como evidencia. Cada evento se firma con HMAC-SHA256 en el servidor al
persistirse. La respuesta incluye la firma (
hmac), el instante de firma (signedAt) y la versión de la llave (hmacKeyVersion) — las llaves de firma se rotan cada 90 días, y la versión guardada permite verificar cada evento contra la llave que lo firmó. - Versionado de política. Cada evento registra contra qué versión de la política de
privacidad (
policyVersion) y del banner (bannerVersion) se otorgó el consentimiento. Si la política publicada cambia, el banner vuelve a preguntar.
Tipos de evento
Sección titulada «Tipos de evento»eventType | Significado |
|---|---|
grant | El visitante aceptó (todo o por categorías). |
withdraw | El visitante retiró su consentimiento (genera una fila nueva, nunca modifica las anteriores). |
update | El visitante cambió sus preferencias granulares. |
no_action | El visitante navegó sin interactuar con el banner. |
grant_sensitive | Consentimiento expreso para datos de categoría sensible (Ley 21.719 art. 16). |
POST /v1/consent
Sección titulada «POST /v1/consent»Endpoint público (lo llama el banner web y el SDK mobile). Con rate limit.
Ruta web (banner): el body incluye siteId. El servidor resuelve el tenant desde el
sitio y exige que el sitio esté activo y verificado, y que el header Origin del request
coincida con el dominio (o un alias) registrado del sitio — un banner copiado a otro dominio
no puede registrar consentimiento.
Ruta mobile (SDK): sin siteId, el SDK identifica el tenant con el header
X-Cooky-Tenant (UUID).
{ "anonymousUserId": "6f1e…-uuid", "siteId": "a2b4…-uuid", "eventType": "grant", "categories": { "analytics": true, "marketing": false }, "vendors": { "google-analytics": true, "meta-pixel": false }, "policyVersion": "1.2.0", "bannerVersion": "0.1.0"}| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
anonymousUserId | UUID | Sí | Identificador anónimo del visitante, generado por el banner. |
siteId | UUID | No | Sitio que origina el consentimiento (ruta web validada por Origin). Ausente → ruta mobile por header. |
authenticatedUserId | UUID | No | Identificador de usuario autenticado del sitio, si aplica. |
eventType | enum | Sí | Uno de los tipos de la tabla anterior. |
categories | objeto { [categoría]: boolean } | Sí | Decisión por categoría. |
vendors | objeto { [vendor]: boolean } | Sí | Decisión por vendor (slug). |
policyVersion | string | Sí | Versión de la política vigente al consentir. |
bannerVersion | string | Sí | Versión del banner que capturó el evento. |
explicitConsent | boolean | Condicional | Obligatorio en true cuando se otorga consentimiento a vendors marcados como sensibles. Sin él, el servidor responde 422. |
sensitiveCategory | enum | No | Categoría de dato sensible involucrada (health, biometric, racial_ethnic, religious, sexual_orientation, political, union_membership). |
La jurisdicción no viene del cliente: el servidor la infiere del país de origen de la solicitud.
Respuesta
Sección titulada «Respuesta»202 Accepted:
{ "eventId": "184467", "hmac": "9f2c…", "signedAt": "2026-07-30T12:00:00.000Z", "hmacKeyVersion": 3}Errores
Sección titulada «Errores»| Código | error | Causa |
|---|---|---|
400 | (validación) | Body que no cumple el esquema, o falta X-Cooky-Tenant en la ruta mobile. |
403 | site_not_verified | El sitio existe pero su dominio no está verificado. |
403 | origin_not_allowed | El Origin del request no coincide con el dominio ni los alias del sitio. |
404 | — | Sitio desconocido o inactivo. |
422 | — | Vendors sensibles aceptados sin explicitConsent: true. |
429 | rate_limit_exceeded | Rate limit superado. |
Exportar evidencia
Sección titulada «Exportar evidencia»GET /v1/consent/export?format=csv|json&from=ISO8601&to=ISO8601
Requiere un token de sesión del dashboard con rol admin (ver
autenticación). Descarga todos los eventos del tenant en
el rango dado. El formato por defecto es json.
El CSV incluye las columnas:
id, tenant_id, site_id, anonymous_user_id, event_type, policy_version, jurisdiction, created_atEl export nunca incluye datos personales del visitante: no hay IP (solo la jurisdicción derivada), no hay user-agent, y el identificador del visitante es el UUID anónimo.