Gestão de Estudantes

Os estudantes representam os alunos matriculados na plataforma. Cada estudante pertence a uma unidade através de um vínculo de matrícula, e pode ser vinculado a um responsável — geralmente um pai/mãe/responsável legal.

:::info
Branch-scoped
Todos os endpoints de estudantes operam no contexto de uma unidade. O parâmetro :id nas rotas refere-se ao ID do vínculo com a unidade (matrícula), não ao ID global do estudante. O responsável, por outro lado, é uma pessoa global que pode ter filhos em várias unidades.
:::

:::warning[O que é o :id em /v1/students/:id?]
/v1/students/:id usa o studentHasBranchId (ID do vínculo com a unidade), não o studentId global.

  • studentId (em student.id): ID global da pessoa. Estável entre unidades.
  • studentHasBranchId (em StudentHasBranch.id): ID do vínculo com a unidade. Muda se o aluno trocar de unidade.

Em quase todos os endpoints da API, o :id é o studentHasBranchId. Use GET /v1/students/:id para descobrir o studentId global (campo student.id na resposta).

Comparação com /v1/users/:id: ali o :id é o userId global, não o userHasBranchId. Verifique a doc de Usuários para o contraste.
:::

Endpoints

MétodoRotaScopeDescrição
GET/v1/studentsstudents:readListar estudantes (paginado, filtros)
POST/v1/studentsstudents:writeCriar estudante (e opcionalmente, responsável)
GET/v1/students/:idstudents:readDetalhar estudante
PUT/v1/students/:idstudents:writeAtualizar dados do estudante
DELETE/v1/students/:idstudents:writeDesligar estudante (soft)
POST/v1/students/:id/reactivatestudents:writeReativar estudante desligado
POST/v1/students/:id/guardianstudents:writeVincular responsável existente
DELETE/v1/students/:id/guardianstudents:writeDesvincular responsável
GET/v1/students/:id/gallerystudents:readListar fotos do aluno (até 10)
POST/v1/students/:id/gallerystudents:writeAdicionar fotos (multipart, validação facial)
DELETE/v1/students/:id/gallerystudents:writeRemover uma foto
POST/v1/students/:id/access-blockstudents:writeBloquear/desbloquear acesso físico
PATCH/v1/students/:id/access-windowstudents:writeDefinir data limite de acesso
POST/v1/students/:id/access-syncstudents:writeForçar sincronização de acesso com dispositivos

Endpoints aninhados de frequência

MétodoRotaScopeDescrição
GET/v1/students/frequencyfrequency:readListar frequência agregada por aluno (com filtros)
GET/v1/students/:id/frequencyfrequency:readDetalhe da frequência de um aluno (timeline, totais, gráficos)

GET /v1/students

Lista os estudantes da unidade com paginação e filtros avançados.

Parâmetros (query)

ParâmetroTipoDefaultDescrição
searchstringBusca por nome, email, número, CPF, nome do responsável, email do responsável
statusstringactiveactive, inactive ou all
schoolYearIdUUIDID do período letivo para filtros de turma. Se omitido e outros filtros exigirem, usa o período ativo.
gradeIdUUIDFiltrar por série
classIdUUIDFiltrar por turma
pendingApproval"true" | "false"Filtrar por status de aprovação do responsável
dataStatuspendingReview | approved | hasErrorsFiltrar por status dos dados cadastrais
hasGuardian"true" | "false"Se tem responsável vinculado
hasFacial"true" | "false"Se tem template facial cadastrado
hasApp"true" | "false"Se tem sessão ativa no app (aluno ou responsável)
unenrolled"true" | "false""false"Listar estudantes desligados (em vez de ativos)
pageinteger1Número da página
limitinteger10Itens por página (máx. 100)
sortBystringnamename ou createdAt
sortOrderstringascDireção: asc ou desc

Exemplo

curl "https://api.gdredu.com/v1/students?gradeId=grade-1&hasGuardian=true&dataStatus=approved&page=1&limit=10" \
  -H "Authorization: Bearer gdredu_live_..." \
  -H "x-branch-id: branch-id-aqui"

