---
title: "Derechos ARCO · API de organización"
description: "Solicitudes de derechos del titular por API: crear y consultar casos, contadores por vencimiento, extensión de plazo y configuración del portal ARCO."
url: "https://docs.edugoverna.com/api-organizacion/derechos"
---
# Derechos ARCO

Una solicitud de derechos (`rights_request`) es el expediente de un titular que ejerce acceso, rectificación, supresión, oposición, portabilidad o bloqueo. Por API puedes crear casos, listarlos por vencimiento, gestionar su plazo y configurar el portal ARCO público del colegio; la ejecución sensible (exportaciones, anonimización) queda reservada a la consola. {{ className: 'lead' }}

Para el recorrido completo de un caso —desde el portal público hasta el cierre notificado— revisa la [guía del flujo ARCO](/guias/flujo-arco) y la página de producto [Derechos ARCO](/derechos-arco).

## El modelo de la solicitud

<Properties>
  <Property name="requestType" type="string">
    Uno de `access`, `rectification`, `suppression`, `opposition`,
    `portability`, `blocking`.
  </Property>
  <Property name="status" type="string">
    Flujo: `submitted` → `in_progress` (o `processing` cuando ejecuta un
    conector externo) → `ready_to_close` → `completed` o `denied`. `failed`
    marca un error de conector pendiente de triage.
  </Property>
  <Property name="dueAt" type="timestamp">
    Plazo legal original: se fija al crear el caso como fin de día (hora de
    Santiago) tras los días hábiles del SLA configurado (por defecto 15, máximo
    20).
  </Property>
  <Property name="extendedDueAt" type="timestamp | null">
    Plazo extendido. El plazo efectivo es siempre `extendedDueAt ?? dueAt`.
  </Property>
  <Property name="portalTrackingCode" type="string">
    Código de seguimiento que el solicitante usa en el portal público. Se acuña
    siempre, también para casos creados por API.
  </Property>
  <Property name="subjects" type="array">
    Titulares alcanzados por el caso, cada uno con su `subjectSummary`.
  </Property>
  <Property
    name="actions / exports / documents / messages / closures"
    type="arrays"
  >
    El expediente completo: acciones de cumplimiento, exportaciones, documentos,
    mensajes con el solicitante y cierres.
  </Property>
</Properties>

---

## Listar solicitudes {{ tag: 'GET', label: '/api/rights-requests' }}

<Row>
  <Col>

    Requiere `rights_requests.read`. Devuelve los expedientes completos (misma forma que el detalle), paginados por `limit`/`offset` o `cursor`.

    ### Parámetros opcionales

    <Properties>
      <Property name="scope" type="string">
        `abiertas`, `vencen-pronto` (vencen en 7 días), `vencidas` (abiertas y
        fuera de plazo), `fuera-de-plazo` (cerradas después del plazo) o
        `cerradas`.
      </Property>
      <Property name="requestType" type="string">
        Filtra por tipo de derecho.
      </Property>
      <Property name="status" type="string">
        Filtra por estado exacto.
      </Property>
      <Property name="q" type="string">
        Busca por código de seguimiento, resumen o id.
      </Property>
      <Property name="sort" type="string">
        `plazo`, `enviada`, `estado` o `tipo`; `dir` = `asc` | `desc`.
      </Property>
      <Property name="limit" type="integer">
        Por defecto 100, máximo 250. `cursor` reemplaza a `offset` si se
        envían ambos.
      </Property>
    </Properties>

  </Col>
  <Col sticky>

    <CodeGroup title="Solicitud" tag="GET" label="/api/rights-requests">

    ```bash {{ title: 'cURL' }}
    curl -G "https://app.edugoverna.com/api/rights-requests" \
      -H "x-api-key: {tu_api_key}" \
      -d scope=vencen-pronto \
      -d sort=plazo -d dir=asc
    ```

    ```js
    const response = await fetch(
      'https://app.edugoverna.com/api/rights-requests?scope=vencen-pronto&sort=plazo&dir=asc',
      { headers: { 'x-api-key': process.env.EDUGOVERNA_API_KEY } },
    )

    const { rightsRequests, meta } = await response.json()
    ```

    </CodeGroup>

    ```json {{ title: 'Respuesta' }}
    {
      "rightsRequests": [
        {
          "id": "7c2e…",
          "requestType": "access",
          "requestChannel": "portal",
          "status": "in_progress",
          "summary": "Acceso a antecedentes académicos",
          "requesterEmail": "camila.requester@example.cl",
          "submittedAt": "2026-08-11T14:02:00.000Z",
          "dueAt": "2026-09-01T23:59:59.999Z",
          "extendedDueAt": null,
          "closedAt": null,
          "portalTrackingCode": "ARCO-…",
          "subjects": [
            {
              "subjectId": "3f6f…",
              "relationType": "target",
              "subjectSummary": {
                "id": "3f6f…",
                "subjectType": "student",
                "referenceCode": "EST-2026-0412",
                "displayName": "Martina Rojas"
              }
            }
          ],
          "actions": [],
          "exports": [],
          "documents": [],
          "messages": [],
          "closures": []
          // …
        }
      ],
      "meta": {
        "total": 9,
        "totalMatchedCount": 9,
        "limit": 100,
        "offset": 0,
        "nextCursor": null
      }
    }
    ```

  </Col>
