---
title: "Derechos ARCO · Partner API"
description: "Referencia de los endpoints de derechos ARCO de la API Partner: portal de derechos del encargado, creación y cierre de solicitudes bajo la Ley 21.719."
url: "https://docs.edugoverna.com/derechos-arco"
---
# Derechos ARCO

La Ley 21.719 reconoce a los titulares los derechos de acceso, rectificación, supresión, oposición, portabilidad y bloqueo. Como encargado de tratamiento, tu plataforma puede recibir estos requerimientos directamente — un apoderado que escribe a tu soporte pidiendo que borren los datos de su hijo — y esta familia de endpoints te permite registrarlos en Edugoverna, publicar tu propio portal de derechos y cerrar los casos con su respuesta formal. {{ className: 'lead' }}

<Note>
  Todas las rutas de esta página cuelgan de la URL base
  `https://app.edugoverna.com/api/partner/v1/organizations/:organizationId`. Los
  cambios de estado de los casos llegan también como [webhooks](/webhooks)
  `rights_request.*` (`created`, `updated`, `closed`, `document.added`,
  `export_ready`). El flujo completo, incluidos los plazos legales, está en la
  [guía de flujo ARCO](/guias/flujo-arco).
</Note>

## El modelo de solicitud de derechos

Una solicitud (`rightsRequest`) tiene un `requestType` (uno de los seis derechos), uno o más titulares vinculados, y un plazo legal `dueAt` que Edugoverna calcula al crearla: los días hábiles configurados en el portal ARCO propio de la organización (la regla por tipo de derecho si existe; si no, su `defaultSlaDays`; por defecto 15), contados desde la presentación y anclados al fin del día en horario de Santiago. El `defaultSlaDays` de tu portal de partner no altera este plazo — por eso la respuesta de tu portal lo dice en el propio campo `appliesTo: "partner_portal_only"`. La dirección pública del portal ARCO **del colegio**, que es donde un titular ejerce derechos ante el responsable, la obtienes en [la conexión](/autenticacion#la-conexion-vista-por-el-partner) (`organization.arcoPortal.url`). Una prórroga formal (única, de hasta 15 días hábiles adicionales) queda en `extendedDueAt`.

El ciclo de vida de `status` es: `submitted` → `in_progress` | `processing` → `ready_to_close` → `completed` | `denied` (`failed` señala un error de conector pendiente de triaje). Cada caso recibe además un folio legible (`portalTrackingCode`) con el que el solicitante puede seguir su estado.

El paquete que devuelven las lecturas incluye las colecciones asociadas al caso: `subjects` (titulares vinculados), `actions` (acciones de cumplimiento), `exports`, `documents`, `messages`, `closures`, `restrictions` (bloqueos activos) y `anonymizationJobs`.

---

## Obtener el portal ARCO {{ tag: 'GET', label: '/v1/organizations/:organizationId/arco/portal' }}

<Row>
  <Col>

    Devuelve la configuración del portal de derechos **propio de tu cuenta de partner** sobre esta organización, o `null` si aún no lo has creado. Cada partner ve y administra únicamente su propio portal; el del sostenedor y los de otros encargados no son visibles desde esta ruta.

    Permiso requerido: `partner.arco_portals.read` · Alcance de conexión: `arco_portals:read`.

  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="GET" label="/v1/.../arco/portal">

    ```bash {{ title: 'cURL' }}
    curl https://app.edugoverna.com/api/partner/v1/organizations/org_2f7a/arco/portal \
      -H "Authorization: Bearer {keyId}.{secret}"
    ```

    ```js
    const response = await fetch(
      'https://app.edugoverna.com/api/partner/v1/organizations/org_2f7a/arco/portal',
      { headers: { Authorization: `Bearer ${keyId}.${secret}` } },
    )
    const { arcoPortal } = await response.json()
    ```

    </CodeGroup>

    ```json {{ title: 'Response' }}
    {
      "arcoPortal": {
        "id": "ap_4c8e",
        "organizationId": "org_2f7a",
        "ownerType": "partner",
        "slug": "milectura-derechos",
        "enabled": true,
        "ownerDisplayName": "Mi Lectura SpA",
        "primaryColor": "#0F4C81",
        "heroVariant": "dark",
        "dpoName": "María Fernández",
        "dpoEmail": "privacidad@milectura.cl",
        "sostenedor": null,
        "policyUrl": "https://milectura.cl/privacidad",
        "policyVersion": "2.1",
        "policyDate": "2026-06-01",
        "privacyContactEmail": "privacidad@milectura.cl",
        "arcopEnabled": true,
        "supportedExportFormats": ["json", "csv", "pdf", "xml"],
        "defaultSlaDays": 15,
        "appliesTo": "partner_portal_only",
        "portalIntroText": null,
        "requestTypeConfig": {
          // configuración por tipo de derecho
        }
      }
    }
    ```

  </Col>
</Row>

---

## Crear o actualizar el portal ARCO {{ tag: 'PUT', label: '/v1/organizations/:organizationId/arco/portal' }}

<Row>
  <Col>

    Crea (`201`) o actualiza (`200`) el portal de derechos de tu cuenta de partner sobre esta organización. El portal queda publicado en la URL pública `/arco/portal/{slug}`.

    Permiso requerido: `partner.arco_portals.write` · Alcance de conexión: `arco_portals:write`.

    El `slug` es globalmente único: si otro portal ya lo usa, la llamada responde `409 ARCO_PORTAL_SLUG_CONFLICT`. La escritura emite el evento de auditoría `arco_portal.config.updated` en la organización, con tu cuenta de partner como actor.

    Tanto esta respuesta como la de lectura incluyen `appliesTo: "partner_portal_only"`: `defaultSlaDays` y las reglas por tipo de derecho rigen tu portal público, no el plazo `dueAt` de los casos del colegio. Los casos que entran por tu portal quedan atribuidos a tu cuenta y aparecen en [tu listado](#listar-solicitudes-de-derechos).

    ### Atributos requeridos

    <Properties>
      <Property name="slug" type="string">
        Identificador de la URL pública (3–80 caracteres, minúsculas, dígitos
        y guiones; no puede empezar ni terminar con guion).
      </Property>
    </Properties>

    ### Atributos opcionales

    <Properties>
      <Property name="enabled" type="boolean">
        Si el portal está activo. Por defecto `true`.
      </Property>
      <Property name="ownerDisplayName" type="string">
        Nombre visible del responsable del portal.
      </Property>
      <Property name="primaryColor" type="string">
        Color principal del portal.
      </Property>
      <Property name="heroVariant" type="string">
        Variante visual de la cabecera. Por defecto `"dark"`.
      </Property>
      <Property name="dpoName" type="string">
        Nombre del delegado de protección de datos.
      </Property>
      <Property name="dpoEmail" type="string">
        Email del delegado de protección de datos.
      </Property>
      <Property name="sostenedor" type="string">
        Nombre del sostenedor, si corresponde mostrarlo.
      </Property>
      <Property name="policyUrl" type="string">
        URL de la política de privacidad. Enviar `null` la elimina.
      </Property>
      <Property name="policyVersion" type="string">
        Versión de la política publicada.
      </Property>
      <Property name="policyDate" type="string">
        Fecha de la política publicada.
      </Property>
      <Property name="privacyContactEmail" type="string">
        Email de contacto de privacidad.
      </Property>
      <Property name="arcopEnabled" type="boolean">
        Habilita el formulario de solicitudes del portal.
      </Property>
      <Property name="supportedExportFormats" type="array">
        Formatos de exportación ofrecidos: subconjunto de `json`, `csv`,
        `pdf`, `xml`. Por defecto, los cuatro.
      </Property>
      <Property name="defaultSlaDays" type="integer">
        Plazo de respuesta en días hábiles (1–20). Por defecto 15.
      </Property>
      <Property name="portalIntroText" type="string">
        Texto introductorio del portal (máx. 2000).
      </Property>
      <Property name="metadata" type="object">
        Objeto libre; se fusiona con el existente.
      </Property>
    </Properties>

  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="PUT" label="/v1/.../arco/portal">

    ```bash {{ title: 'cURL' }}
    curl -X PUT https://app.edugoverna.com/api/partner/v1/organizations/org_2f7a/arco/portal \
      -H "Authorization: Bearer {keyId}.{secret}" \
      -H "Content-Type: application/json" \
      -d '{
        "slug": "milectura-derechos",
        "ownerDisplayName": "Mi Lectura SpA",
        "dpoEmail": "privacidad@milectura.cl",
        "defaultSlaDays": 15,
        "appliesTo": "partner_portal_only"
      }'
    ```

    ```js
    const response = await fetch(
      'https://app.edugoverna.com/api/partner/v1/organizations/org_2f7a/arco/portal',
      {
        method: 'PUT',
        headers: {
          Authorization: `Bearer ${keyId}.${secret}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          slug: 'milectura-derechos',
          ownerDisplayName: 'Mi Lectura SpA',
          dpoEmail: 'privacidad@milectura.cl',
          defaultSlaDays: 15,
        }),
      },
    )
    const { arcoPortal } = await response.json()
    ```

    </CodeGroup>

    ```json {{ title: 'Response' }}
    {
      "arcoPortal": {
        "id": "ap_4c8e",
        "ownerType": "partner",
        "slug": "milectura-derechos",
        "enabled": true,
        "ownerDisplayName": "Mi Lectura SpA",
        "dpoEmail": "privacidad@milectura.cl",
        "defaultSlaDays": 15,
        "appliesTo": "partner_portal_only"
        // ...
      }
    }
    ```

  </Col>
</Row>

---

## Listar solicitudes de derechos {{ tag: 'GET', label: '/v1/organizations/:organizationId/arco/requests' }}

<Row>
  <Col>

    Devuelve una página de solicitudes de derechos de la organización, de la más reciente a la más antigua, cada una con su paquete completo.

    Permiso requerido: `partner.rights_requests.read` · Alcance de conexión: `rights_requests:read`.

    La bandeja es **la tuya**, no la del colegio: se listan los casos atribuidos a tu cuenta de partner — los que creaste por esta API y los que entraron por [tu propio portal ARCO](#crear-o-actualizar-el-portal-arco). Dos plataformas conectadas al mismo colegio no se ven los casos entre sí, ni los que el colegio abrió por su cuenta. Si tu integración lleva la mesa ARCO completa del colegio, el colegio lo declara al otorgar el alcance `rights_requests:read` con la condición `{ "readAll": true }`; con ella el listado devuelve toda la bandeja.

    ### Parámetros de consulta opcionales

    <Properties>
      <Property name="status" type="string">
        Filtra por estado (`submitted`, `in_progress`, `processing`,
        `ready_to_close`, `completed`, `denied`, `failed`).
      </Property>
      <Property name="requestType" type="string">
        Filtra por derecho (`access`, `rectification`, `suppression`,
        `opposition`, `portability`, `blocking`).
      </Property>
      <Property name="limit" type="integer">
        Tamaño de página, entre 1 y 200.
      </Property>
      <Property name="cursor" type="string">
        Cursor de la página anterior (`nextCursor`). Ver
        [Paginación](/paginacion).
      </Property>
    </Properties>

  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="GET" label="/v1/.../arco/requests">

    ```bash {{ title: 'cURL' }}
    curl -G https://app.edugoverna.com/api/partner/v1/organizations/org_2f7a/arco/requests \
      -H "Authorization: Bearer {keyId}.{secret}" \
      -d status=in_progress \
      -d limit=50
    ```

    ```js
    const response = await fetch(
      'https://app.edugoverna.com/api/partner/v1/organizations/org_2f7a/arco/requests?status=in_progress&limit=50',
      { headers: { Authorization: `Bearer ${keyId}.${secret}` } },
    )
    const { rightsRequests, totalMatchedCount, nextCursor } =
      await response.json()
    ```

    </CodeGroup>

    ```json {{ title: 'Response' }}
    {
      "rightsRequests": [
        {
          "id": "rr_9d3f",
          "requestType": "suppression",
          "requestChannel": "partner_api",
          "status": "in_progress",
          "summary": "Apoderada solicita eliminar los datos de su hija.",
          "submittedAt": "2026-08-18T13:20:00.000Z",
          "dueAt": "2026-09-09T02:59:59.999Z",
          "extendedDueAt": null,
          "closedAt": null,
          "portalTrackingCode": "ARCO-2026-0031-M3QK7D",
          "subjects": [
            {
              "subjectId": "9c1f6d1e-1c9d-4f6a-9a44-1f2ab5c0d9e1",
              "subjectSummary": { "displayName": "Martina Rojas Pino" }
            }
          ],
          "actions": [],
          "exports": [],
          "documents": [],
          "messages": [],
          "closures": [],
          "restrictions": [],
          "anonymizationJobs": []
          // ...
        }
      ],
      "totalMatchedCount": 4,
      "nextCursor": null
    }
    ```

  </Col>
</Row>

---

## Crear una solicitud de derechos {{ tag: 'POST', label: '/v1/organizations/:organizationId/arco/requests' }}

<Row>
  <Col>

    Registra una solicitud de derechos recibida por tu canal y la vincula a uno o más titulares del padrón. Responde `201` con el paquete del caso, ya con su `dueAt` calculado y su folio, y emite el webhook `rights_request.created`.

    Permiso requerido: `partner.rights_requests.write` · Alcance de conexión: `rights_requests:write`.

    Un caso de **supresión** siembra los trabajos de anonimización en estado de espera de aprobación: la redacción irreversible sólo se ejecuta cuando un revisor humano de la organización la aprueba (control a cuatro ojos), nunca por el solo registro del caso.

    Si algún `subjectId` no pertenece a la organización, la llamada completa falla con `404 RIGHTS_REQUEST_SUBJECT_NOT_FOUND`.

    ### Atributos requeridos

    <Properties>
      <Property name="requestType" type="string">
        Derecho ejercido: `access`, `rectification`, `suppression`,
        `opposition`, `portability` o `blocking`.
      </Property>
      <Property name="subjectIds" type="array">
        IDs de los titulares afectados (UUID), entre 1 y 200.
      </Property>
    </Properties>

    ### Atributos opcionales

    <Properties>
      <Property name="requestChannel" type="string">
        Canal de recepción. Por defecto `"partner_api"`.
      </Property>
      <Property name="requesterSubjectId" type="string">
        Titular que presenta la solicitud (por ejemplo, el apoderado), si es
        un titular del padrón.
      </Property>
      <Property name="requesterUserId" type="string">
        Usuario interno que la presenta, si aplica.
      </Property>
      <Property name="summary" type="string">
        Resumen del requerimiento (máx. 2000).
      </Property>
      <Property name="legalBasis" type="string">
        Base legal invocada (máx. 255).
      </Property>
    </Properties>

  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="POST" label="/v1/.../arco/requests">

    ```bash {{ title: 'cURL' }}
    curl https://app.edugoverna.com/api/partner/v1/organizations/org_2f7a/arco/requests \
      -H "Authorization: Bearer {keyId}.{secret}" \
      -H "Content-Type: application/json" \
      -d '{
        "requestType": "suppression",
        "subjectIds": ["9c1f6d1e-1c9d-4f6a-9a44-1f2ab5c0d9e1"],
        "requesterSubjectId": "5d2a8c3b-77e1-4b0e-9f1d-3c4e5f6a7b8c",
        "summary": "Apoderada solicita eliminar los datos de su hija."
      }'
    ```

    ```js
    const response = await fetch(
      'https://app.edugoverna.com/api/partner/v1/organizations/org_2f7a/arco/requests',
      {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${keyId}.${secret}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          requestType: 'suppression',
          subjectIds: ['9c1f6d1e-1c9d-4f6a-9a44-1f2ab5c0d9e1'],
          requesterSubjectId: '5d2a8c3b-77e1-4b0e-9f1d-3c4e5f6a7b8c',
          summary: 'Apoderada solicita eliminar los datos de su hija.',
        }),
      },
    )
    const rightsRequest = await response.json()
    ```

    </CodeGroup>

    ```json {{ title: 'Response' }}
    {
      "id": "rr_9d3f",
      "requestType": "suppression",
      "requestChannel": "partner_api",
      "status": "submitted",
      "submittedAt": "2026-08-25T12:30:00.000Z",
      "dueAt": "2026-09-16T02:59:59.999Z",
      "portalTrackingCode": "ARCO-2026-0031-M3QK7D",
      "requesterSubjectId": "5d2a8c3b-77e1-4b0e-9f1d-3c4e5f6a7b8c",
      "subjects": [
        {
          "subjectId": "9c1f6d1e-1c9d-4f6a-9a44-1f2ab5c0d9e1",
          "subjectSummary": { "displayName": "Martina Rojas Pino" }
        }
      ],
      "actions": [
        {
          "actionType": "anonymize_subject",
          "status": "pending"
        }
      ],
      "restrictions": [],
      "anonymizationJobs": [
        {
          "status": "awaiting_approval",
          "subjectId": "9c1f6d1e-1c9d-4f6a-9a44-1f2ab5c0d9e1"
        }
      ]
      // ...
    }
    ```

  </Col>
</Row>

---

## Obtener una solicitud de derechos {{ tag: 'GET', label: '/v1/organizations/:organizationId/arco/requests/:rightsRequestId' }}

<Row>
  <Col>

    Devuelve el paquete completo de un caso, incluidas sus acciones, documentos, mensajes, cierres, bloqueos y trabajos de anonimización. Si el caso no existe en la organización — o pertenece a otro partner y no tienes `readAll` — responde `404 RIGHTS_REQUEST_NOT_FOUND`, deliberadamente indistinguible.

    Permiso requerido: `partner.rights_requests.read` · Alcance de conexión: `rights_requests:read`.

  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="GET" label="/v1/.../arco/requests/rr_9d3f">

    ```bash {{ title: 'cURL' }}
    curl https://app.edugoverna.com/api/partner/v1/organizations/org_2f7a/arco/requests/rr_9d3f \
      -H "Authorization: Bearer {keyId}.{secret}"
    ```

    ```js
    const response = await fetch(
      'https://app.edugoverna.com/api/partner/v1/organizations/org_2f7a/arco/requests/rr_9d3f',
      { headers: { Authorization: `Bearer ${keyId}.${secret}` } },
    )
    const rightsRequest = await response.json()
    ```

    </CodeGroup>

    ```json {{ title: 'Response' }}
    {
      "id": "rr_9d3f",
      "requestType": "suppression",
      "status": "in_progress",
      "submittedAt": "2026-08-18T13:20:00.000Z",
      "dueAt": "2026-09-09T02:59:59.999Z",
      "portalTrackingCode": "ARCO-2026-0031-M3QK7D",
      "subjects": [ { "subjectId": "9c1f6d1e-…" } ],
      "actions": [ { "actionType": "anonymize_subject", "status": "pending" } ],
      "exports": [],
      "documents": [],
      "messages": [],
      "closures": [],
      "restrictions": [ { "restrictionType": "suppression_hold" } ],
      "anonymizationJobs": [ { "status": "awaiting_approval" } ]
      // ...
    }
    ```

  </Col>
</Row>

---

## Cerrar una solicitud de derechos {{ tag: 'POST', label: '/v1/organizations/:organizationId/arco/requests/:rightsRequestId/close' }}

<Row>
  <Col>

    Cierra formalmente un caso con su respuesta. Edugoverna genera el documento de respuesta final y el certificado de cierre como artefactos del caso, notifica por email al solicitante (cuando hay dirección registrada) y emite el webhook `rights_request.closed`. La respuesta es el paquete actualizado del caso, con `status` `completed` o `denied` y su registro en `closures`.

    Permiso requerido: `partner.rights_requests.write` · Alcance de conexión: `rights_requests:write`.

    Solo puedes cerrar los casos que ves: un caso de otro partner responde `404 RIGHTS_REQUEST_NOT_FOUND`, igual que en la lectura. La condición `readAll` se declara en el scope `rights_requests:read` y rige también aquí — quien ve toda la bandeja puede cerrar cualquier caso de ella.

    ### Atributos requeridos

    <Properties>
      <Property name="responseSummary" type="string">
        Respuesta entregada al solicitante (2–5000 caracteres). En un cierre
        `denied`, se registra además como motivo de la denegación.
      </Property>
    </Properties>

    ### Atributos opcionales

    <Properties>
      <Property name="outcome" type="string">
        Resultado del caso: `completed`, `partially_completed` o `denied`.
        Por defecto `completed`.
      </Property>
    </Properties>

  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="POST" label="/v1/.../arco/requests/rr_9d3f/close">

    ```bash {{ title: 'cURL' }}
    curl https://app.edugoverna.com/api/partner/v1/organizations/org_2f7a/arco/requests/rr_9d3f/close \
      -H "Authorization: Bearer {keyId}.{secret}" \
      -H "Content-Type: application/json" \
      -d '{
        "outcome": "completed",
        "responseSummary": "Los datos de la estudiante fueron eliminados de nuestros sistemas el 25 de agosto de 2026."
      }'
    ```

    ```js
    const response = await fetch(
      'https://app.edugoverna.com/api/partner/v1/organizations/org_2f7a/arco/requests/rr_9d3f/close',
      {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${keyId}.${secret}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          outcome: 'completed',
          responseSummary:
            'Los datos de la estudiante fueron eliminados de nuestros sistemas el 25 de agosto de 2026.',
        }),
      },
    )
    const rightsRequest = await response.json()
    ```

    </CodeGroup>

    ```json {{ title: 'Response' }}
    {
      "id": "rr_9d3f",
      "status": "completed",
      "respondedAt": "2026-08-25T12:30:00.000Z",
      "closedAt": "2026-08-25T12:30:00.000Z",
      "responseSummary": "Los datos de la estudiante fueron eliminados de nuestros sistemas el 25 de agosto de 2026.",
      "closures": [
        {
          "outcome": "completed",
          "notificationChannel": "email",
          "finalResponseArtifactId": "art_5f1a",
          "certificateArtifactId": "art_5f1b"
        }
      ]
      // ...
    }
    ```

  </Col>
</Row>