Resposta (200)

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "registration": "2026001",
      "socialCredit": 10.0,
      "approvedByResponsibleAt": "2026-01-15T10:00:00.000Z",
      "unenrolledAt": null,
      "sendNotificationToParents": true,
      "student": {
        "id": "660e8400-e29b-41d4-a716-446655440000",
        "name": "João da Silva",
        "email": "[email protected]",
        "number": null,
        "cpf": null,
        "hasFacial": true,
        "dataStatus": "approved",
        "guardian": {
          "id": "770e8400-e29b-41d4-a716-446655440000",
          "name": "Maria da Silva",
          "email": "[email protected]"
        }
      },
      "class": {
        "id": "880e8400-e29b-41d4-a716-446655440000",
        "name": "Turma 1A",
        "grade": { "id": "...", "name": "1º Ano EM" }
      },
      "lastPresenceAt": "2026-06-18T08:00:00.000Z"
    }
  ],
  "pagination": { "page": 1, "limit": 10, "total": 1, "totalPages": 1, "hasNext": false, "hasPrev": false }
}

Campos da resposta

CampoTipoDescrição
idUUIDID do vínculo do estudante com a unidade (matrícula)
registrationstringMatrícula na unidade
socialCreditnumberPontuação de comportamento
approvedByResponsibleAtISO 8601 | nullQuando o responsável aprovou o uso dos dados (LGPD)
unenrolledAtISO 8601 | nullQuando foi desligado, ou null se ativo
sendNotificationToParentsbooleanSe recebe notificações
student.idUUIDID global do estudante
student.namestringNome completo
student.emailstring | nullEmail
student.numberstring | nullTelefone
student.cpfstring | nullCPF
student.hasFacialbooleanSe tem template facial cadastrado
student.dataStatusstringpendingReview | approved | hasErrors
student.guardianobject | nullResumo do responsável (id, name, email)
classobject | nullTurma ativa no ano letivo
lastPresenceAtISO 8601 | nullData/hora do último reconhecimento facial

POST /v1/students

Cria um novo estudante na unidade. Opcionalmente, também vincula ou cria um responsável.

Body (mínimo)

{
  "name": "João da Silva",
  "classId": "550e8400-e29b-41d4-a716-446655440000",
  "schoolYearId": "660e8400-e29b-41d4-a716-446655440000"
}

Body (com responsável)

Existem 3 formas de vincular o responsável:

  1. Vincular por ID (responsável já existe):
{
  "name": "João da Silva",
  "classId": "550e8400-e29b-41d4-a716-446655440000",
  "schoolYearId": "660e8400-e29b-41d4-a716-446655440000",
  "guardianUserId": "770e8400-e29b-41d4-a716-446655440000"
}
  1. Criar novo responsável (se o email já existir, o responsável é vinculado; caso contrário, é criado):
{
  "name": "João da Silva",
  "classId": "550e8400-e29b-41d4-a716-446655440000",
  "schoolYearId": "660e8400-e29b-41d4-a716-446655440000",
  "guardianName": "Maria da Silva",
  "guardianEmail": "[email protected]",
  "guardianPhone": "11999998888"
}
  1. Sem responsável (não envie nenhum campo de responsável):
{
  "name": "João da Silva",
  "classId": "550e8400-e29b-41d4-a716-446655440000",
  "schoolYearId": "660e8400-e29b-41d4-a716-446655440000"
}

Campos completos

CampoTipoObrigatórioDescrição
namestringsimNome completo do estudante
emailstringnãoEmail único
numberstringnãoTelefone do estudante
registrationstringnãoMatrícula na unidade
classIdUUIDsim*ID da turma para matricular (* obrigatoriamente com schoolYearId)
schoolYearIdUUIDsim*ID do período letivo (* obrigatoriamente com classId)
fatherName, motherNamestringnãoFiliação
birthdateISO 8601nãoData de nascimento
birthCity, birthState, nationalitystringnãoNaturalidade
rg, cpf, orgExpstringnãoDocumentos
sendNotificationToParentsbooleannãoDefault: true
notifyOnlyAfterThreeDaysAbsentbooleannãoDefault: false
Responsável
guardianUserIdUUIDORID global do responsável existente (vincula)
guardianName + guardianEmailstringORVincula ao responsável existente com esse email, ou cria um novo
guardianPhonestringnãoTelefone do responsável