</Row>

---

## Contadores por vencimiento {{ tag: 'GET', label: '/api/rights-requests/counts' }}

<Row>
  <Col>

    Requiere `rights_requests.read`. Devuelve los mismos cinco alcances del listado más el total, listos para un tablero de plazos. Acepta un único filtro opcional, `requestType`. Nota: dos claves llevan guion.

  </Col>
  <Col sticky>

    <CodeGroup title="Solicitud" tag="GET" label="/api/rights-requests/counts">

    ```bash {{ title: 'cURL' }}
    curl "https://app.edugoverna.com/api/rights-requests/counts" \
      -H "x-api-key: {tu_api_key}"
    ```

    ```js
    const counts = await fetch(
      'https://app.edugoverna.com/api/rights-requests/counts',
      { headers: { 'x-api-key': process.env.EDUGOVERNA_API_KEY } },
    ).then((r) => r.json())
    ```

    </CodeGroup>

    ```json {{ title: 'Respuesta' }}
    {
      "total": 9,
      "abiertas": 5,
      "vencen-pronto": 1,
      "vencidas": 2,
      "fuera-de-plazo": 2,
      "cerradas": 4
    }
    ```

  </Col>
</Row>

---

## Crear una solicitud {{ tag: 'POST', label: '/api/rights-requests' }}

<Row>
  <Col>

    Requiere `rights_requests.write`. El servidor calcula `dueAt` según el SLA configurado y acuña el `portalTrackingCode`. Responde `201` con el expediente completo.

    ### Atributos requeridos

    <Properties>
      <Property name="requestType" type="string">
        `access`, `rectification`, `suppression`, `opposition`, `portability`
        o `blocking`.
      </Property>
      <Property name="subjectIds" type="string[]">
        Titulares alcanzados (1 a 200). Un id que no exista en el padrón
        responde `404 RIGHTS_REQUEST_SUBJECT_NOT_FOUND`.
      </Property>
    </Properties>

    ### Atributos opcionales

    <Properties>
      <Property name="requesterSubjectId" type="string">
        Titular que solicita (p. ej. el apoderado).
      </Property>
      <Property name="requesterEmail" type="string">
        Correo del solicitante para las notificaciones.
      </Property>
      <Property name="requestChannel" type="string">
        Canal de entrada; por defecto `portal`.
      </Property>
      <Property name="summary" type="string">
        Resumen del caso (hasta 2000 caracteres).
      </Property>
      <Property name="legalBasis" type="string">
        Base legal invocada.
      </Property>
    </Properties>

  </Col>
  <Col sticky>

    <CodeGroup title="Solicitud" tag="POST" label="/api/rights-requests">

    ```bash {{ title: 'cURL' }}
    curl -X POST "https://app.edugoverna.com/api/rights-requests" \
      -H "x-api-key: {tu_api_key}" \
      -H "Content-Type: application/json" \
      -d '{
        "requestType": "access",
        "subjectIds": ["3f6f0a2e-…"],
        "requesterEmail": "camila.requester@example.cl",
        "summary": "Acceso a antecedentes académicos"
      }'
    ```

    ```js
    const rightsRequest = await fetch(
      'https://app.edugoverna.com/api/rights-requests',
      {
        method: 'POST',
        headers: {
          'x-api-key': process.env.EDUGOVERNA_API_KEY,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          requestType: 'access',
          subjectIds: ['3f6f0a2e-…'],
          requesterEmail: 'camila.requester@example.cl',
          summary: 'Acceso a antecedentes académicos',
        }),
      },
    ).then((r) => r.json())
    ```

    </CodeGroup>

    ```json {{ title: 'Respuesta · 201' }}
    {
      "id": "7c2e…",
      "requestType": "access",
      "status": "submitted",
      "requestChannel": "portal",
      "dueAt": "2026-09-15T23:59:59.999Z",
      "extendedDueAt": null,
      "portalTrackingCode": "ARCO-…",
      "subjects": [{ "subjectId": "3f6f0a2e-…", "relationType": "target" }]
      // …
    }
    ```

  </Col>
