Conexiones y partners

Una conexión es la relación formal entre tu establecimiento y un partner tecnológico: quién es, con qué propósito trata datos, a qué recursos puede llegar y bajo qué contrato. Esta página cubre la API con que se administra ese grafo — cuentas de partner, solicitudes de conexión, scopes, contratos DPA y orígenes de redirección — además del endpoint de diagnóstico para depurar rechazos 403.

El modelo: conexión, scopes y DPA

Tres piezas gobiernan el acceso de un partner:

  • La conexión (organization_partner_connection) une un colegio con una cuenta de partner. Registra el propósito (purposeSummary), la base legal, quién la autorizó y su estado (active o revoked; cualquier estado distinto de active cierra el paso al partner). Hay a lo más una conexión por par colegio–partner.
  • Los scopes (connection_scopes) abren grupos de rutas de la API de partner por espacio de recursos (resourceNamespace, por ejemplo subjects o consents) y tipo (read o write). Sin el scope correspondiente, el grupo de rutas queda cerrado aunque la credencial tenga el permiso.
  • El contrato DPA (Art. 15 bis) es una compuerta dura: sin un DPA vigente — estado active y dentro de su rango de vigencia — toda llamada del partner es rechazada con PARTNER_DPA_NOT_ACTIVE. Las conexiones de tipo external_registry no llevan DPA; para ellas la compuerta exige la declaración jurada firmada del registrador.

Cada llamada del partner atraviesa, en orden, cuatro compuertas: credencial válida y no vencida → conexión activa con ese colegio → cuenta del partner activa → DPA vigente (o declaración jurada, según el tipo). Recién entonces se evalúan scopes y permisos de la ruta. Puedes reproducir esa evaluación con el diagnóstico de acceso.

Las credenciales de API del partner y los endpoints de webhook asociados a una conexión se documentan aparte.


GET/api/integrations/partners

Listar partners

Devuelve el estado completo del grafo para tu organización en una sola respuesta:

  • Nombre
    partnerConnections
    Tipo
    array
    Descripción

    Las conexiones existentes, cada una con su cuenta de partner (partner), sus scopes y el resumen del último DPA (dpa, con status, vigencia y si tiene documento adjunto).

  • Nombre
    partnerConnectionRequests
    Tipo
    array
    Descripción

    Las solicitudes de conexión pendientes o decididas que involucran a tu organización.

  • Nombre
    orphanPartnerAccounts
    Tipo
    array
    Descripción

    Cuentas de partner creadas por tu organización que aún no tienen conexión, listadas para que puedas limpiarlas.

Solicitud

GET
/api/integrations/partners
curl https://app.edugoverna.com/api/integrations/partners \
  -H "x-api-key: {api_key}"

Respuesta

{
  "partnerConnections": [
    {
      "id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
      "partnerAccountId": "16fd2706-8baf-433b-82eb-8c7fada847da",
      "connectionType": "api",
      "status": "active",
      "purposeSummary": "Sincronización de matrícula y consentimientos",
      "legalBasis": "contrato_encargo",
      "partner": {
        "id": "16fd2706-8baf-433b-82eb-8c7fada847da",
        "name": "Plataforma Escolar SpA",
        "slug": "plataforma-escolar"
      },
      "scopes": [
        { "resourceNamespace": "subjects", "scopeType": "read" },
        { "resourceNamespace": "consents", "scopeType": "write" }
      ],
      "dpa": {
        "id": "a3bb189e-8bf9-3888-9912-ace4e6543002",
        "versionNumber": 2,
        "status": "active",
        "effectiveFrom": "2026-08-12T00:00:00.000Z",
        "effectiveTo": null,
        "hasDocument": true
      }
    }
  ],
  "partnerConnectionRequests": [],
  "orphanPartnerAccounts": []
}

GET/api/integrations/partners/:organizationPartnerConnectionId

Detalle de una conexión

Devuelve una conexión con todo lo que cuelga de ella: la cuenta de partner, sus scopes (con id, para poder quitarlos), el resumen del último DPA, los redirectOrigins aprobados y las credentials del partner en su forma segura (con prefix, nunca la llave). Una conexión de otra organización responde 404 con ORGANIZATION_PARTNER_CONNECTION_NOT_FOUND.

Solicitud

GET
/api/integrations/partners/:id
curl https://app.edugoverna.com/api/integrations/partners/d290f1ee-6c54-4b01-90e6-d701748f0851 \
  -H "x-api-key: {api_key}"