Resposta (201)

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "branchId": "...",
  "registration": "2026001",
  "approvedByResponsibleAt": "2026-06-19T12:00:00.000Z",
  "guardianId": "770e8400-e29b-41d4-a716-446655440000"
}

Erros

StatusCodeQuando
400VALIDATION_ERRORDados inválidos, email/CPF duplicado, turma/ano letivo não encontrado

Matrícula em turma

Ao criar um estudante, o par classId + schoolYearId é obrigatório se você quiser vinculá-lo a uma turma. Isso reflete o modelo do sistema: cada aluno tem um histórico de matrículas (uma por ano letivo) e cada matrícula é vinculada a uma turma e um ano letivo específicos.

:::caution
A criação de aluno sem classId/schoolYearId é aceita (o aluno é cadastrado mas sem matrícula). Você poderá vinculá-lo depois via PUT /v1/students/:id (em uma versão futura) ou diretamente no painel.
:::

Como descobrir o schoolYearId atual

Se você não souber qual schoolYearId usar, descubra via:

curl "https://api.gdredu.com/v1/school-years/active" \
  -H "Authorization: Bearer gdredu_live_..." \
  -H "x-branch-id: 770e8400-..."

O retorno inclui o id do ano letivo ativo. Use esse valor no schoolYearId do POST /v1/students. Veja a doc completa de Anos Letivos para mais detalhes.

Como descobrir o classId

curl "https://api.gdredu.com/v1/classes?schoolYearId=aa0e8400-..." \
  -H "Authorization: Bearer gdredu_live_..." \
  -H "x-branch-id: 770e8400-..."

Filtra por série/turno e use o id da turma desejada.

Exemplo completo (criação + matrícula)

# 1. Descobrir o ano letivo ativo
curl "https://api.gdredu.com/v1/school-years/active" \
  -H "Authorization: Bearer gdredu_live_..." \
  -H "x-branch-id: 770e8400-..." | jq '.active.id'

# 2. Descobrir uma turma
curl "https://api.gdredu.com/v1/classes?schoolYearId=aa0e8400-..." \
  -H "Authorization: Bearer gdredu_live_..." \
  -H "x-branch-id: 770e8400-..." | jq '.data[0].id'

# 3. Criar aluno já matriculando
curl -X POST "https://api.gdredu.com/v1/students" \
  -H "Authorization: Bearer gdredu_live_..." \
  -H "x-branch-id: 770e8400-..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d" \
  -d '{
    "name": "João da Silva",
    "classId": "880e8400-e29b-41d4-a716-446655440000",
    "schoolYearId": "aa0e8400-e29b-41d4-a716-446655440000",
    "guardianName": "Maria da Silva",
    "guardianEmail": "[email protected]"
  }'

A resposta do GET /v1/students/:id posteriormente trará a matrícula no campo enrollments (uma entrada com class, schoolYear e schoolYearId).

Erros comuns

StatusCodeQuando
400VALIDATION_ERRORclassId ou schoolYearId inválido para a unidade

GET /v1/students/:id

Retorna os detalhes completos de um estudante (incluindo dados pessoais, documentos, status LGPD, etc).

Resposta (200)

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "branchId": "a999af34-c399-45f6-9dc9-5e8c024b0a49",
  "registration": "2026001",
  "socialCredit": 10.0,
  "approvedByResponsibleAt": "2026-01-15T10:00:00.000Z",
  "unenrolledAt": null,
  "sendNotificationToParents": true,
  "notifyOnlyAfterThreeDaysAbsent": false,
  "hasControlIdEquipment": false,
  "enrollments": [
    {
      "id": "990e8400-e29b-41d4-a716-446655440000",
      "schoolYearId": "aa0e8400-e29b-41d4-a716-446655440000",
      "schoolYear": {
        "id": "aa0e8400-e29b-41d4-a716-446655440000",
        "name": "Ano letivo 2026",
        "year": 2026,
        "isActive": true
      },
      "class": {
        "id": "880e8400-e29b-41d4-a716-446655440000",
        "name": "Turma 1A",
        "gradeId": "660e8400-e29b-41d4-a716-446655440000"
      }
    }
  ],
  "student": {
    "id": "660e8400-e29b-41d4-a716-446655440000",
    "name": "João da Silva",
    "email": "[email protected]",
    "number": null,
    "cpf": null,
    "hasFacial": true,
    "dataStatus": "approved",
    "fatherName": "José da Silva",
    "motherName": "Maria da Silva",
    "birthdate": "2010-05-15T00:00:00.000Z",
    "birthCity": "Recife",
    "birthState": "PE",
    "nationality": "Brasileira",
    "guardian": {
      "id": "770e8400-e29b-41d4-a716-446655440000",
      "name": "Maria da Silva",
      "email": "[email protected]"
    }
  }
}

