Skip to main content

Centro de preferencias: la página pública de opt-in/opt-out

Original en inglés: Preference center: the public opt-in/opt-out page.
El centro de preferencias es una página pública donde un contacto gestiona sus propios opt-ins de canal, temas de suscripción, frecuencia de mensajes y (si usted lo habilita) presenta una solicitud de borrado de datos — sin cuenta, sin login. Cada contacto llega a través de un enlace firmado: la URL porta un token HMAC-SHA256 (v1.<payload>.<signature>) que expira tras 30 días, de modo que la página es de autoservicio pero queda acotada a exactamente un contacto en exactamente una organización. La superficie resumida de endpoints vive también dentro de Send Gates; esta guía es el recorrido completo: cada campo de configuración, dónde colocar el enlace, qué devuelve la API de la página pública y qué superficies de cumplimiento escribe un opt-out u opt-in. Todos los endpoints siguientes tienen su raíz en https://api.orbit.devotel.io/api/v1/compliance.
El centro de preferencias es un control propiedad del tenant: usted elige los canales, los temas y la marca, y su organización conserva la evidencia de consentimiento. Orbit opera la plataforma; la decisión de consentimiento pertenece al contacto. Esta guía no es asesoramiento legal — confirme sus obligaciones con su asesor.

1. Configurar una vez: POST/GET /preference-center

Establezca la configuración con POST /preference-center (clave API de owner/admin). El endpoint hace upsert de la configuración en los ajustes de su organización y devuelve el objeto guardado — ejecútelo de nuevo para actualizar. GET /preference-center lee la configuración actual; antes de configurar devuelve enabled: false con un mensaje de pista.

Campos de configuración

Cada campo se valida en el servidor — un POST rechazado devuelve 422 con incidencias por campo (field, message) para que sepa cuál falló.

Temas de suscripción

Un tema es un grupo con nombre — Newsletter, Product Updates, Billing Alerts — en el que un contacto puede darse de alta o de baja sin tocar el canal completo. Los id de tema deben ser únicos y cumplir el patrón de slug ([a-z0-9][a-z0-9_-]{0,63}); cada entrada tiene:
  • name (1–120 caracteres) — el nombre visible en la página.
  • description (opcional, ≤500) — una línea de contexto junto al control.
  • defaultOptIn (predeterminado false) — cómo se trata a un contacto sin preferencia registrada.
  • archived (opcional) — los temas archivados permanecen en la pista de auditoría pero ya no se renderizan en la página.
Trampas a nivel de lint: las URLs que no superan el refinamiento de esquema http(s) se rechazan de antemano, y los id de tema duplicados fallan con “Topic ids must be unique” en lugar de sobrescribirse en silencio.

2. Generar un enlace por contacto

Una vez configurado, genere un enlace para un contacto a la vez con POST /preference-center/link:
La respuesta devuelve link — una URL de la forma ${DEVOTEL_WEB_URL}/preferences?token=v1…. Puntos a tener en cuenta:
  • El enlace apunta a la página alojada, no al endpoint JSON. Cópielo literalmente en sus plantillas de pie/remitente; la propia página consulta el endpoint de datos por debajo.
  • TTL de 30 días. Pasado ese plazo el token verifica como expirado y el contacto debe solicitar un enlace nuevo (generar uno nuevo cuesta una llamada de API).
  • La página es agnóstica de locale al generar. La app web resuelve una redirección preservando la query ?token=, así que no necesita adivinar el locale del contacto.

Dónde colocarlo

  • Envíos de marketing con cuerpo de texto libre: se añade por usted. No necesita colocar el enlace. Orbit añade una línea {optOutMessage}: {link} a cada envío de marketing con cuerpo de texto libre mientras su centro de preferencias esté habilitado — en sms y whatsapp a través de su dominio corto personalizado, en email y los demás canales de texto libre como enlace tokenizado en bruto — y los envíos de plantilla se omiten. La misma página describe cuándo aparece el pie, qué escribe el clic añadido y cómo se relaciona con la fórmula “Reply STOP” del operador: vea Preference center: when Orbit appends the opt-out footer for you.
  • Envíos transaccionales y de plantilla: colóquelo usted. Estos envíos nunca llevan el pie añadido, así que el enlace generado arriba es su vía de baja de un toque: cópielo literalmente en el área de baja de sus plantillas de correo y redáctelo en copias de plantilla o cuerpos transaccionales donde lo quiera. Generar un enlace corto trackeado para una colocación es opcional; si la generación de enlace corto falla, el enlace en bruto sigue funcionando — el respaldo es aditivo, nunca estructural para el cumplimiento.
  • Re-opt-in impulsado por supresión. Cuando un contacto vuelve a optar vía otro flujo, puede entregarle un enlace nuevo para que obtenga la misma página de autoservicio.