Respuesta

{
  "partnerConnection": {
    "id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
    "status": "active",
    "partner": { "name": "Plataforma Escolar SpA" },
    "scopes": [
      {
        "id": "0b8e4c2a-5d1f-4a6b-8c3e-7f9d2a1b6c4e",
        "resourceNamespace": "subjects",
        "scopeType": "read"
      }
    ],
    "dpa": { "status": "active", "hasDocument": true },
    "redirectOrigins": [
      {
        "id": "b1946ac9-2d5a-4a3c-8f2e-0d9c7e6f5a4b",
        "origin": "https://app.plataformaescolar.cl",
        "allowSubpaths": true
      }
    ],
    "credentials": [
      {
        "id": "9e2a41d7-6c3b-4f0e-8a17-b5d4c2e8f901",
        "label": "Producción",
        "prefix": "9e2a41d7-6c3",
        "status": "active"
      }
    ]
  }
}

POST/api/integrations/partners

Crear una cuenta de partner

Registra una cuenta de partner nueva (por ejemplo, un proveedor que aún no existe en la plataforma). La cuenta queda visible en tu listado como huérfana hasta que la conectes.

Atributos obligatorios

  • Nombre
    name
    Tipo
    string
    Descripción

    Nombre del partner (2–160 caracteres).

Atributos opcionales

  • Nombre
    slug
    Tipo
    string
    Descripción

    Identificador legible, único en la plataforma (2–160 caracteres).

  • Nombre
    partnerType
    Tipo
    string
    Descripción

    Tipo de partner. Por defecto software_vendor.

  • Nombre
    websiteUrl
    Tipo
    string
    Descripción

    Sitio web del partner.

  • Nombre
    contactEmail
    Tipo
    string
    Descripción

    Correo de contacto general.

  • Nombre
    contactPhone
    Tipo
    string
    Descripción

    Teléfono de contacto.

  • Nombre
    privacyContactEmail
    Tipo
    string
    Descripción

    Correo del contacto de privacidad del partner.

  • Nombre
    status
    Tipo
    string
    Descripción

    Estado inicial. Por defecto active.

  • Nombre
    metadata
    Tipo
    object
    Descripción

    Metadatos libres.

Para eliminar una cuenta creada por tu organización que no tiene conexión, usa DELETE /api/integrations/partner-accounts/:partnerAccountId; si la cuenta ya tiene conexiones, solicitudes o credenciales, responde 409 con PARTNER_ACCOUNT_IN_USE.

Solicitud

POST
/api/integrations/partners
curl https://app.edugoverna.com/api/integrations/partners \
  -H "x-api-key: {api_key}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Plataforma Escolar SpA",
    "contactEmail": "soporte@plataformaescolar.cl",
    "privacyContactEmail": "privacidad@plataformaescolar.cl"
  }'

Respuesta (201)

{
  "id": "16fd2706-8baf-433b-82eb-8c7fada847da",
  "name": "Plataforma Escolar SpA",
  "slug": "plataforma-escolar-spa",
  "partnerType": "software_vendor",
  "status": "active"
  // ... resto de la cuenta
}

POST/api/integrations/connection-requests

Solicitudes de conexión

Una solicitud de conexión es la invitación formal entre las partes: el colegio invita a un partner (school_invites_partner) o el partner pide acceso a un colegio (partner_requests_school). Las pendientes se listan con GET /api/integrations/connection-requests y la contraparte las decide con POST /api/integrations/connection-requests/:id/decide enviando { "decision": "accepted" } o { "decision": "rejected" }. Al aceptarse, la plataforma crea la conexión con los scopes solicitados; si la solicitud no traía scopes, aplica un conjunto por defecto (subjects read, consents read y write, rights_requests read).

Atributos opcionales

  • Nombre
    direction
    Tipo
    string
    Descripción

    school_invites_partner (por defecto) o partner_requests_school.

  • Nombre
    targetPartnerAccountId
    Tipo
    string
    Descripción

    UUID de la cuenta de partner invitada.

  • Nombre
    targetOrganizationId
    Tipo
    string
    Descripción

    UUID de la organización objetivo, cuando quien solicita es el partner.

  • Nombre
    targetEmail
    Tipo
    string
    Descripción

    Correo del invitado cuando aún no tiene cuenta en la plataforma; la invitación le llega por correo.

  • Nombre
    requestedScopes
    Tipo
    array
    Descripción

    Hasta 50 scopes solicitados, cada uno con resourceNamespace (2–80 caracteres), scopeType y conditions opcionales.

  • Nombre
    message
    Tipo
    string
    Descripción

    Mensaje para la contraparte (hasta 2000 caracteres).

  • Nombre
    expiresAt
    Tipo
    string (fecha)
    Descripción

    Vencimiento de la invitación.