O campo enrollments lista todas as matrículas ativas do estudante na unidade (uma por ano letivo + turma). Use GET /v1/school-years/active para descobrir o ano letivo corrente da unidade.

Erros

StatusCodeQuando
404NOT_FOUNDEstudante não existe ou não pertence à unidade

PUT /v1/students/:id

Atualiza dados do estudante e/ou do vínculo com a unidade.

Body

Todos os campos são opcionais (PATCH semântico):

{
  "name": "João da Silva Santos",
  "registration": "2026002",
  "email": "[email protected]",
  "number": "11988887777",
  "fatherName": "José da Silva Santos",
  "birthdate": "2010-05-15T00:00:00.000Z",
  "sendNotificationToParents": true,
  "notifyOnlyAfterThreeDaysAbsent": false
}

Erros

StatusCodeQuando
404NOT_FOUNDEstudante não existe ou já desligado
400VALIDATION_ERRORDados inválidos

DELETE /v1/students/:id

Desliga o estudante da unidade. Pode ser reativado posteriormente.

Resposta (204)

Sem corpo (No Content).

Erros

StatusCodeQuando
404NOT_FOUNDEstudante não existe ou já desligado

POST /v1/students/:id/reactivate

Reativa um estudante desligado.

Resposta (200)

{ "id": "...", "message": "Estudante reativado com sucesso." }

Vínculo de responsável

POST /v1/students/:id/guardian

Vincula um responsável existente (pelo ID global do responsável) ao estudante. Para criar um novo responsável no momento do cadastro, use POST /v1/students com guardianName + guardianEmail.

Body:

{ "guardianUserId": "770e8400-e29b-41d4-a716-446655440000" }

Resposta (200):

{
  "studentId": "660e8400-e29b-41d4-a716-446655440000",
  "guardian": { "id": "...", "name": "Maria da Silva", "email": "..." }
}

DELETE /v1/students/:id/guardian

Desvincula o responsável atual do estudante.

Resposta (204)


Galeria de Fotos

A galeria armazena até 10 fotos por aluno, usadas para reconhecimento facial. A primeira foto é tratada como foto principal (avatar).

GET /v1/students/:id/gallery

Lista as fotos do aluno.

Resposta (200)

{
  "studentId": "660e8400-e29b-41d4-a716-446655440000",
  "studentName": "João da Silva",
  "pictures": [
    "https://cdn.gdredu.com/photos/students/660e.../abc123.jpg?<sas>",
    "https://cdn.gdredu.com/photos/students/660e.../def456.jpg?<sas>"
  ],
  "maxSize": 10
}
CampoTipoDescrição
picturesstring[]URLs das fotos. As URLs expiram após o TTL configurado na plataforma.
maxSizenumberLimite máximo (10).

POST /v1/students/:id/gallery

Adiciona uma ou mais fotos à galeria. Cada foto é validada (presença de rosto, qualidade) antes de ser aceita.

Content-Type: multipart/form-data

Campos do formulário

CampoTipoLimiteDescrição
imagesfile[]até 8 arquivosImagens do rosto (JPG/PNG).

Exemplo

curl -X POST https://api.gdredu.com/v1/students/660e8400-e29b-41d4-a716-446655440000/gallery \
  -H "Authorization: Bearer gdredu_live_..." \
  -H "x-branch-id: 770e8400-e29b-41d4-a716-446655440000" \
  -H "Idempotency-Key: any-uuid" \
  -F "images=@/path/to/foto1.jpg" \
  -F "images=@/path/to/foto2.jpg"

Resposta (200)

