Campañas sobre registros compartidos

Un colegio puede compartir contigo cursos completos de su padrón — un registry share — para que tu plataforma solicite consentimientos a esas familias sin que el colegio tenga que operar la campaña. En esta guía descubrirás los shares disponibles, crearás una campaña compartida, emitirás sobres uno a uno y mantendrás la audiencia al día cuando el colegio actualice su padrón.

El flujo completo:

  1. El colegio comparte uno o más cursos con tu cuenta de socio (concede el share).
  2. Tu plataforma lista los shares y, si lo necesita, sus integrantes → GET /shares, GET /shares/:shareId/subjects.
  3. Creas y publicas la campaña sobre esos shares → POST /shared-campaigns, respuesta 202.
  4. En modo bulk Edugoverna despacha el roster completo; en modo per_subject emites cada sobre cuando tu producto lo decide → POST .../envelopes.
  5. Cada familia recibe su entrega y decide en el portal → tu organización recibe el webhook consent.decision.recorded con la proyección shared_partner.
  6. Cuando el colegio matricula estudiantes nuevos, sincronizas la audiencia → POST .../sync-audience.

Qué es un registro compartido

Un share es una concesión explícita del colegio: «este curso de mi padrón es visible para este socio, para este fin». Lo que ves de cada integrante es una proyección acotada — nombre para mostrar, tramo etario, RUT enmascarado y presencia de canales de contacto, nunca sus valores. Los datos siguen viviendo en la organización del colegio; la campaña, en cambio, vive en la tuya. El detalle conceptual está en Campañas compartidas.

1. Descubre los shares y sus integrantes

GET
/shares
curl https://app.edugoverna.com/api/partner/v1/organizations/{colegioOrgId}/shares \
  -H "Authorization: Bearer {keyId}.{secret}"

Respuesta

{
  "shares": [
    {
      "id": "b1f6a3d2-4c1e-4e29-9d5b-8a0f7c3e2d11",
      "groupType": "segment",
      "groupKind": "course",
      "groupName": "3° Básico A 2026",
      "memberCount": 32,
      "grantSource": "school_dashboard",
      "createdAt": "2026-03-04T12:00:00.000Z"
    }
  ]
}

Los integrantes de un share se listan con paginación por offset y limit:

GET
/shares/:shareId/subjects
curl -G https://app.edugoverna.com/api/partner/v1/organizations/{colegioOrgId}/shares/{shareId}/subjects \
  -H "Authorization: Bearer {keyId}.{secret}" \
  -d offset=0 \
  -d limit=50

Respuesta

{
  "share": {
    "id": "b1f6a3d2-4c1e-4e29-9d5b-8a0f7c3e2d11",
    "groupType": "segment",
    "groupKind": "course",
    "groupName": "3° Básico A 2026",
    "memberCount": 32
  },
  "subjects": [
    {
      "subjectId": "8f3b7f0a-2f9d-4d4e-a1c3-77b2a0f1d942",
      "displayName": "Martina P.",
      "subjectType": "student",
      "currentAgeBand": "under_14",
      "maskedRut": "••.•••.634-5",
      "contacts": [{ "contactType": "email", "isPrimary": true }]
    }
  ],
  "meta": {
    "totalCount": 32,
    "offset": 0,
    "limit": 50,
    "missingContactCount": 3
  }
}

meta.missingContactCount te anticipa cuántos integrantes del share no tienen ningún canal registrado: son los candidatos a la puerta pública de completación (más abajo). Si el colegio habilitó la lectura ampliada, puedes pedirla explícitamente con ?disclosure=full; es un acto deliberado que queda auditado por sí mismo.

2. Crea la campaña compartida

Una sola llamada crea y publica la campaña en tu organización de trabajo. La actividad de tratamiento es tuya — el aviso que leerá la familia lo firmas tú como responsable de ese tratamiento — y se referencia por versión exacta.

POST
/shared-campaigns
curl https://app.edugoverna.com/api/partner/v1/organizations/{workspaceOrgId}/shared-campaigns \
  -H "Authorization: Bearer {keyId}.{secret}" \
  -H "Content-Type: application/json" \
  -d '{
    "processingActivityVersionId": "3f7e6c9d-8f21-4b83-bb1c-5e2d9a447f10",
    "name": "Fotografías y videos · Temporada 2026",
    "channels": ["email", "whatsapp"],
    "endsAt": "2026-10-31T03:00:00Z",
    "reminderDayOffsets": [3, 7],
    "defaultSuccessRedirectUrl": "https://plataforma.ejemplo.cl/gracias",
    "redirectMode": "bridge",
    "dispatchMode": "bulk",
    "publicCompletionEnabled": true,
    "targets": [
      { "shareId": "b1f6a3d2-4c1e-4e29-9d5b-8a0f7c3e2d11" },
      { "shareId": "e77c2b90-15aa-4d0f-b3c8-6f4a9d2e8b03" }
    ]
  }'