Solicitud

POST
/api/integrations/connection-requests
curl https://app.edugoverna.com/api/integrations/connection-requests \
  -H "x-api-key: {api_key}" \
  -H "Content-Type: application/json" \
  -d '{
    "direction": "school_invites_partner",
    "targetPartnerAccountId": "16fd2706-8baf-433b-82eb-8c7fada847da",
    "requestedScopes": [
      { "resourceNamespace": "subjects", "scopeType": "read" },
      { "resourceNamespace": "consents", "scopeType": "write" }
    ],
    "message": "Integración de consentimientos 2026"
  }'

Decidir (POST …/:id/decide)

{
  "decision": "accepted"
}

POST/api/integrations/connections

Crear o reactivar una conexión

Crea la conexión directamente (sin pasar por una solicitud), o actualiza y reactiva la existente: hay a lo más una conexión por par colegio–partner, así que un segundo POST con el mismo partnerAccountId actualiza esa fila y limpia una revocación previa.

Atributos obligatorios

  • Nombre
    partnerAccountId
    Tipo
    string
    Descripción

    UUID de la cuenta de partner.

Atributos opcionales

  • Nombre
    connectionType
    Tipo
    string
    Descripción

    Tipo de conexión. Por defecto api.

  • Nombre
    status
    Tipo
    string
    Descripción

    Estado inicial. Por defecto active.

  • Nombre
    purposeSummary
    Tipo
    string
    Descripción

    Propósito del tratamiento encargado (hasta 1000 caracteres).

  • Nombre
    legalBasis
    Tipo
    string
    Descripción

    Base legal registrada para la relación.

  • Nombre
    controllerEntityId
    Tipo
    string
    Descripción

    Entidad responsable bajo la cual se registra la conexión; si se omite, se usa la entidad principal de la organización.

  • Nombre
    authorizedByUserId
    Tipo
    string
    Descripción

    Usuario que autorizó la conexión.

  • Nombre
    approvedAt
    Tipo
    string (fecha)
    Descripción

    Fecha de aprobación. Por defecto, el momento de la llamada.

  • Nombre
    returnOrDeletionRequired
    Tipo
    boolean
    Descripción

    Si al término de la relación se exige devolución o supresión de los datos. Por defecto true.

Solicitud

POST
/api/integrations/connections
curl https://app.edugoverna.com/api/integrations/connections \
  -H "x-api-key: {api_key}" \
  -H "Content-Type: application/json" \
  -d '{
    "partnerAccountId": "16fd2706-8baf-433b-82eb-8c7fada847da",
    "purposeSummary": "Sincronización de matrícula y consentimientos",
    "legalBasis": "contrato_encargo"
  }'

Respuesta (201)

{
  "id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "partnerAccountId": "16fd2706-8baf-433b-82eb-8c7fada847da",
  "connectionType": "api",
  "status": "active",
  "returnOrDeletionRequired": true
  // ... resto de la conexión
}

POST/api/integrations/connections/:id/scopes

Scopes de una conexión

Agrega un scope a la conexión. Cada scope abre un grupo de rutas de la API de partner; quitarlo lo cierra en la llamada siguiente, sin caché de por medio.

Atributos

  • Nombre
    resourceNamespace
    Tipo
    string
    Descripción

    Espacio de recursos que abre el scope (2–80 caracteres), por ejemplo subjects o consents.

  • Nombre
    scopeType
    Tipo
    string
    Descripción

    read o write. Por defecto read.

  • Nombre
    conditions
    Tipo
    object
    Descripción

    Condiciones adicionales del scope, opcionales.

Para quitar un scope: DELETE /api/integrations/connections/:id/scopes/:connectionScopeId. El id de cada scope viene en el detalle de la conexión; un id de otra conexión u otra organización responde 404 con CONNECTION_SCOPE_NOT_FOUND. La respuesta de la eliminación es { "ok": true }.

Solicitud

