Como a API responde quando algo dá errado, quantas chamadas cabem por minuto, como percorrer listas grandes e como repetir um pedido sem duplicar nada.
Formato dos erros
Todo erro de /api/v1 vem em application/problem+json (RFC 9457):
{
"type": "about:blank",
"title": "Unprocessable Content",
"status": 422,
"detail": "Alguns campos estão inválidos.",
"code": "validation_failed",
"errors": { "address.line": ["O campo endereço é obrigatório."] },
"request_id": "9a6c1f2e-3b4d-4e5f-8a9b-0c1d2e3f4a5b"
}
codeé estável: não muda entre versões. Decida por ele.detailé para gente ler, no idioma pedido emAccept-Language(pt-BR,enoues). O texto pode mudar.errorssó emvalidation_failed: mensagens por campo.scopessó eminsufficient_scope: as permissões que faltam.request_idé o mesmo do cabeçalhoX-Request-Id. Informe ao suporte.
Códigos
code |
Status | Quer dizer |
|---|---|---|
unauthenticated |
401 | Chave ausente, errada, vencida ou revogada |
api_disabled |
403 | A API está desligada na escola |
insufficient_scope |
403 | A chave não tem a permissão da rota |
forbidden |
403 | Acesso negado |
student_limit_reached |
403 | O plano da escola chegou ao limite de alunos |
not_found |
404 | O registro não existe nesta escola |
method_not_allowed |
405 | Método HTTP não aceito no endereço |
bad_request |
400 | Pedido mal formado |
invalid_cursor |
400 | Cursor de página inválido: recomece a lista |
idempotency_key_required |
400 | A rota exige o cabeçalho Idempotency-Key |
idempotency_key_invalid |
400 | Idempotency-Key fora do formato |
conflict |
409 | O pedido conflita com o estado atual do registro |
idempotency_in_progress |
409 | Outro pedido com a mesma Idempotency-Key ainda está rodando |
enrollment_conflict |
409 | O aluno já tem matrícula viva no curso ou trilha (veja existing_enrollment_id) |
enrollment_not_cancellable |
409 | A matrícula já está cancelada ou concluída |
installment_not_payable |
409 | A parcela não pode ter 2ª via (paga, cancelada ou dispensada) |
boleto_still_valid |
409 | O boleto atual ainda vale e não pode ser cancelado no banco |
gateway_not_connected |
409 | A escola não conectou a conta de recebimento |
student_inactive |
409 | O aluno está inativo |
student_without_portal_access |
409 | O aluno não tem e-mail ou conta no portal |
portal_not_configured |
409 | O portal do aluno da escola não tem endereço |
portal_link_ambiguous_email |
409 | Dois alunos da escola usam o mesmo e-mail |
validation_failed |
422 | Campos inválidos (detalhe em errors) |
idempotency_key_reused |
422 | A Idempotency-Key já foi usada com outros dados |
rate_limited |
429 | Limite de chamadas atingido |
internal_error |
500 | Erro interno no EduPay |
gateway_error |
502 | O banco recusou ou não respondeu |
http_error |
outros | Não foi possível atender o pedido |
Limites de chamadas
| Limite | Por minuto |
|---|---|
Consultas (GET) por chave |
120 |
Escritas (POST, PATCH, DELETE) por chave |
30 |
| Todas as chaves da escola somadas | 300 |
Toda resposta traz X-RateLimit-Limit e X-RateLimit-Remaining. Passou do limite, a resposta é 429 com Retry-After (segundos). Espere esse tempo e repita.
As rotas do plugin do Moodle têm limite próprio e não entram nessa conta.
Listas em páginas
As listas devolvem até limit itens (de 1 a 200; sem ele, 50), em ordem de criação:
{
"data": [ { "id": 101, "...": "..." }, { "id": 102, "...": "..." } ],
"meta": { "next_cursor": "eyJpZCI6MTAyfQ", "has_more": true }
}
Para a próxima página, repita a chamada com cursor= igual ao meta.next_cursor, mantendo os outros filtros. Pare quando has_more for false. O cursor não pula nem repete registro, mesmo que entrem registros novos no meio.
Para sincronizar só o que mudou, use updated_since (data e hora em ISO 8601).
Repetir com segurança
Escritas (POST e PATCH) aceitam o cabeçalho Idempotency-Key; criar matrícula exige. Mande um código único por pedido, de 1 a 255 caracteres visíveis (um UUID ou o número do pedido no seu sistema).
| Situação | O que acontece |
|---|---|
| Mesma chave, mesmo pedido, em até 24 horas | Volta a primeira resposta, com Idempotent-Replayed: true. Nada é gravado de novo |
| Mesma chave, dados diferentes | 422 com code idempotency_key_reused |
| Mesma chave enquanto o primeiro pedido ainda roda | 409 com code idempotency_in_progress: espere uns segundos e repita |
| O primeiro pedido deu erro | A chave fica livre: corrija e repita com a mesma chave |
A chave vale por escola e por 24 horas. "Mesmo pedido" é mesmo método, mesmo endereço e mesmos dados, em qualquer ordem dos campos.
Quando repetir
429: depois doRetry-After.500,502,503ou tempo esgotado: com espera crescente (1 s, 2 s, 4 s...) e a mesmaIdempotency-Key.400,401,403,404,409e422: não adianta repetir igual. Corrija o pedido, a chave ou a permissão.