API REST (Desarrolladores)
Gestión de Riesgos

API de Gestión de Riesgos

El módulo de Gestión de Riesgos está disponible en todos los planes. Los límites de registros son: Starter 30 riesgos, Professional 100, Business y Enterprise ilimitados. Consulta la guía funcional del módulo para más contexto.

El módulo de riesgos implementa una matriz de evaluación 5×5 probabilidad × impacto (escala 1 a 5 para cada dimensión), produciendo un puntaje de riesgo entre 1 y 25. Los riesgos se categorizan según las dimensiones clave del estándar ISO 27701 §6.3 adaptadas a la Ley 21.719.

Base URL: https://api.dpolab.com/api/v1/risks

Resumen de endpoints

MétodoEndpointRol mínimoDescripción
GET/risksVIEWERListar riesgos con paginación
POST/risksANALYST+Crear riesgo
GET/risks/:idVIEWERObtener detalle de riesgo
PUT/risks/:idANALYST+Actualizar riesgo
DELETE/risks/:idADMINEliminar riesgo (soft delete)
GET/risks/heatmapVIEWERMapa de calor 5×5
GET/risks/statsVIEWEREstadísticas globales
GET/risks/threatsVIEWERCatálogo de amenazas
POST/risks/:id/action-plansANALYST+Crear plan de acción
PUT/risks/:id/action-plans/:planIdANALYST+Actualizar plan de acción
DELETE/risks/:id/action-plans/:planIdANALYST+Eliminar plan de acción

Riesgos

Listar riesgos

GET /risks

Retorna riesgos ordenados por puntaje descendente (mayor riesgo primero). Cada entrada incluye el asignado responsable si lo tiene.

Query params opcionales:

ParamTipoDescripción
legalEntityIdUUIDFiltrar por entidad legal
categoryenumVer categorías disponibles abajo
statusenumIDENTIFIED, ANALYZING, TREATING, MONITORED, CLOSED
dpiaIdUUIDFiltrar riesgos vinculados a una DPIA específica
minScoreinteger (1-25)Puntaje mínimo (usa el puntaje actual si existe, si no el inicial)
maxScoreinteger (1-25)Puntaje máximo
pageintegerDefault: 1
limitinteger (máx. 100)Default: 20
curl "https://api.dpolab.com/api/v1/risks?category=PRIVACY_RIGHTS&minScore=10" \
  -H "Authorization: Bearer {token}"

Respuesta (200):

{
  "success": true,
  "data": {
    "risks": [
      {
        "id": "risk_001",
        "legalEntityId": "entity_xyz",
        "title": "Acceso no autorizado a datos de clientes",
        "category": "CONFIDENTIALITY",
        "subcategory": "Control de acceso",
        "threatRef": "T-003",
        "probability": 3,
        "impact": 5,
        "riskScoreInitial": 15,
        "probabilityCurrent": null,
        "impactCurrent": null,
        "riskScoreCurrent": null,
        "probabilityResidual": null,
        "impactResidual": null,
        "riskScoreResidual": null,
        "status": "TREATING",
        "treatment": "MITIGATE",
        "dpiaId": null,
        "dpiaRequired": false,
        "assignee": {
          "userId": "usr_abc",
          "name": "María González",
          "email": "[email protected]"
        },
        "createdAt": "2026-04-01T09:00:00Z",
        "updatedAt": "2026-05-10T14:00:00Z"
      }
    ],
    "pagination": {
      "page": 1,
      "limit": 20,
      "total": 8
    }
  }
}

Crear riesgo

POST /risks

Requiere rol ANALYST o superior. Sujeto al límite del plan.

Los riesgos con puntaje inicial igual o superior a 10 generan automáticamente una tarea de seguimiento para el equipo de cumplimiento.

curl -X POST https://api.dpolab.com/api/v1/risks \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "legalEntityId": "entity_xyz",
    "title": "Acceso no autorizado a datos de clientes",
    "description": "Riesgo de acceso indebido a la base de datos de CRM por personal sin autorización.",
    "category": "CONFIDENTIALITY",
    "subcategory": "Control de acceso",
    "threatRef": "T-003",
    "probability": 3,
    "impact": 5,
    "dpiaRequired": false,
    "treatment": "MITIGATE"
  }'
