Derechos ARCO vía API

La Ley 21.719 reconoce a cada titular los derechos de acceso, rectificación, supresión y oposición — y suma portabilidad y bloqueo — ejercibles ante cada responsable del tratamiento. En esta guía configurarás el portal de recepción, crearás solicitudes en nombre de un titular, las seguirás por API y webhooks, y las cerrarás dentro del plazo.

El ciclo de un caso:

  1. Configuras (una vez) tu portal ARCO → PUT /arco/portal. Los titulares pueden ingresar solicitudes ahí, o tu plataforma las crea por API.
  2. Creas la solicitud → POST /arco/requests, respuesta 201 con folio y fecha límite; evento rights_request.created.
  3. El caso avanza — documentos, prórrogas, exports — → eventos rights_request.updated, rights_request.document.added, rights_request.export_ready.
  4. El plazo se acerca o se vence → Edugoverna recuerda por correo al equipo responsable; tu integración lo vigila con dueAt.
  5. Respondes al titular y cierras → POST /arco/requests/:id/close; correo de cierre al solicitante (si el caso tiene email de contacto) y evento rights_request.closed.

Cada solicitud nace con una fecha límite (dueAt) calculada en días hábiles — la Ley 21.719 fija el máximo en 20 días hábiles — según la configuración de tu portal ARCO: el valor por tipo de derecho si lo definiste, si no defaultSlaDays, y en ausencia de configuración, 15 días hábiles. El vencimiento cae al final del día en horario de Chile continental, y una prórroga fundada puede extenderlo. Cuando el plazo se acerca o se vence, Edugoverna recuerda por correo al equipo responsable dentro de la consola; para tu integración, la fuente de verdad es el dueAt de cada caso — vigílalo por polling y no dejes que llegue al límite.

1. Configura el portal ARCO

El portal es la puerta pública donde los titulares ejercen sus derechos respecto de tu tratamiento como responsable. Vive en https://app.edugoverna.com/arco/portal/{slug} y cada credencial de socio ve y administra únicamente el suyo. Requiere partner.arco_portals.read para leer y partner.arco_portals.write para escribir.

GET /arco/portal devuelve { "arcoPortal": null } si aún no lo creas. El alta y la actualización son el mismo PUT:

PUT
/arco/portal
curl -X PUT https://app.edugoverna.com/api/partner/v1/organizations/{organizationId}/arco/portal \
  -H "Authorization: Bearer {keyId}.{secret}" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "plataforma-ejemplo",
    "enabled": true,
    "ownerDisplayName": "Plataforma Ejemplo SpA",
    "dpoName": "María Delgado",
    "dpoEmail": "privacidad@ejemplo.cl",
    "privacyContactEmail": "privacidad@ejemplo.cl",
    "policyUrl": "https://ejemplo.cl/politica-privacidad",
    "policyVersion": "2026-1",
    "supportedExportFormats": ["json", "csv", "pdf"],
    "defaultSlaDays": 15
  }'

Responde 201 al crear y 200 al actualizar. Los campos principales:

  • slug — obligatorio, 3–80 caracteres en minúsculas, dígitos y guiones. Es la URL pública y es único en toda la plataforma: si otro portal ya lo usa, la respuesta es 409 ARCO_PORTAL_SLUG_CONFLICT.
  • enabledtrue por defecto; en false el portal deja de recibir solicitudes sin perder su configuración.
  • dpoName, dpoEmail, privacyContactEmail, sostenedor, ownerDisplayName — la identificación del responsable que exige la ley en la primera plana del portal.
  • policyUrl, policyVersion, policyDate — la política de privacidad publicada; policyUrl: null la retira.
  • supportedExportFormats — formatos ofrecidos para acceso y portabilidad: json, csv, pdf, xml.
  • defaultSlaDays — 1 a 20 días hábiles.
  • primaryColor, heroVariant, portalIntroText — apariencia y texto de bienvenida.

2. Crea una solicitud en nombre del titular

Cuando el titular ejerce su derecho a través de tu plataforma — un formulario propio, un correo a tu soporte — regístralo por API para que el plazo legal empiece a correr con evidencia. Requiere partner.rights_requests.write.

POST
/arco/requests
curl https://app.edugoverna.com/api/partner/v1/organizations/{organizationId}/arco/requests \
  -H "Authorization: Bearer {keyId}.{secret}" \
  -H "Content-Type: application/json" \
  -d '{
    "requestType": "access",
    "requestChannel": "partner_api",
    "requesterSubjectId": "c2a4e8d1-13b7-4f6e-9a20-4e8b7c1d5f30",
    "summary": "La apoderada solicita copia de los datos de su hija tratados por la plataforma.",
    "subjectIds": ["8f3b7f0a-2f9d-4d4e-a1c3-77b2a0f1d942"]
  }'
  • requestType — obligatorio: access, rectification, suppression, opposition, portability o blocking.
  • subjectIds — obligatorio: los titulares afectados, entre 1 y 200 ids.
  • requesterSubjectId — quién ejerce el derecho (por ejemplo, la apoderada), cuando no coincide con los afectados.
  • requestChannel — de dónde vino el ejercicio; por defecto partner_api.
  • summary (hasta 2.000 caracteres) y legalBasis (hasta 255) — el contexto que leerá quien tramite el caso.

