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(emstudent.id): ID global da pessoa. Estável entre unidades.studentHasBranchId(emStudentHasBranch.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étodo | Rota | Scope | Descrição |
|---|---|---|---|
| GET | /v1/students | students:read | Listar estudantes (paginado, filtros) |
| POST | /v1/students | students:write | Criar estudante (e opcionalmente, responsável) |
| GET | /v1/students/:id | students:read | Detalhar estudante |
| PUT | /v1/students/:id | students:write | Atualizar dados do estudante |
| DELETE | /v1/students/:id | students:write | Desligar estudante (soft) |
| POST | /v1/students/:id/reactivate | students:write | Reativar estudante desligado |
| POST | /v1/students/:id/guardian | students:write | Vincular responsável existente |
| DELETE | /v1/students/:id/guardian | students:write | Desvincular responsável |
| GET | /v1/students/:id/gallery | students:read | Listar fotos do aluno (até 10) |
| POST | /v1/students/:id/gallery | students:write | Adicionar fotos (multipart, validação facial) |
| DELETE | /v1/students/:id/gallery | students:write | Remover uma foto |
| POST | /v1/students/:id/access-block | students:write | Bloquear/desbloquear acesso físico |
| PATCH | /v1/students/:id/access-window | students:write | Definir data limite de acesso |
| POST | /v1/students/:id/access-sync | students:write | Forçar sincronização de acesso com dispositivos |
Endpoints aninhados de frequência
| Método | Rota | Scope | Descrição |
|---|---|---|---|
| GET | /v1/students/frequency | frequency:read | Listar frequência agregada por aluno (com filtros) |
| GET | /v1/students/:id/frequency | frequency:read | Detalhe 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âmetro | Tipo | Default | Descrição |
|---|---|---|---|
search | string | — | Busca por nome, email, número, CPF, nome do responsável, email do responsável |
status | string | active | active, inactive ou all |
schoolYearId | UUID | — | ID do período letivo para filtros de turma. Se omitido e outros filtros exigirem, usa o período ativo. |
gradeId | UUID | — | Filtrar por série |
classId | UUID | — | Filtrar por turma |
pendingApproval | "true" | "false" | — | Filtrar por status de aprovação do responsável |
dataStatus | pendingReview | approved | hasErrors | — | Filtrar 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) |
page | integer | 1 | Número da página |
limit | integer | 10 | Itens por página (máx. 100) |
sortBy | string | name | name ou createdAt |
sortOrder | string | asc | Direçã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
| Campo | Tipo | Descrição |
|---|---|---|
id | UUID | ID do vínculo do estudante com a unidade (matrícula) |
registration | string | Matrícula na unidade |
socialCredit | number | Pontuação de comportamento |
approvedByResponsibleAt | ISO 8601 | null | Quando o responsável aprovou o uso dos dados (LGPD) |
unenrolledAt | ISO 8601 | null | Quando foi desligado, ou null se ativo |
sendNotificationToParents | boolean | Se recebe notificações |
student.id | UUID | ID global do estudante |
student.name | string | Nome completo |
student.email | string | null | |
student.number | string | null | Telefone |
student.cpf | string | null | CPF |
student.hasFacial | boolean | Se tem template facial cadastrado |
student.dataStatus | string | pendingReview | approved | hasErrors |
student.guardian | object | null | Resumo do responsável (id, name, email) |
class | object | null | Turma ativa no ano letivo |
lastPresenceAt | ISO 8601 | null | Data/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:
- 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"
}- 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"
}- 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
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | sim | Nome completo do estudante |
email | string | não | Email único |
number | string | não | Telefone do estudante |
registration | string | não | Matrícula na unidade |
classId | UUID | sim* | ID da turma para matricular (* obrigatoriamente com schoolYearId) |
schoolYearId | UUID | sim* | ID do período letivo (* obrigatoriamente com classId) |
fatherName, motherName | string | não | Filiação |
birthdate | ISO 8601 | não | Data de nascimento |
birthCity, birthState, nationality | string | não | Naturalidade |
rg, cpf, orgExp | string | não | Documentos |
sendNotificationToParents | boolean | não | Default: true |
notifyOnlyAfterThreeDaysAbsent | boolean | não | Default: false |
| Responsável | |||
guardianUserId | UUID | OR | ID global do responsável existente (vincula) |
guardianName + guardianEmail | string | OR | Vincula ao responsável existente com esse email, ou cria um novo |
guardianPhone | string | não | Telefone 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
| Status | Code | Quando |
|---|---|---|
| 400 | VALIDATION_ERROR | Dados 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
schoolYearId atualSe 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
classIdcurl "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
| Status | Code | Quando |
|---|---|---|
| 400 | VALIDATION_ERROR | classId 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
| Status | Code | Quando |
|---|---|---|
| 404 | NOT_FOUND | Estudante 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
| Status | Code | Quando |
|---|---|---|
| 404 | NOT_FOUND | Estudante não existe ou já desligado |
| 400 | VALIDATION_ERROR | Dados inválidos |
DELETE /v1/students/:id
Desliga o estudante da unidade. Pode ser reativado posteriormente.
Resposta (204)
Sem corpo (No Content).
Erros
| Status | Code | Quando |
|---|---|---|
| 404 | NOT_FOUND | Estudante 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
}| Campo | Tipo | Descrição |
|---|---|---|
pictures | string[] | URLs das fotos. As URLs expiram após o TTL configurado na plataforma. |
maxSize | number | Limite 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
| Campo | Tipo | Limite | Descrição |
|---|---|---|---|
images | file[] | até 8 arquivos | Imagens 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
| Status | Code | Quando |
|---|---|---|
| 400 | VALIDATION_ERROR | Galeria cheia (10 fotos) ou foto rejeitada (sem rosto, baixa qualidade, rosto não confere com o já cadastrado) |
| 400 | VALIDATION_ERROR | Mais de 8 fotos enviadas na mesma requisição |
| 404 | NOT_FOUND | Aluno 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>"]
}| Status | Code | Quando |
|---|---|---|
| 404 | NOT_FOUND | Foto 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
}| Status | Code | Quando |
|---|---|---|
| 400 | VALIDATION_ERROR | Unidade não possui dispositivos de acesso compatíveis |
| 400 | VALIDATION_ERROR | Formato 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
id da rota: é o vínculo, não a pessoaO :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)
student.dataStatus)pendingReview— dados ainda não validadosapproved— dados revisados e aprovadoshasErrors— 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.
Updated 1 day ago