CampoTipoRequeridoDescripción
legalEntityIdUUIDEntidad legal responsable
titlestring (2-300 chars)Título del riesgo
descriptionstring (máx. 5000 chars)NoDescripción detallada (cifrada en reposo)
categoryenumVer categorías abajo
subcategorystring (máx. 200 chars)NoSubcategoría libre
threatRefstring (máx. 50 chars)NoCódigo de amenaza del catálogo (p. ej. T-003)
probabilityinteger (1-5)Probabilidad de ocurrencia
impactinteger (1-5)Impacto si ocurre
dpiaIdUUIDNoDPIA asociada
dpiaRequiredbooleanNoIndica si este riesgo requiere DPIA
treatmentenumNoACCEPT, MITIGATE, TRANSFER, AVOID

Respuesta (201):

{
  "success": true,
  "data": {
    "risk": {
      "id": "risk_new009",
      "title": "Acceso no autorizado a datos de clientes",
      "probability": 3,
      "impact": 5,
      "riskScoreInitial": 15,
      "status": "IDENTIFIED",
      "createdAt": "2026-05-24T10:00:00Z"
    }
  }
}

Obtener detalle de riesgo

GET /risks/:id

Retorna el riesgo completo incluyendo description (descifrada), todos los puntajes (inicial, actual, residual) y metadatos.

curl https://api.dpolab.com/api/v1/risks/risk_001 \
  -H "Authorization: Bearer {token}"

Actualizar riesgo

PUT /risks/:id

Requiere rol ANALYST o superior. Acepta los mismos campos que la creación más los puntajes actuales y residuales. Solo envía los campos que quieras modificar.

curl -X PUT https://api.dpolab.com/api/v1/risks/risk_001 \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "probabilityCurrent": 2,
    "impactCurrent": 5,
    "probabilityResidual": 1,
    "impactResidual": 3,
    "status": "MONITORED",
    "treatment": "MITIGATE"
  }'
Campo adicionalTipoDescripción
probabilityCurrentinteger (1-5) o nullProbabilidad tras medidas implementadas
impactCurrentinteger (1-5) o nullImpacto tras medidas implementadas
probabilityResidualinteger (1-5) o nullProbabilidad residual esperada
impactResidualinteger (1-5) o nullImpacto residual esperado
statusenumIDENTIFIED, ANALYZING, TREATING, MONITORED, CLOSED

El sistema calcula automáticamente riskScoreCurrent = probabilityCurrent × impactCurrent y riskScoreResidual = probabilityResidual × impactResidual cuando se envían esos campos.

Eliminar riesgo

DELETE /risks/:id

Requiere rol ADMIN. Los riesgos se mantienen para auditoría incluso al eliminarlos (soft delete). El estado pasa a CLOSED y se marca como eliminado.


Mapa de calor

GET /risks/heatmap

Retorna la distribución de riesgos en la matriz 5×5. Solo incluye riesgos que no están en estado CLOSED. Usa el puntaje actual si existe; si no, el puntaje inicial.

Query params opcionales:

ParamDescripción
legalEntityIdFiltrar por entidad legal
curl "https://api.dpolab.com/api/v1/risks/heatmap?legalEntityId=entity_xyz" \
  -H "Authorization: Bearer {token}"

Respuesta (200):

{
  "success": true,
  "data": {
    "matrix": [
      [0, 1, 0, 0, 0],
      [0, 0, 2, 1, 0],
      [1, 0, 0, 0, 1],
      [0, 0, 1, 0, 0],
      [0, 0, 0, 1, 0]
    ],
    "risks": [
      {
        "id": "risk_001",
        "title": "Acceso no autorizado a datos de clientes",
        "probability": 3,
        "impact": 5,
        "score": 15,
        "status": "TREATING",
        "category": "CONFIDENTIALITY"
      }
    ]
  }
}

La matrix es un arreglo de 5×5 donde matrix[impacto-1][probabilidad-1] contiene el número de riesgos en esa celda. Impacto y probabilidad van de 1 (bajo) a 5 (muy alto), siendo matrix[4][4] la celda de mayor criticidad (probabilidad 5, impacto 5).


Estadísticas

GET /risks/stats

Query params opcionales: legalEntityId.

curl https://api.dpolab.com/api/v1/risks/stats \
  -H "Authorization: Bearer {token}"

Respuesta (200):