</Row>

---

## Extender el plazo {{ tag: 'POST', label: '/api/rights-requests/:id/extend' }}

<Row>
  <Col>

    Requiere `rights_requests.write`. La ley admite **una sola extensión**, de hasta 15 días hábiles sobre el `dueAt` vigente; un segundo intento responde `409 RIGHTS_REQUEST_ALREADY_EXTENDED`. La razón queda como mensaje `deadline_extension` en el expediente.

    ### Atributos requeridos

    <Properties>
      <Property name="extendedDueAt" type="timestamp">
        Nuevo plazo (ISO 8601). Debe caer en un día calendario de Santiago
        posterior al plazo vigente.
      </Property>
      <Property name="reason" type="string">
        Justificación (2 a 2000 caracteres).
      </Property>
    </Properties>

  </Col>
  <Col sticky>

    <CodeGroup title="Solicitud" tag="POST" label="/api/rights-requests/:id/extend">

    ```bash {{ title: 'cURL' }}
    curl -X POST "https://app.edugoverna.com/api/rights-requests/7c2e…/extend" \
      -H "x-api-key: {tu_api_key}" \
      -H "Content-Type: application/json" \
      -d '{
        "extendedDueAt": "2026-09-30T23:59:59.999Z",
        "reason": "Caso complejo con revisión de antecedentes externos."
      }'
    ```

    ```js
    await fetch(
      'https://app.edugoverna.com/api/rights-requests/7c2e…/extend',
      {
        method: 'POST',
        headers: {
          'x-api-key': process.env.EDUGOVERNA_API_KEY,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          extendedDueAt: '2026-09-30T23:59:59.999Z',
          reason: 'Caso complejo con revisión de antecedentes externos.',
        }),
      },
    )
    ```

    </CodeGroup>

  </Col>
</Row>

---

## Los demás endpoints del caso

| Método y ruta                                            | Permiso                 | Qué hace                                           |
| -------------------------------------------------------- | ----------------------- | -------------------------------------------------- |
| `GET /rights-requests/:id`                               | `rights_requests.read`  | Expediente completo (mismo cuerpo que el listado). |
| `POST /rights-requests/:id/subjects`                     | `rights_requests.write` | Agrega un titular al caso.                         |
| `DELETE /rights-requests/:id/subjects/:subjectId`        | `rights_requests.write` | Retira un titular del caso.                        |
| `PATCH /rights-requests/:id/requester-email`             | `rights_requests.write` | Corrige el correo del solicitante.                 |
| `POST /rights-requests/:id/messages`                     | `rights_requests.write` | Escribe un mensaje al solicitante.                 |
| `POST /rights-requests/:id/rectify`                      | `rights_requests.write` | Ejecuta la rectificación de identidad del titular. |
| `POST /rights-requests/:id/restrictions/complete`        | `rights_requests.write` | Completa un bloqueo/restricción de tratamiento.    |
| `POST /rights-requests/:id/restrictions/lift-opposition` | `rights_requests.write` | Levanta una oposición.                             |
| `GET /rights-requests/:id/action-fulfillment`            | `rights_requests.read`  | Estado de los conectores de acción.                |
| `POST /rights-requests/:id/actions/trigger`              | `rights_requests.write` | Dispara un conector de acción.                     |
| `POST /rights-requests/:id/deny`                         | `rights_requests.write` | Deniega el caso con razón.                         |
| `POST /rights-requests/:id/final-response/preview`       | `rights_requests.write` | Previsualiza la respuesta final.                   |
| `POST /rights-requests/:id/close`                        | `rights_requests.write` | Cierra el caso.                                    |
| `POST /rights-requests/:id/notify`                       | `rights_requests.write` | Notifica el cierre al solicitante.                 |