3. La página pública de token

La página alojada lee y escribe a través de dos endpoints no autenticados protegidos por el token firmado:
  • GET /preferences/:token — devuelve el payload de la página.
  • PUT /preferences/:token — aplica actualizaciones.
Las formas de token inválidas devuelven 400 INVALID_TOKEN; los tokens expirados o manipulados devuelven 401 TOKEN_EXPIRED con “Please request a new link.”

Respuesta GET

El payload agrupa el estado actual del contacto y la configuración de la organización:
El correo y el teléfono están enmascarados en la respuesta pública — la página nunca muestra el identificador en bruto con el que se la llama. consentHistory es la pista de auditoría de opt-in/opt-out del contacto, más reciente primero, limitada a 20 filas, tomada del mismo libro de consentimientos que sus operadores ven en el panel.

Cuerpo de petición PUT

  • channelPreferences — se permite mapa parcial (Zod partial-record); se requiere al menos un canal.
  • frequencyPreference — opcional, uno de all, important_only, weekly_digest, monthly_digest.
  • topicPreferences — mapa opcional { topicId: opted_in | opted_out } validado contra sus temas configurados; los ids desconocidos se ignoran.
  • requestDataDeletion — establece una solicitud de borrado GDPR junto al opt-out (vea la sección 6).
Una respuesta 422 porta incidencias por campo para que el formulario alojado pueda señalar la elección inválida.

4. Cómo fluyen las actualizaciones

Un opt-in/opt-out escrito aquí no es solo un flag de UI — se actualizan las mismas cuatro superficies de cumplimiento que escribe una palabra clave STOP:
  • Libro de consentimientos. Se agrega una fila consent_records por canal (o por tema) con source: preference_center — su pista de auditoría de carga de la prueba del Art. 7 GDPR.
  • Lista de supresión. En cualquier canal dado de baja, el teléfono/correo canónico del contacto se inserta con ámbito all — un bloqueo inter-canales que lee toda puerta de envío.
  • Valla STOP. Se fija una valla rápida de Redis en el opt-out (y se limpia en un re-opt-in completo), de modo que los lotes de campaña en curso ven el cambio antes de que se propague la supresión más lenta de la base de datos.
  • Registro de auditoría. compliance.preference_center_updated se registra cuando usted cambia la configuración, y los eventos de opt-in/out a nivel de contacto se capturan en el libro de consentimientos.
El re-opt-in es simétrico: un opt-in completo (todos los canales opted_in) revoca las filas de supresión activas del teléfono del contacto y limpia la valla STOP, mientras el libro de consentimientos gana la entrada invertida.
Tema vs. canal. Un opt-out a nivel de canal siempre gana — un control de tema estrecha el consentimiento dentro de los canales que el contacto aún acepta. Los ids de tema desconocidos en un PUT se ignoran en lugar de persistirse, de modo que un formulario obsoleto no puede escribir claves de atributo arbitrarias.

5. Semántica del control de borrado GDPR

Cuando showGdprDelete está habilitado y el contacto marca requestDataDeletion: true en el PUT, la API registra una solicitud de borrado GDPR heredada — una fila pending marcada para su proceso de borrado de datos — junto al opt-out. Ese marcado es deliberado: el control de borrado del centro de preferencias marca al contacto, pero no inicia el pipeline DSAR trackeado.
El control de borrado del centro de preferencias no tiene reloj de SLA, no tiene exportación de datos descifrados y no tiene certificado de supresión del Artículo 17. Para una solicitud de derecho al borrado que su DPO pueda seguir, preséntela por el endpoint DSAR (POST /compliance/dsar, owner/admin) — vea Data Subject Access Requests y la guía DSAR + registro de brechas.

6. Probarlo

Dos ejemplos curl listos para pegar en un script de humo: Guardar la configuración:
Esperado: 201 con la configuración guardada como eco. Generar un enlace y ejercer los endpoints públicos:
Esperado: el GET devuelve las preferencias actuales del contacto; el PUT devuelve updated: true más las preferencias aplicadas y, cuando se solicita, una entrada gdprRequest. Fallos comunes contra los que comprobar: 400 INVALID_TOKEN (token malformado), 401 TOKEN_EXPIRED (TTL superado o firma no coincidente — genere un enlace nuevo), 422 VALIDATION_ERROR (incidencias a nivel de campo en el cuerpo de configuración o actualización) y 404 NOT_FOUND cuando el centro de preferencias está deshabilitado o el id de contacto no existe.