Registrar un consentimiento
/v1/consent-eventsDescripción
Registra un consentimiento obtenido en un canal propio del integrador — por ejemplo, un formulario en su propio sitio, distinto de los formularios de Fidelizador. El registro queda con source=api.
Un evento tiene dos partes. El encabezado dice qué término se aceptó y cómo; las reglas dicen qué se autoriza o se deniega, para qué identificador y para qué finalidad. Se envían juntos, en una sola llamada, y el evento queda inmutable.
Revocar es una regla con action: deny, no un estado del evento. Cada llamada agrega un registro nuevo y actualiza el estado vigente; nada se edita ni se borra.
La versión del término aplicada es siempre la vigente al momento de la llamada — no se acepta una versión específica en el request.
Autenticación
Authorizationbearer tokenheaderobligatorio- API key con scope
consent:write. Formato:Bearer FD.<key_id>.<token>. X-Instance-Slugstringheaderobligatorio
Request
Body:
{
"term_id": 4,
"method": "double_opt_in",
"rules": [
{
"channel": "mail",
"contact_type": "email_address",
"contact": "ana@ejemplo.cl",
"purpose_id": 1,
"action": "allow"
}
]
}
term_idintegerobligatorio- Id del término aceptado — ver `GET /v1/consent-terms`.
methodstring, enum: `single_opt_in | double_opt_in`obligatorio- Cómo se obtuvo el consentimiento.
rulesarrayobligatorio- Al menos una regla. Una por par canal + finalidad.
Cada elemento de rules:
channelstring, enum: `mail | sms | wsp | call | push`- Canal al que aplica la regla. Por defecto
mail. contact_typestring, enum: `email_address | phone_number | uniquecode`obligatorio- Qué identificador trae
contact. contactstringobligatorio- Identificador del titular, 1–254 caracteres.
purpose_idintegerobligatorio- Finalidad a la que aplica — ver `GET /v1/consent-purposes`.
actionstring, enum: `allow | deny`obligatorioallowotorga,denyrevoca.
El canal y el tipo de identificador tienen que ser compatibles: mail admite email_address o uniquecode; sms, wsp y call admiten phone_number o uniquecode; push admite solo uniquecode. Una combinación inválida devuelve 409.
Response
Location trae su URL (ver Headers).idintegerobligatorio- Identificador del evento creado.
term_idintegerobligatorio- —
term_version_idintegerobligatorio- Versión del término resuelta automáticamente (la vigente al momento de la llamada).
statusstring, enum: `confirmed | pending | expired`obligatorio- Un consentimiento registrado por esta vía nace
confirmed. methodstring, enum: `single_opt_in | double_opt_in`obligatorio- —
sourcestring, enum: `form | api | import | system`obligatorio- Siempre
apien la respuesta de este endpoint. confirmed_atstring (date-time) | null- —
expired_atstring (date-time) | null- —
created_atstring (date-time)obligatorio- —
rulesarrayobligatorio- Las reglas del evento, con el
idque se les asignó.
Errores
| Código | Cuándo |
|---|---|
| 404 | El term_id no existe en la cuenta (consent_term_not_found). |
| 409 | El término está inactivo (consent_term_inactive), no tiene ninguna versión vigente (consent_term_no_current_version), el tipo de identificador no corresponde al canal (consent_contact_type_channel_mismatch), o vienen dos reglas para el mismo par canal + finalidad (consent_duplicate_rule). |
Detalle completo en Errores genéricos y Errores genéricos.
- Las direcciones de correo se guardan en forma canónica: se normalizan a minúsculas y se recortan los espacios. Registrar
Ana@Ejemplo.cly consultar después porana@ejemplo.cldevuelve la misma regla. Losuniquecode, en cambio, se guardan tal cual: para ellosABCyabcson dos códigos distintos. - No existe una versión "actualizar" de este endpoint. Para revocar, registrar un evento nuevo cuya regla lleve
action: deny; el registro original queda intacto como evidencia. - Para saber si hoy se le puede enviar a alguien, usar
GET /v1/consent-rules/resolve— no el listado de eventos, que es historial.
curl -X POST "https://$API_HOST/v1/consent-events" \
-H "Authorization: Bearer $API_KEY" \
-H "X-Instance-Slug: $SLUG" \
-H "Content-Type: application/json" \
-d '{
"term_id": 4,
"method": "double_opt_in",
"rules": [
{
"contact_type": "email_address",
"contact": "ana@ejemplo.cl",
"purpose_id": 1,
"action": "allow"
}
]
}'
{
"id": 42,
"term_id": 4,
"term_version_id": 7,
"status": "confirmed",
"method": "double_opt_in",
"source": "api",
"confirmed_at": "2026-05-08T14:22:31Z",
"expired_at": null,
"created_at": "2026-05-08T14:22:31Z",
"rules": [
{
"id": 91,
"channel": "mail",
"contact_type": "email_address",
"contact": "ana@ejemplo.cl",
"purpose_id": 1,
"action": "allow",
"created_at": "2026-05-08T14:22:31Z"
}
]
}