Paginación
Las listas de la Partner API se paginan por cursor: cada página incluye un nextCursor opaco que apunta a la página siguiente, hasta que llega como null. El cursor codifica una posición estable en el ordenamiento (no un número de página), así que el recorrido es determinista aunque se inserten filas nuevas mientras paginas.
Cómo funciona
Toda lista acepta los mismos dos parámetros. El resto de los filtros depende de cada recurso.
Parámetros de paginación
- Nombre
limit- Tipo
- integer
- Descripción
Cuántos registros devolver por página. En las listas de consentimientos: entre 1 y 200, con 50 por defecto. En el padrón (
directory/subjects): hasta 250, con 100 por defecto.
- Nombre
cursor- Tipo
- string
- Descripción
El
nextCursordevuelto por la página anterior, sin modificar. Es un valor opaco: no lo parsees ni lo construyas.
El cursor está ligado a la consulta que lo emitió: al recurso, a la
organización y a sus filtros. Reanudar un recorrido cambiando los filtros
respondería filas incorrectas sin que pudieras notarlo, así que el servidor
responde 422 INVALID_CURSOR: en las listas de consentimientos, ante
cualquier cambio de filtros u organización; en el padrón, cuando la
posición a la que apunta el cursor ya no calza con la consulta. Si
necesitas cambiar los filtros, empieza un recorrido nuevo desde la primera
página.
Un cursor tampoco expira por tiempo: puedes pausar un recorrido largo y retomarlo después, siempre con los mismos filtros.
Primera página
curl -G "https://app.edugoverna.com/api/partner/v1/organizations/{organizationId}/directory/subjects" \
-H "Authorization: Bearer $EDUGOVERNA_PARTNER_KEY" \
-d subjectType=student \
-d limit=100
Respuesta (recortada)
{
"subjects": [ "…100 titulares…" ],
"meta": {
"filteredRestrictedCount": 0,
"totalMatchedCount": 412,
"nextCursor": "eyJzY29wZSI6…"
}
}
Recorrer todas las páginas
Para recorrer una lista completa, repite la solicitud pasando el
nextCursor de cada respuesta hasta recibir null. En el padrón el
cursor viaja dentro de meta; en las listas de consentimientos viene al
nivel superior de la respuesta, junto a consentRequests.
Dos detalles del padrón que conviene conocer:
totalMatchedCountes el total de titulares que calzan con el filtro, no el tamaño de la página.filteredRestrictedCountcuenta titulares que existían pero fueron excluidos de la respuesta — por una restricción de tratamiento activa o por la condiciónonlyActivedel alcance de tu conexión. La suma de lo recibido puede ser menor que el total del colegio, y eso es intencional.
Recorrido completo
async function listAllSubjects(organizationId, key) {
const subjects = []
let cursor = null
do {
const url = new URL(
`https://app.edugoverna.com/api/partner/v1/organizations/${organizationId}/directory/subjects`,
)
url.searchParams.set('limit', '100')
if (cursor) url.searchParams.set('cursor', cursor)
const response = await fetch(url, {
headers: { Authorization: `Bearer ${key}` },
})
if (!response.ok) {
const { error } = await response.json()
throw new Error(`${error.code}: ${error.message}`)
}
const page = await response.json()
subjects.push(...page.subjects)
cursor = page.meta.nextCursor
} while (cursor)
return subjects
}
Sincronización incremental con since
La lista de solicitudes de consentimiento acepta además un parámetro
since pensado para trabajos de sincronización: devuelve solo las
solicitudes creadas después de esa fecha (comparada contra
requestedAt). Así, un trabajo periódico no necesita recorrer el
histórico completo en cada corrida:
- En cada corrida, guarda la marca de tiempo de inicio.
- Consulta con
sinceigual a la marca guardada de la corrida anterior y pagina concursorhasta agotar los resultados. - Si todo terminó bien, persiste la marca nueva.
since es un filtro como cualquier otro: forma parte de la identidad del
cursor, así que las páginas de un mismo recorrido deben repetirlo con el
mismo valor.
since filtra por fecha de creación de la solicitud, no de su
último cambio. Para enterarte de decisiones y cambios de estado sin
consultar en un ciclo, complementa la sincronización con los
webhooks — por ejemplo consent.decision.recorded.
Sincronización
curl -G "https://app.edugoverna.com/api/partner/v1/organizations/{organizationId}/consents/requests" \
-H "Authorization: Bearer $EDUGOVERNA_PARTNER_KEY" \
-d since=2026-08-24T00:00:00Z \
-d limit=200
Respuesta (recortada)
{
"consentRequests": [ "…solicitudes nuevas…" ],
"nextCursor": null
}
Otros filtros de la lista de consentimientos
Además de since, cursor y limit, la lista de solicitudes de consentimiento acepta:
- Nombre
status- Tipo
- string
- Descripción
Filtra por estado de la solicitud (por ejemplo
pendingogranted).
- Nombre
processingActivityCode- Tipo
- string
- Descripción
Solo solicitudes de una actividad de tratamiento, por su código.
- Nombre
partnerExternalId- Tipo
- string
- Descripción
Solo solicitudes que creaste con ese identificador externo tuyo — útil para reconciliar contra tu propio sistema.
El detalle de cada recurso y sus filtros está en la referencia: sujetos del padrón y consentimientos.