La respuesta 201 es el caso completo. Entre otros campos:

Respuesta (fragmento)

{
  "id": "7e1c4b9a-2d6f-4a83-9c05-b8f3e6a1d270",
  "requestType": "access",
  "requestChannel": "partner_api",
  "status": "submitted",
  "portalTrackingCode": "ARCO-2026-0318-M3QK7D",
  "submittedAt": "2026-08-25T13:40:12.000Z",
  "dueAt": "2026-09-16T02:59:59.999Z",
  "subjects": [{ "subjectId": "8f3b7f0a-2f9d-4d4e-a1c3-77b2a0f1d942" }],
  "documents": [],
  "messages": [],
  "closures": []
}

portalTrackingCode es el folio legible que puedes entregar al titular para que siga su caso en el portal.

3. Sigue los casos

Con partner.rights_requests.read, el listado acepta status, requestType, cursor y limit (máximo 200; ver Paginación) y responde { rightsRequests, totalMatchedCount, nextCursor }. El detalle vive en GET /arco/requests/:rightsRequestId y responde 404 RIGHTS_REQUEST_NOT_FOUND si el caso no existe en esa organización.

Para no depender del polling, suscribe la familia rights_request.* en Gestión » Webhooks:

  • Nombre
    rights_request.created
    Descripción

    Se abrió un caso — por API o desde el portal público.

  • Nombre
    rights_request.updated
    Descripción

    El caso cambió: una prórroga del plazo, un mensaje agregado al expediente.

  • Nombre
    rights_request.document.added
    Descripción

    Se agregó un documento al expediente (por ejemplo, el titular subió un antecedente desde el portal).

  • Nombre
    rights_request.export_ready
    Descripción

    Un export de acceso o portabilidad terminó de construirse.

  • Nombre
    rights_request.sla_due_soon
    Descripción

    El plazo legal está por vencer. Está en el catálogo suscribible, pero la plataforma aún no lo emite: hoy el aviso llega por correo al equipo responsable.

  • Nombre
    rights_request.sla_overdue
    Descripción

    El plazo legal venció con el caso aún abierto. Mismo estado que el anterior: suscribible, aún sin emisión.

  • Nombre
    rights_request.closed
    Descripción

    El caso se cerró con su respuesta final.

Ejemplo de payload (fragmento)

{
  "event": "rights_request.closed",
  "sourceType": "rights_request",
  "sourceId": "7e1c4b9a-2d6f-4a83-9c05-b8f3e6a1d270",
  "occurredAt": "2026-09-11T14:22:05.000Z",
  "data": {
    "id": "7e1c4b9a-2d6f-4a83-9c05-b8f3e6a1d270",
    "requestType": "access",
    "status": "completed",
    "portalTrackingCode": "ARCO-2026-0318-M3QK7D",
    "dueAt": "2026-09-16T02:59:59.999Z",
    "closures": [
      {
        "outcome": "completed",
        "createdAt": "2026-09-11T14:22:05.000Z"
      }
    ]
  }
}

El sobre y la verificación de firma son los mismos de toda la plataforma — cabeceras x-edugoverna-signature y x-edugoverna-timestamp — descritos en Webhooks.

4. Cierra el caso

El cierre registra la respuesta final, notifica por correo al solicitante si el caso tiene un email de contacto (los casos originados en el portal lo traen; los creados por API no llevan email, así que ahí la notificación corre por tu cuenta), y emite rights_request.closed:

POST
/arco/requests/:rightsRequestId/close
curl https://app.edugoverna.com/api/partner/v1/organizations/{organizationId}/arco/requests/{rightsRequestId}/close \
  -H "Authorization: Bearer {keyId}.{secret}" \
  -H "Content-Type: application/json" \
  -d '{
    "outcome": "completed",
    "responseSummary": "Se entregó al solicitante el archivo con la totalidad de los datos personales tratados, en formato JSON, junto con el detalle de finalidades y destinatarios."
  }'
  • outcomecompleted (por defecto), partially_completed o denied. Una denegación debe fundarse en una causal legal; el fundamento va en el resumen.
  • responseSummary — obligatorio, 2 a 5.000 caracteres: la respuesta que queda en el expediente y viaja en el correo de cierre al titular.

La respuesta es el caso ya cerrado, con su constancia de cierre en closures.

5. Qué queda fuera de la API

Dos operaciones son deliberadamente exclusivas de la consola, con una sesión de usuario de por medio:

  • La descarga de exports. rights_request.export_ready te avisa que el archivo de acceso o portabilidad está construido, pero su contenido — datos personales en bruto — solo se descarga desde la consola por quien tiene la sesión y el permiso. La API nunca sirve el archivo.
  • Las decisiones sensibles. Aprobar una supresión o anonimización (la revisión a cuatro ojos), conceder prórrogas y las demás resoluciones que alteran el expediente de forma irreversible se toman en la consola, donde quedan atribuidas a una persona concreta.

Tu integración abre casos, los observa y los cierra; los momentos irreversibles siguen siendo humanos.

¿Qué sigue?

¿Te sirvió esta página?