<Note>
  **Sólo disponible con sesión de la consola:** la generación de exportaciones
  (`POST /rights-requests/:id/exports`), la anonimización (`POST
  /rights-requests/:id/anonymize`), la subida de documentos y todas las
  descargas de artefactos (exportaciones, documentos, certificados de cierre).
  Una API key puede leer el expediente y ver que la exportación existe, pero los
  bytes del paquete de datos personales sólo se entregan a una persona con
  sesión.
</Note>

---

## Portal ARCO {{ tag: 'GET', label: '/api/arco/portal/current' }}

<Row>
  <Col>

    La configuración del portal público de derechos del colegio. Lectura con `rights_requests.read`; escritura con `PUT` y `rights_requests.write` (mismo cuerpo de respuesta). El portal define el SLA por defecto y por tipo (`defaultSlaDays`, `requestTypeConfig.<tipo>.slaDays`, 1 a 20 días hábiles), los documentos exigidos al solicitante, los formatos de exportación y los conectores de acción — cuyo `secret` es de sólo escritura: la lectura devuelve únicamente `hasSecret`.

  </Col>
  <Col sticky>

    <CodeGroup title="Solicitud" tag="GET" label="/api/arco/portal/current">

    ```bash {{ title: 'cURL' }}
    curl "https://app.edugoverna.com/api/arco/portal/current" \
      -H "x-api-key: {tu_api_key}"
    ```

    ```js
    const { organization, arcoPortal } = await fetch(
      'https://app.edugoverna.com/api/arco/portal/current',
      { headers: { 'x-api-key': process.env.EDUGOVERNA_API_KEY } },
    ).then((r) => r.json())
    ```

    </CodeGroup>

    ```json {{ title: 'Respuesta (recortada)' }}
    {
      "organization": { "id": "org_…", "name": "Colegio Andes", "slug": "colegio-andes" },
      "arcoPortal": {
        "ownerType": "school",
        "enabled": true,
        "arcopEnabled": true,
        "slug": "colegio-andes",
        "ownerDisplayName": "Colegio Andes",
        "dpoName": "Patricia Núñez",
        "dpoEmail": "dpo@colegioandes.cl",
        "defaultSlaDays": 15,
        "supportedExportFormats": ["json", "pdf"],
        "requestTypeConfig": {
          "access": {
            "enabled": true,
            "slaDays": 15,
            "requiredDocuments": [
              { "kind": "identity", "label": "Documento de identidad", "required": true }
            ]
          }
          // … los seis tipos siempre presentes
        },
        "actionConnectors": {
          "export_access_package": {
            "mode": "internal",
            "endpointUrl": null,
            "hasSecret": false
          }
        }
      }
    }
    ```

  </Col>
</Row>

---

## Orígenes de redirección {{ tag: 'GET', label: '/api/organization/redirect-origins' }}

<Row>
  <Col>

    La lista de orígenes autorizados para redirigir a un titular de vuelta a un sitio del colegio después de completar un flujo público (consentimiento, portal). La lectura acepta `consents.read` **o** `schools.read`; crear y borrar exigen `schools.write`.

    `POST` es idempotente: reenviar un origen ya registrado devuelve la fila existente. El origen se normaliza (esquema + host, sin ruta): registrar `https://Colegio.example/gracias` guarda `https://colegio.example`.

  </Col>
  <Col sticky>

    <CodeGroup title="Solicitud" tag="POST" label="/api/organization/redirect-origins">

    ```bash {{ title: 'cURL' }}
    curl -X POST "https://app.edugoverna.com/api/organization/redirect-origins" \
      -H "x-api-key: {tu_api_key}" \
      -H "Content-Type: application/json" \
      -d '{ "origin": "https://www.colegioandes.cl", "allowSubpaths": true }'
    ```

    ```js
    const origin = await fetch(
      'https://app.edugoverna.com/api/organization/redirect-origins',
      {
        method: 'POST',
        headers: {
          'x-api-key': process.env.EDUGOVERNA_API_KEY,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          origin: 'https://www.colegioandes.cl',
          allowSubpaths: true,
        }),
      },
    ).then((r) => r.json())
    ```

    </CodeGroup>

    ```json {{ title: 'Respuesta · 201' }}
    {
      "id": "9a1b…",
      "organizationId": "org_…",
      "origin": "https://www.colegioandes.cl",
      "allowSubpaths": true,
      "createdByUserId": null,
      "createdAt": "2026-08-25T12:00:00.000Z"
    }
    ```

  </Col>
</Row>

Estos orígenes también gobiernan los redirects de campañas de consentimiento; el detalle de esa interacción está en [Consentimientos](/api-organizacion/consentimientos).
