Actividades de tratamiento
El registro de actividades de tratamiento (RAT) es el inventario legal de todo lo que el colegio hace con datos personales. Cada actividad (processing_activity) describe una finalidad; su contenido vive en versiones selladas (processing_activity_versions), y sobre las actividades de alto riesgo se levantan evaluaciones de impacto (dpia_assessments, EIPD, Art. 15 ter). Por API puedes leer todo el registro y escribir el RAT; la autoría de EIPD es de consola.
La misma superficie para integradores partner está en Actividades de tratamiento (Partner API); el registro de riesgos asociado, en Riesgos.
El modelo de versionado
Una actividad publica su contenido en versiones inmutables y monotónicas:
versionNumbercrece de a uno; la actividad apunta a la vigente concurrentVersionNumber.- Cada versión queda sellada con
noticeChecksum— SHA-256 sobre el contenido normativo (finalidad, aviso en lenguaje claro, base legal, modelo de consentimiento y sus opciones, resúmenes de retención/transferencia/automatización). Si el texto cambia, cambia el checksum: es la prueba de qué vio el apoderado. - Publicar una versión nueva puede invalidar los consentimientos anteriores (
invalidatesPreviousConsents): las solicitudespending/grantedde versiones previas pasan ainvalidatedy se dispara la recaptura. La respuesta te entrega los ids afectados. - Lo que no envíes en la versión nueva (
dataCategories,recipients,consentOptions) se arrastra desde la versión anterior; lo que envíes la reemplaza. - Publicar cuenta como revisión: fija
lastReviewedAt, calcula el próximoreviewDueAty reabre las EIPD aprobadas de la actividad.
Listar actividades
Requiere processing_activities.read. Pagina con limit y cursor. Cada actividad llega con su currentVersion, su política de retención y el conteo de EIPD (dpiaAssessmentCount).
Campos principales
- Nombre
code / name- Tipo
- string
- Descripción
Folio y nombre de la actividad.
- Nombre
status- Tipo
- string
- Descripción
draft,activeoarchived.
- Nombre
treatmentRole- Tipo
- string
- Descripción
El rol de la organización en esa actividad:
controller(responsable),processor(encargado o mandatario, Art. 15 bis) oboth. Tiene valor por defectocontroller, así que siempre viene en la respuesta, incluso en actividades creadas antes de que el campo existiera.
- Nombre
actingOnBehalfOf- Tipo
- string | null
- Descripción
Por cuenta de quién se trata, cuando el rol es
processoroboth. Encontrollerel servidor lo normaliza anull: un responsable no actúa por cuenta de nadie.
- Nombre
lawfulBasis- Tipo
- string
- Descripción
Base de licitud (por defecto
consent). La finalidad no es un campo de la actividad: vive en la versión comopurposeSummary.
- Nombre
sensitiveLawfulBasis- Tipo
- string | null
- Descripción
La base de licitud propia de los datos sensibles, que es un régimen distinto del general:
express_consent,legal_authorization,manifestly_public,vital_or_health_emergency,judicial_or_rights_defenseononprofit_members. Sólo tiene sentido coninvolvesSensitiveData: true; si la actividad deja de tratar datos sensibles, el servidor la limpia anull.
- Nombre
riskLevel / isHighRisk- Tipo
- string / boolean
- Descripción
Nivel de riesgo declarado; con las banderas
involvesSensitiveData,involvesMinorData,includesAutomatedDecisions,includesProfiling,includesInternationalTransfers,includesMonitoring,isLargeScale.
- Nombre
currentVersion- Tipo
- object | null
- Descripción
La versión vigente:
versionNumber,versionStatus,title,purposeSummary,plainLanguageNotice,legalBasisDetail,sensitiveLegalBasisDetail,consentModel(bundled|granular),noticeChecksum,publishedAt…
- Nombre
reviewDueAt / lastReviewedAt- Tipo
- timestamp
- Descripción
El ciclo de revisión anual del RAT.
curl -G "https://app.edugoverna.com/api/processing-activities" \
-H "x-api-key: {tu_api_key}" \
-d limit=25
{
"processingActivities": [
{
"id": "a2f1…",
"code": "ACT-004",
"name": "Comunicaciones académicas",
"status": "active",
"treatmentRole": "controller",
"actingOnBehalfOf": null,
"lawfulBasis": "consent",
"sensitiveLawfulBasis": null,
"consentRequired": true,
"involvesSensitiveData": false,
"involvesMinorData": true,
"includesAutomatedDecisions": false,
"includesProfiling": false,
"riskLevel": "medium",
"isHighRisk": false,
"currentVersionNumber": 2,
"currentVersion": {
"versionNumber": 2,
"versionStatus": "published",
"title": "v2 · salidas pedagógicas",
"purposeSummary": "Informar y coordinar actividades académicas…",
"consentModel": "bundled",
"noticeChecksum": "9b1e…",
"publishedAt": "2026-07-30T14:00:00.000Z"
},
"retentionPolicy": null,
"dpiaAssessmentCount": 0,
"reviewDueAt": "2027-07-30T14:00:00.000Z"
}
],
"meta": {
"totalMatchedCount": 9,
"limit": 25,
"returnedCount": 9,
"nextCursor": null,
"hasMore": false
}
}
El detalle (GET /processing-activities/:processingActivityId) agrega el historial versions[] (con consentRequestCount por versión), los consentRequestCounts de la actividad —el radio de impacto de la próxima publicación invalidante— y expande currentVersion con sus dataCategories[] y recipients[].
Publicar una versión nueva
Requiere processing_activities.write. Acuña y publica de inmediato la versión siguiente (sellada con su noticeChecksum). Todos los campos son opcionales: lo omitido se arrastra de la versión anterior.
Si el screening del Art. 15 ter exige EIPD y la actividad no tiene una viva, la publicación se rechaza con 409 DPIA_REQUIRED; si la tiene pero sin descripción, necesidad o proporcionalidad, con 409 DPIA_INCOMPLETE (ver la EIPD mínima del núcleo).
Atributos opcionales frecuentes
- Nombre
title / purposeSummary / plainLanguageNotice- Tipo
- string
- Descripción
El contenido normativo que verá el titular.
- Nombre
legalBasisDetail / sensitiveLegalBasisDetail- Tipo
- string
- Descripción
El fundamento de la base de licitud, y —cuando la actividad trata datos sensibles— el de la base sensible declarada en la actividad. Este último sólo entra al
noticeChecksumcuando trae contenido, para no invalidar los sellos acuñados antes de que el campo existiera.
- Nombre
consentModel- Tipo
- string
- Descripción
bundledogranular; congranular, defineconsentOptions[]({ code, label, description? }, hasta 20).
- Nombre
dataCategories / recipients- Tipo
- array
- Descripción
Categorías de datos y destinatarios de la versión (hasta 100 c/u); reemplazan los de la versión anterior si se envían.
- Nombre
invalidatesPreviousConsents- Tipo
- boolean
- Descripción
Si la publicación invalida los consentimientos previos y dispara la recaptura.
- Nombre
requiresGuardianAuthorization- Tipo
- boolean
- Descripción
Si la actividad necesita además la autorización escrita del apoderado (salidas, giras). Cuando un titular decide por sí mismo según su edad, junto a su solicitud se abre otra para el apoderado (ver autorización del apoderado). Heredado de la versión anterior; por defecto
false.
- Nombre
ageTransitionPolicy- Tipo
- string
- Descripción
recertify_on_threshold_change(por defecto: al cruzar los 14 o los 16 años se invalida el consentimiento y se pide de nuevo a quien ahora decide) okeep_until_expiry(se mantiene hasta que venza o se revoque). Heredado de la versión anterior; la Consola lo muestra en la versión vigente y lo edita al publicar. Un partner puede fijarlo por su API, por eso conviene revisarlo.
curl -X POST "https://app.edugoverna.com/api/processing-activities/a2f1…/versions" \
-H "x-api-key: {tu_api_key}" \
-H "Content-Type: application/json" \
-d '{
"title": "v3 · incluye fotografías",
"purposeSummary": "Comunicaciones académicas y registro fotográfico de actividades.",
"invalidatesPreviousConsents": true
}'
{
"activity": {
"id": "a2f1…",
"currentVersionNumber": 3,
"currentVersion": {
"versionNumber": 3,
"versionStatus": "published",
"noticeChecksum": "c7a2…"
}
},
"invalidatedConsentRequestIds": ["b9d2…", "b9d3…"]
}
Las demás rutas del RAT
| Método y ruta | Permiso | Qué hace |
|---|---|---|
POST /processing-activities | processing_activities.write | Crea la actividad con su v1 en borrador (409 PROCESSING_ACTIVITY_CODE_CONFLICT si el folio choca). |
PATCH /processing-activities/:id | processing_activities.write | Edita los atributos de la actividad. |
POST /processing-activities/:id/review | processing_activities.write | Registra la revisión anual sin publicar versión. |
DELETE /processing-activities/:id | processing_activities.write | Elimina una actividad (sin consentimientos vivos). |
Tanto POST como PATCH aceptan treatmentRole, actingOnBehalfOf, sensitiveLawfulBasis e includesProfiling, con las normalizaciones del servidor: actingOnBehalfOf se limpia al pasar el rol a controller, y sensitiveLawfulBasis se limpia al dejar involvesSensitiveData en false.
Exportar el RAT
Requiere processing_activities.read — es una lectura, así que funciona igual con sesión de la consola o con una API key. Responde el archivo directo con su Content-Disposition: attachment, no un JSON con un enlace.
Parámetro
- Nombre
format- Tipo
- string
- Descripción
xlsx(por defecto) opdf. Cualquier otro valor cae enxlsx.
El libro trae dos hojas: RAT (una fila por actividad, con carátula del responsable, rol, bases de licitud, banderas de riesgo, categorías, destinatarios, retención y estado de la evaluación de impacto) y Criterios (los vocabularios y las reglas con que se llenó, incluidas las letras del Art. 15 ter y la versión de la metodología de riesgo). El PDF lleva el mismo contenido en formato de informe.
Es un documento de trabajo con fecha de corte, no una pieza sellada:
a diferencia del PDF de una EIPD aprobada, no queda guardado como
artifact y no lleva folio ni huella. La fecha va en el nombre del archivo
(rat-AAAA-MM-DD.xlsx), y cada descarga queda en la auditoría de la
organización.
curl -G "https://app.edugoverna.com/api/processing-activities/export" \
-H "x-api-key: {tu_api_key}" \
-d format=xlsx \
-o rat.xlsx
HTTP/1.1 200 OK
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Content-Disposition: attachment; filename="rat-2026-08-27.xlsx"
La ruta se resuelve antes que /processing-activities/:processingActivityId,
así que export nunca se lee como el id de una actividad.
Evaluaciones de impacto (EIPD)
Con una API key las EIPD son de sólo lectura (dpia.read): toda la autoría —crear, editar escenarios, recomputar, aprobar— exige dpia.write, que es un permiso de sesión.
GET /dpia responde { assessments } (filtros processingActivityId, status, reviewOverdue=true); cada evaluación trae su folio (assessmentCode), estado (draft, in_review, approved, under_revision), niveles de riesgo inherente y residual, y methodologyVersion — la metodología vigente es eg-2026.08: una matriz declarada 4×4 (probabilidad × impacto, valores 1–4) que resuelve low/medium/high/critical, agregando siempre el peor escenario, nunca un promedio. GET /dpia/:assessmentId agrega los scenarios con sus valores inherentes y residuales.
curl -G "https://app.edugoverna.com/api/dpia/screening" \
-H "x-api-key: {tu_api_key}" \
-d processingActivityId=a2f1…
{
"activity": { "id": "a2f1…", "name": "Videovigilancia patios", "code": "ACT-011" },
"screening": {
"level": "required",
"letters": ["c"],
"factors": ["declared_high_risk"],
"reasons": ["La actividad declara observación sistemática…"]
},
"letters": [
{
"letter": "c",
"legalText": "…",
"schoolMeaning": "Cámaras u observación sistemática de espacios…",
"reason": "…"
}
],
"existingAssessmentId": null,
"existingAssessmentCode": null,
"suggestedTemplates": [
{ "key": "cctv", "name": "Videovigilancia escolar", "whenToUse": "…" }
]
}
Cómo leer el screening
existingAssessmentId y existingAssessmentCode apuntan a la evaluación viva más reciente de la actividad (draft, in_review, approved o under_revision); una archivada o reemplazada no cuenta. Si vienen con valor, lo que corresponde es continuar esa evaluación, no abrir otra.
level es la respuesta (required, recommended o not_required) y llega acompañada de por qué:
lettersson los casos que el Art. 15 ter "requiere siempre":adecisiones automatizadas con efectos jurídicos significativos ·btratamiento masivo o a gran escala ·cmonitoreo sistemático de una zona de acceso público ·ddatos sensibles bajo una excepción del consentimiento. Cualquiera de ellas dejalevel: "required".factorsson las señales del inciso general:declared_high_risk,sensitive_data,international_transfer,profiling,minor_data.
minor_data y profiling son agravantes, no gatillos. Por sí solos dejan la evaluación en recommended; acompañando a cualquier otra señal, entran a reasons y la evaluación queda required.
Que includesProfiling no dispare por sí solo es deliberado: la letra a) exige "efectos jurídicos significativos", y elaborar perfiles sin decidir nada sobre el estudiante no la configura. Eso sí, obliga igualmente a informarlo en la política pública (Art. 14 ter l), que pide declarar la existencia de decisiones automatizadas incluida la elaboración de perfiles). Un colegio que además decide sobre esos perfiles marca includesAutomatedDecisions, y ahí sí es la letra a).
El piso de impacto para NNA
Al escribir un escenario (POST /dpia/:assessmentId/scenarios, sesión + dpia.write) rige un piso: si la evaluación cuelga de una actividad con involvesSensitiveData: true, el escenario declara affectedSubjectTypes con student y el inherentImpact queda bajo 3 (Significativo), hay que fundamentar la calificación por escrito en impactRationale.
La regla es asimétrica según el origen de la fila:
origin | Qué pasa |
|---|---|
manual (por defecto) | Sin impactRationale, la escritura se rechaza con 422 NNA_IMPACT_JUSTIFICATION_REQUIRED. |
template · suggested | El escenario se guarda y la respuesta 201 trae warnings: ["nna_impact_floor"]. Llegan pre-puntuadas y la persona las revisa igual. |
El piso nunca altera el puntaje: no sube el impacto ni cambia el nivel. Sólo exige que la calificación baja quede defendida, que es lo que la hace sostenible ante la Agencia en los dos sentidos.
Los escenarios aceptan además probabilityRationale e impactRationale como fundamento separado de cada eje (hasta 2.000 caracteres cada uno), distintos de la justification general del escenario.
Rutas de EIPD
| Método y ruta | Permiso | Qué hace |
|---|---|---|
GET /dpia | dpia.read | Lista las evaluaciones. |
GET /dpia/:assessmentId | dpia.read | Detalle con escenarios de riesgo. |
GET /dpia/screening?processingActivityId=… | dpia.read | El test del Art. 15 ter: si la actividad exige EIPD y por qué letras. |
GET /dpia/templates | dpia.read | Plantillas disponibles (videovigilancia, plataformas, etc.). |
POST /dpia · PATCH /dpia/:id · escenarios · medidas · recompute · approval · revision · reviews · document · templates/:key/adopt | dpia.write | Sólo disponible con sesión de la consola. |
POST /dpia, PATCH /dpia/:id y POST /dpia/templates/:key/adopt aceptan interviewConversationId (uuid): la conversación de la entrevista que redactó la evaluación, que queda en metadata.interviewConversationId. El adopt acepta además summary, necessityAssessment, proportionalityAssessment y mitigationPlan, que reemplazan el borrador de la plantilla sin marcar ninguna sección como revisada. Al editar, una sección queda marcada «editada» sólo si su texto cambió de verdad.
La disponibilidad de la EIPD depende del plan contratado: en organizaciones
sin el módulo licenciado estas rutas responden 403 MODULE_NOT_LICENSED.
Los escenarios de una EIPD comparten catálogo de medidas y matriz con el registro de riesgos.