{
  "success": true,
  "pictures": [
    "https://cdn.gdredu.com/photos/students/660e.../foto1.jpg?<sas>",
    "https://cdn.gdredu.com/photos/students/660e.../foto2.jpg?<sas>"
  ],
  "added": 2,
  "validation": {
    "confidence": 0.97,
    "faceCount": 1
  }
}

Erros

StatusCodeQuando
400VALIDATION_ERRORGaleria cheia (10 fotos) ou foto rejeitada (sem rosto, baixa qualidade, rosto não confere com o já cadastrado)
400VALIDATION_ERRORMais de 8 fotos enviadas na mesma requisição
404NOT_FOUNDAluno não encontrado na unidade

DELETE /v1/students/:id/gallery

Remove uma foto da galeria. Informe a URL completa da foto.

Body

{
  "pictureUrl": "https://cdn.gdredu.com/photos/students/660e.../foto1.jpg?<sas>"
}

Resposta (200)

{
  "success": true,
  "pictures": ["https://cdn.gdredu.com/photos/students/660e.../restante.jpg?<sas>"]
}
StatusCodeQuando
404NOT_FOUNDFoto não encontrada na galeria

Acesso Físico (Catracas)

Endpoints para controlar o acesso físico do aluno (entrada/saída de catracas) e definir uma data limite de acesso. Verifique o campo hasControlIdEquipment em GET /v1/students/:id — quando false, os endpoints desta seção retornam 400.

POST /v1/students/:id/access-block

Bloqueia ou desbloqueia o acesso físico do aluno. Após alterar, a plataforma propaga automaticamente a mudança aos dispositivos da unidade.

Body

{
  "blocked": true
}

Resposta (200)

{
  "id": "660e8400-e29b-41d4-a716-446655440000",
  "isAccessBlocked": true,
  "accessBlockedAt": "2026-06-20T16:30:00.000Z",
  "devicesUpdated": 3
}

PATCH /v1/students/:id/access-window

Define uma data limite de acesso. Após essa data, o aluno é considerado sem acesso até que a janela seja removida (null) ou estendida.

:::info
Bloqueio efetivo
O acesso efetivo é bloqueado se qualquer das condições for verdadeira: isAccessBlocked = true ou accessAllowedUntil já expirou. A catraca respeita esse valor combinado no momento do reconhecimento.
:::

Body

{
  "accessAllowedUntil": "2026-12-31"
}

Para remover a data limite (acesso permanente enquanto não houver bloqueio manual), envie null:

{
  "accessAllowedUntil": null
}

Resposta (200)

{
  "id": "660e8400-e29b-41d4-a716-446655440000",
  "accessAllowedUntil": "2026-12-31T23:59:59.000Z",
  "accessExpired": false,
  "effectiveAccessBlocked": false,
  "devicesUpdated": 3
}
StatusCodeQuando
400VALIDATION_ERRORUnidade não possui dispositivos de acesso compatíveis
400VALIDATION_ERRORFormato de data inválido (esperado YYYY-MM-DD)

POST /v1/students/:id/access-sync

Força a sincronização do estado de acesso do aluno com todos os dispositivos da unidade. Use após mudanças em massa (ex: várias fotos adicionadas em sequência) ou ao diagnosticar inconsistências.

Resposta (200)

{
  "id": "660e8400-e29b-41d4-a716-446655440000",
  "devicesUpdated": 3
}

Conceitos importantes

id da rota: é o vínculo, não a pessoa

O :id em /v1/students/:id refere-se ao ID do vínculo (matrícula) com a unidade, não ao ID global do estudante. Isso porque todas as operações são por unidade — duas matrículas do mesmo estudante em unidades diferentes têm IDs diferentes.

Responsável: pessoa global, vínculo de estudante: por unidade

O campo student.guardian referencia uma pessoa global. Um responsável pode ter filhos em várias unidades e ser vinculado a cada um separadamente.

Status dos dados (student.dataStatus)

  • pendingReview — dados ainda não validados
  • approved — dados revisados e aprovados
  • hasErrors — dados com pendências para corrigir

Desligamento vs Exclusão

O DELETE não remove o vínculo de forma permanente. O registro é preservado para histórico e pode ser reativado via POST /v1/students/:id/reactivate.


Did this page help you?