POST
/api/integrations/connections/:id/scopes
curl https://app.edugoverna.com/api/integrations/connections/d290f1ee-6c54-4b01-90e6-d701748f0851/scopes \
  -H "x-api-key: {api_key}" \
  -H "Content-Type: application/json" \
  -d '{ "resourceNamespace": "consents", "scopeType": "write" }'

Respuesta (201)

{
  "id": "0b8e4c2a-5d1f-4a6b-8c3e-7f9d2a1b6c4e",
  "organizationPartnerConnectionId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "resourceNamespace": "consents",
  "scopeType": "write",
  "conditions": null
}

POST/api/integrations/connections/:id/revoke

Revocar una conexión

Marca la conexión como revoked y registra cuándo y quién la revocó. La revocación arrastra todo lo que cuelga de la relación: las comparticiones de padrón otorgadas por esta conexión se retiran y sus solicitudes de consentimiento pendientes quedan invalidadas (ver Campañas compartidas). Desde ese momento, toda llamada del partner a tu organización es rechazada con PARTNER_CONNECTION_NOT_ACTIVE.

Un nuevo POST /api/integrations/connections con el mismo partner reactiva la relación.

Solicitud

POST
/api/integrations/connections/:id/revoke
curl -X POST https://app.edugoverna.com/api/integrations/connections/d290f1ee-6c54-4b01-90e6-d701748f0851/revoke \
  -H "x-api-key: {api_key}"

Respuesta

{
  "id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "status": "revoked",
  "revokedAt": "2026-08-25T14:03:22.511Z"
  // ... resto de la conexión
}

POST/api/integrations/connections/:id/dpa-contracts

Registrar un contrato DPA

Registra una nueva versión del contrato de encargo (Art. 15 bis) del partner. El endpoint acepta dos formatos:

Multipart — adjunta el documento firmado en el campo file (máximo 15 MB; DPA_DOCUMENT_TOO_LARGE si lo excede) y, opcionalmente, un campo status. El documento se almacena como evidencia y la nueva versión del contrato lo referencia.

JSON — registra la versión con o sin documento externo:

  • Nombre
    status
    Tipo
    string
    Descripción

    draft o active. Por defecto active. Solo un contrato active dentro de su vigencia abre la compuerta de la API de partner.

  • Nombre
    versionNumber
    Tipo
    integer
    Descripción

    Número de versión; si se omite, continúa la numeración existente.

  • Nombre
    executedAt
    Tipo
    string (fecha)
    Descripción

    Fecha de firma. Por defecto, el momento de la llamada.

  • Nombre
    effectiveFrom
    Tipo
    string (fecha)
    Descripción

    Inicio de vigencia. Por defecto, el momento de la llamada.

  • Nombre
    effectiveTo
    Tipo
    string (fecha)
    Descripción

    Fin de vigencia; debe ser posterior a effectiveFrom.

  • Nombre
    documentUrl
    Tipo
    string
    Descripción

    Referencia externa al documento (URL), como alternativa al adjunto.

  • Nombre
    returnOrDeletionClause
    Tipo
    string
    Descripción

    Texto de la cláusula de devolución o supresión (hasta 2000 caracteres).

  • Nombre
    artifactId / artifact
    Tipo
    string / object
    Descripción

    Referencia a un artefacto de evidencia ya almacenado, o uno inline. Excluyentes entre sí.

Una versión nueva que no re-adjunta documento arrastra la referencia al documento de la versión anterior, de modo que el DPA vigente siga apuntando al último documento cargado.

El documento del último contrato registrado se descarga con GET /api/integrations/connections/:id/dpa-document — la respuesta es el archivo mismo, con su content-type original y la cabecera x-artifact-checksum. Si la conexión no tiene documento cargado, responde 404 con DPA_DOCUMENT_NOT_FOUND.

Solicitud

POST
/api/integrations/connections/:id/dpa-contracts
curl https://app.edugoverna.com/api/integrations/connections/d290f1ee-6c54-4b01-90e6-d701748f0851/dpa-contracts \
  -H "x-api-key: {api_key}" \
  -F "file=@dpa-firmado.pdf" \
  -F "status=active"

Respuesta (201)

{
  "id": "a3bb189e-8bf9-3888-9912-ace4e6543002",
  "versionNumber": 2,
  "status": "active",
  "executedAt": "2026-08-25T14:03:22.511Z",
  "effectiveFrom": "2026-08-25T14:03:22.511Z",
  "effectiveTo": null
  // ... resto del contrato
}