{
  "success": true,
  "data": {
    "total": 14,
    "avgScore": 11.2,
    "avgInitialScore": 12.8,
    "byCategory": {
      "CONFIDENTIALITY": 5,
      "INTEGRITY": 2,
      "AVAILABILITY": 1,
      "PRIVACY_RIGHTS": 4,
      "PHYSICAL": 0,
      "THIRD_PARTY": 1,
      "LEGAL_REGULATORY": 1
    },
    "byStatus": {
      "IDENTIFIED": 3,
      "ANALYZING": 2,
      "TREATING": 5,
      "MONITORED": 3,
      "CLOSED": 1
    },
    "remediationPct": 22,
    "highRiskCount": 4
  }
}
CampoDescripción
avgScorePromedio del puntaje actual (o inicial si no hay actual)
avgInitialScorePromedio del puntaje inicial en todos los riesgos
remediationPctReducción porcentual del puntaje inicial al residual (solo riesgos con score residual registrado)
highRiskCountRiesgos activos con puntaje actual ≥ 15 (zona roja de la matriz)

Catálogo de amenazas

GET /risks/threats

Retorna el catálogo de amenazas predefinidas del sistema. Los campos ref y title se pueden usar como referencia en el campo threatRef al crear un riesgo.

curl https://api.dpolab.com/api/v1/risks/threats \
  -H "Authorization: Bearer {token}"

Respuesta (200):

{
  "success": true,
  "data": {
    "threats": [
      {
        "id": "threat_001",
        "ref": "T-001",
        "title": "Acceso no autorizado a sistemas",
        "category": "CONFIDENTIALITY",
        "isDefault": true
      },
      {
        "id": "threat_002",
        "ref": "T-002",
        "title": "Pérdida o robo de dispositivos",
        "category": "CONFIDENTIALITY",
        "isDefault": true
      }
    ]
  }
}

Planes de acción

Cada riesgo puede tener múltiples planes de acción para gestionar su tratamiento.

Crear plan de acción

POST /risks/:id/action-plans

Requiere rol ANALYST o superior.

curl -X POST https://api.dpolab.com/api/v1/risks/risk_001/action-plans \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Implementar autenticación multifactor en CRM",
    "description": "Activar MFA para todos los usuarios con acceso a datos de clientes.",
    "dueDate": "2026-07-31",
    "status": "PENDING"
  }'
CampoTipoRequeridoDescripción
titlestring (2-300 chars)Acción concreta a tomar
descriptionstring (máx. 5000 chars)NoDetalle de implementación
dueDatestring YYYY-MM-DDNoFecha límite
statusenumNoPENDING, IN_PROGRESS, COMPLETED, CANCELLED — default: PENDING

Respuesta (201):

{
  "success": true,
  "data": {
    "actionPlan": {
      "id": "plan_001",
      "riskId": "risk_001",
      "title": "Implementar autenticación multifactor en CRM",
      "dueDate": "2026-07-31",
      "status": "PENDING",
      "createdAt": "2026-05-24T10:00:00Z"
    }
  }
}

Actualizar plan de acción

PUT /risks/:id/action-plans/:planId

Acepta los mismos campos que la creación. Solo envía los campos que quieras modificar.

curl -X PUT https://api.dpolab.com/api/v1/risks/risk_001/action-plans/plan_001 \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{ "status": "COMPLETED" }'

Eliminar plan de acción

DELETE /risks/:id/action-plans/:planId

Eliminación permanente.

curl -X DELETE https://api.dpolab.com/api/v1/risks/risk_001/action-plans/plan_001 \
  -H "Authorization: Bearer {token}"

Categorías de riesgo

CategoríaDescripción
CONFIDENTIALITYAcceso o divulgación no autorizados de datos personales
INTEGRITYAlteración, corrupción o modificación no autorizada
AVAILABILITYPérdida de acceso o disponibilidad del dato
PRIVACY_RIGHTSIncumplimiento de derechos ARSOP o bases legales
PHYSICALPérdida de dispositivos, acceso físico no autorizado
THIRD_PARTYRiesgos asociados a encargados, subencargados o proveedores
LEGAL_REGULATORYIncumplimiento normativo (Ley 21.719, GDPR, sectorial)

Estados de riesgo

EstadoDescripción
IDENTIFIEDRiesgo identificado, pendiente de análisis
ANALYZINGEn evaluación de probabilidad e impacto
TREATINGCon planes de acción activos en ejecución
MONITOREDTratamiento completado, en seguimiento continuo
CLOSEDRiesgo cerrado (eliminado o aceptado definitivamente)

Interpretación de la matriz 5×5

PuntajeNivelAcción recomendada
1-4BajoMonitorear periódicamente
5-9ModeradoGestionar con plan de acción
10-14AltoAtención prioritaria, plazo definido
15-25CríticoAcción inmediata, posible DPIA requerida
⚠️

Los riesgos con puntaje inicial ≥ 10 generan automáticamente una tarea de seguimiento en el módulo de tareas. Los riesgos con dpiaRequired: true aparecen como recomendación en el screening de DPIA.

Ver también