Los campos que definen el comportamiento:

  • targets — obligatorio, 1 a 50 shares. Cada entrada puede además acotar por RUT (ruts, hasta 500 por share y 1.000 por campaña): en ese modo RUT solo se contacta a quienes calcen dentro del grupo compartido, y ninguna respuesta revela cuáles calzaron.
  • dispatchMode"bulk" (por defecto) materializa y despacha el roster completo al publicar; "per_subject" materializa el roster pero espera a que tú emitas cada sobre.
  • channels["email"] por defecto; acepta email y whatsapp.
  • reminderDayOffsets — hasta 10 recordatorios, en días 1–60 desde el envío.
  • redirects — pares { rut, successRedirectUrl, declineRedirectUrl?, redirectMode? } (hasta 2.500) que fijan un destino por estudiante desde la creación. Los RUT que no calcen se ignoran en silencio; la respuesta solo repite cuántos pares enviaste.
  • publicCompletionEnabled — abre la puerta pública de completación para titulares del padrón sin canal registrado: verifican su RUT, registran un contacto propio y validan con OTP.
  • endsAt — cierre de la campaña; debe ser una fecha futura.

Respuesta · 202 Accepted

{
  "campaignId": "a4c8e2f6-7b31-4d95-8e0a-1f6c3b9d2e57",
  "submittedShareCount": 2,
  "publicCompletionEnabled": true,
  "publicCompletionUrl": "https://app.edugoverna.com/consents/campaigns/…",
  "status": "accepted"
}

El estado agregado vive en GET /shared-campaigns/:campaignId: estado, canales, outcomes (decisiones agregadas) y — salvo en modo RUT, donde se reporta decidedOnly: truerosterTotal y coverage.

3. Emite sobres y reenvíos

En modo per_subject, cada envío es un sobre: una llamada que despacha la solicitud de un titular con su propio destino de redirección. Los sobres solo existen en campañas creadas con dispatchMode: "per_subject" (en bulk el despacho ya ocurrió al publicar, y la llamada responde 409 CONSENT_CAMPAIGN_DISPATCH_MODE_UNSUPPORTED) y no están disponibles en campañas acotadas por RUT, que no divulgan estado por titular. Acepta un sobre individual o un lote de hasta 200:

POST
/shared-campaigns/:campaignId/envelopes
curl https://app.edugoverna.com/api/partner/v1/organizations/{workspaceOrgId}/shared-campaigns/{campaignId}/envelopes \
  -H "Authorization: Bearer {keyId}.{secret}" \
  -H "Content-Type: application/json" \
  -d '{
    "rut": "12345678-5",
    "successRedirectUrl": "https://plataforma.ejemplo.cl/matricula/8841/ok",
    "redirectMode": "auto",
    "partnerExternalId": "matricula-8841",
    "idempotencyKey": "sobre-matricula-8841"
  }'

Cada sobre identifica al titular con exactamente uno de subjectId (el id que devuelve la lectura del padrón compartido) o rut. La respuesta 202 trae un resultado por sobre:

Resultado por sobre

{
  "subjectId": "8f3b7f0a-2f9d-4d4e-a1c3-77b2a0f1d942",
  "rut": null,
  "envelopeId": "6c2e9a41-0d5f-4b83-a7e2-3f9c1b8d6e04",
  "consentRequestId": "0d9a2c1e-6d61-4f1c-9f5a-3f2f8b6f1a77",
  "status": "sent"
}

Los estados posibles son sent, already_sent (ese titular ya tiene su solicitud: reintentar es seguro), not_in_campaign (no está en el roster; como sobre individual responde 404 CONSENT_CAMPAIGN_CONTACT_NOT_FOUND) y share_revoked (el colegio revocó el share del que venía).

El estado de todos los sobres — incluido el destino planificado de los que aún no se despachan — está en GET .../envelopes, filtrable por status. Para reenviar uno ya despachado, con la opción de corregir su destino:

Reenviar un sobre

curl https://app.edugoverna.com/api/partner/v1/organizations/{workspaceOrgId}/shared-campaigns/{campaignId}/envelopes/{envelopeId}/resend \
  -H "Authorization: Bearer {keyId}.{secret}" \
  -H "Content-Type: application/json" \
  -d '{ "successRedirectUrl": "https://plataforma.ejemplo.cl/matricula/8841/ok-v2" }'

4. Sincroniza la audiencia cuando el padrón crece

Si el colegio matricula estudiantes nuevos en un curso compartido después de creada la campaña, no vuelvas a crearla: sync-audience re-resuelve los cursos guardados y agrega solo los contactos que faltan. Los redirects del cuerpo aplican a los agregados en esa pasada.