POST/api/integrations/connections/:id/redirect-origins

Orígenes de redirección

Cuando el partner lanza flujos que terminan redirigiendo al titular de vuelta a su propia aplicación (por ejemplo, al cerrar un portal de consentimiento de una campaña), el destino debe estar en esta lista de orígenes aprobados por el colegio. Un origen fuera de la lista es rechazado.

Atributos

  • Nombre
    origin
    Tipo
    string
    Descripción

    El origen a aprobar, por ejemplo https://app.plataformaescolar.cl. Se normaliza antes de guardarse; un valor que no es un origen válido responde con REDIRECT_ORIGIN_INVALID.

  • Nombre
    allowSubpaths
    Tipo
    boolean
    Descripción

    Si se permiten rutas bajo el origen. Por defecto true.

La operación es idempotente: volver a agregar un origen existente devuelve la fila que ya estaba. Los orígenes se listan con GET /api/integrations/connections/:id/redirect-origins y se quitan con DELETE /api/integrations/connections/:id/redirect-origins/:redirectOriginId.

Solicitud

POST
/api/integrations/connections/:id/redirect-origins
curl https://app.edugoverna.com/api/integrations/connections/d290f1ee-6c54-4b01-90e6-d701748f0851/redirect-origins \
  -H "x-api-key: {api_key}" \
  -H "Content-Type: application/json" \
  -d '{ "origin": "https://app.plataformaescolar.cl" }'

Respuesta (201)

{
  "id": "b1946ac9-2d5a-4a3c-8f2e-0d9c7e6f5a4b",
  "organizationPartnerConnectionId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "origin": "https://app.plataformaescolar.cl",
  "allowSubpaths": true
}

POST/api/integrations/authorize

Diagnóstico de acceso

Resuelve una llave de partner contra tu organización pasando por las mismas cuatro compuertas que una llamada real de la API de partner. Es la herramienta para depurar un 403: en lugar de adivinar cuál compuerta rechazó, la respuesta te lo dice. Aunque el método es POST, la ruta es de diagnóstico y exige integrations.read.

Atributos

  • Nombre
    providedKey
    Tipo
    string
    Descripción

    La llave del partner en texto plano (mínimo 10 caracteres).

Si todas las compuertas pasan, la respuesta es el contexto de acceso completo: credencial, cuenta, conexión, scopes, permissions y el resumen del dpaContract vigente. Si alguna falla, el error identifica la compuerta:

  • PARTNER_CREDENTIAL_INVALID (401) — la llave no existe o está revocada.
  • PARTNER_CREDENTIAL_EXPIRED (401) — la credencial venció.
  • PARTNER_CONNECTION_NOT_ACTIVE (403) — no hay conexión activa entre el partner y tu organización.
  • PARTNER_WORKSPACE_NOT_ACTIVE (403) — la cuenta del partner está suspendida o pendiente de activación.
  • PARTNER_DPA_NOT_ACTIVE (403) — no hay DPA vigente (o falta la declaración jurada, en conexiones de registro externo).

El formato general de los errores está en Errores.

Solicitud

POST
/api/integrations/authorize
curl https://app.edugoverna.com/api/integrations/authorize \
  -H "x-api-key: {api_key}" \
  -H "Content-Type: application/json" \
  -d '{ "providedKey": "9e2a41d7-6c3b-4f0e-8a17-b5d4c2e8f901.f47ac10b58cc4372a5670e02b2c3d479" }'

Respuesta

{
  "partnerCredentialId": "0b8e4c2a-5d1f-4a6b-8c3e-7f9d2a1b6c4e",
  "partnerAccountId": "16fd2706-8baf-433b-82eb-8c7fada847da",
  "organizationPartnerConnectionId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "scopes": [
    {
      "resourceNamespace": "subjects",
      "scopeType": "read",
      "conditions": null
    }
  ],
  "permissions": ["partner.consents.write", "partner.subjects.read"],
  "dpaContract": {
    "id": "a3bb189e-8bf9-3888-9912-ace4e6543002",
    "versionNumber": 2,
    "status": "active",
    "executedAt": "2026-08-12T00:00:00.000Z",
    "effectiveFrom": "2026-08-12T00:00:00.000Z",
    "effectiveTo": null
  }
}

¿Te sirvió esta página?