POST
/shared-campaigns/:campaignId/sync-audience
curl https://app.edugoverna.com/api/partner/v1/organizations/{workspaceOrgId}/shared-campaigns/{campaignId}/sync-audience \
  -H "Authorization: Bearer {keyId}.{secret}" \
  -H "Content-Type: application/json" \
  -d '{
    "redirects": [
      { "rut": "23456789-6", "successRedirectUrl": "https://plataforma.ejemplo.cl/matricula/9102/ok" }
    ]
  }'

Respuesta · 202 Accepted

{
  "addedContactCount": 4,
  "materializedRequestCount": 4,
  "pendingRequestCount": 0,
  "submittedRedirectCount": 1
}

En una campaña bulk publicada, la sincronización además emite y despacha las solicitudes nuevas por tramos: pendingRequestCount > 0 significa «vuelve a llamar». El comando es repetible — cada pasada trabaja por diferencia contra lo ya escrito, así que reintentar nunca duplica.

5. Redirects: auto versus bridge

Tras decidir en el portal, el titular puede aterrizar en tu plataforma. En ambos modos el destino recibe consent_id y decision como parámetros de consulta. El modo controla cómo:

  • auto (por defecto): confirmada la decisión, el portal redirige por sí solo tras una breve confirmación visual. Es el modo para flujos donde el consentimiento es un paso intermedio — una matrícula en tu plataforma que continúa del otro lado. Si el navegador del titular pide movimiento reducido, el portal muestra el botón manual en su lugar.
  • bridge: el portal muestra una página puente con la confirmación de la decisión y un botón «Continuar» que el titular pulsa cuando quiera. Es el modo para cierres tranquilos, donde no hay un paso siguiente urgente.

En una campaña compartida los destinos son tuyos — el aviso que la familia lee lo firma tu organización — y hay tres momentos para fijarlos: al crear (defaultSuccessRedirectUrl y los pares redirects por RUT), al emitir o reenviar un sobre (destino de esa entrega puntual) y con POST .../redirects para corregir el destino planificado de sobres aún no despachados (para uno ya enviado, usa el reenvío con destino nuevo).

6. Seguimiento con webhooks

Los eventos de decisión de una campaña compartida cruzan dos organizaciones: la solicitud vive en el padrón del colegio, pero tú eres quien debe empezar — o dejar de — tratar datos con esa decisión. Por eso consent.decision.recorded se despacha a ambas partes, y tu copia llega con una proyección reducida (projection: "shared_partner") limitada a lo que ya puedes leer por la API:

Payload · proyección shared_partner

{
  "event": "consent.decision.recorded",
  "sourceType": "consent_request",
  "sourceId": "0d9a2c1e-6d61-4f1c-9f5a-3f2f8b6f1a77",
  "occurredAt": "2026-08-25T14:03:22.000Z",
  "data": {
    "projection": "shared_partner",
    "consentRequestId": "0d9a2c1e-6d61-4f1c-9f5a-3f2f8b6f1a77",
    "dataOwnerOrganizationId": "org-colegio",
    "registryShareId": "b1f6a3d2-4c1e-4e29-9d5b-8a0f7c3e2d11",
    "campaignId": "a4c8e2f6-7b31-4d95-8e0a-1f6c3b9d2e57",
    "campaignStatus": "published",
    "campaignMode": "targeted",
    "campaignContactEntryId": "6c2e9a41-0d5f-4b83-a7e2-3f9c1b8d6e04",
    "processingActivityVersionId": "3f7e6c9d-8f21-4b83-bb1c-5e2d9a447f10",
    "subject": {
      "referenceCode": "EST-2026-0142",
      "subjectType": "student",
      "requestedForAgeBand": "under_14"
    },
    "status": "granted",
    "decisionActorType": "guardian",
    "requestedAt": "2026-08-25T13:40:12.000Z",
    "expiresAt": null,
    "updatedAt": "2026-08-25T14:03:22.000Z",
    "latestDecision": {
      "decision": "granted",
      "decisionAuthority": "guardian",
      "captureMethod": "portal_link_otp",
      "decidedAt": "2026-08-25T14:03:21.000Z",
      "effectiveFrom": "2026-08-25T14:03:21.000Z",
      "effectiveTo": null,
      "revokedAt": null
    }
  }
}

Correlaciona con campaignContactEntryId — el id del sobre en tu propia organización — en lugar de identificadores del padrón ajeno. La proyección nunca incluye RUT, contactos ni el nombre del titular: si los necesitas para mostrar, ya los tienes por GET /shares/:shareId/subjects.

Ten presente que las solicitudes de una campaña compartida viven en la organización del colegio, así que los eventos de su ciclo de entrega (consent.requested, consent.delivery.*) se enrutan a los endpoints del colegio, no a los tuyos: la copia que te llega a ti es la decisión. Para el estado intermedio de tus envíos usa GET /shared-campaigns/:campaignId y GET .../envelopes. Configura tus endpoints en Gestión » Webhooks y revisa el formato general en Webhooks.

¿Qué sigue?

¿Te sirvió esta página?