Desarrolladores · Documentación de la API

Errores y límites

Formato de los errores, códigos, límites de llamadas, listas paginadas y reintentos seguros en la API de EduPay.

Cómo responde la API cuando algo sale mal, cuántas llamadas caben por minuto, cómo recorrer listas grandes y cómo repetir una solicitud sin duplicar nada.

Formato de los errores

Todo error de /api/v1 viene en application/problem+json (RFC 9457):

{
  "type": "about:blank",
  "title": "Unprocessable Content",
  "status": 422,
  "detail": "Algunos campos no son válidos.",
  "code": "validation_failed",
  "errors": { "address.line": ["El campo dirección es obligatorio."] },
  "request_id": "9a6c1f2e-3b4d-4e5f-8a9b-0c1d2e3f4a5b"
}
  • code es estable: no cambia entre versiones. Decida por él.
  • detail es para que lo lean las personas, en el idioma pedido en Accept-Language (pt-BR, en o es). El texto puede cambiar.
  • errors solo en validation_failed: mensajes por campo.
  • scopes solo en insufficient_scope: los permisos que faltan.
  • request_id es el mismo del encabezado X-Request-Id. Infórmelo al soporte.

Códigos

code Estado Significa
unauthenticated 401 Clave ausente, incorrecta, vencida o revocada
api_disabled 403 La API está desactivada en la escuela
insufficient_scope 403 La clave no tiene el permiso de la ruta
forbidden 403 Acceso denegado
student_limit_reached 403 El plan de la escuela llegó al límite de alumnos
not_found 404 El registro no existe en esta escuela
method_not_allowed 405 Método HTTP no aceptado en la dirección
bad_request 400 Solicitud mal formada
invalid_cursor 400 Cursor de página inválido: reinicie la lista
idempotency_key_required 400 La ruta exige el encabezado Idempotency-Key
idempotency_key_invalid 400 Idempotency-Key fuera del formato
conflict 409 La solicitud entra en conflicto con el estado actual del registro
idempotency_in_progress 409 Otra solicitud con la misma Idempotency-Key todavía está en curso
enrollment_conflict 409 El alumno ya tiene una matrícula vigente en el curso o trayecto (vea existing_enrollment_id)
enrollment_not_cancellable 409 La matrícula ya está cancelada o concluida
installment_not_payable 409 La cuota no puede tener segunda copia (pagada, cancelada o dispensada)
boleto_still_valid 409 El boleto actual todavía vale y no se puede cancelar en el banco
gateway_not_connected 409 La escuela no conectó la cuenta de cobro
student_inactive 409 El alumno está inactivo
student_without_portal_access 409 El alumno no tiene e-mail o cuenta en el portal
portal_not_configured 409 El portal del alumno de la escuela no tiene dirección
portal_link_ambiguous_email 409 Dos alumnos de la escuela usan el mismo e-mail
validation_failed 422 Campos inválidos (detalle en errors)
idempotency_key_reused 422 La Idempotency-Key ya se usó con otros datos
rate_limited 429 Límite de llamadas alcanzado
internal_error 500 Error interno en EduPay
gateway_error 502 El banco rechazó o no respondió
http_error otros No fue posible atender la solicitud

Límites de llamadas

Límite Por minuto
Consultas (GET) por clave 120
Escrituras (POST, PATCH, DELETE) por clave 30
Todas las claves de la escuela sumadas 300

Toda respuesta trae X-RateLimit-Limit y X-RateLimit-Remaining. Si pasa el límite, la respuesta es 429 con Retry-After (segundos). Espere ese tiempo y repita.

Las rutas del plugin de Moodle tienen su propio límite y no entran en esa cuenta.

Listas en páginas

Las listas devuelven hasta limit elementos (de 1 a 200; sin él, 50), en orden de creación:

{
  "data": [ { "id": 101, "...": "..." }, { "id": 102, "...": "..." } ],
  "meta": { "next_cursor": "eyJpZCI6MTAyfQ", "has_more": true }
}

Para la página siguiente, repita la llamada con cursor= igual a meta.next_cursor, manteniendo los demás filtros. Pare cuando has_more sea false. El cursor no salta ni repite registros, aunque entren registros nuevos en el medio.

Para sincronizar solo lo que cambió, use updated_since (fecha y hora en ISO 8601).

Repetir con seguridad

Las escrituras (POST y PATCH) aceptan el encabezado Idempotency-Key; crear una matrícula lo exige. Envíe un código único por solicitud, de 1 a 255 caracteres visibles (un UUID o el número del pedido en su sistema).

Situación Qué ocurre
Misma clave, misma solicitud, en hasta 24 horas Vuelve la primera respuesta, con Idempotent-Replayed: true. No se graba nada de nuevo
Misma clave, datos diferentes 422 con code idempotency_key_reused
Misma clave mientras la primera solicitud todavía está en curso 409 con code idempotency_in_progress: espere unos segundos y repita
La primera solicitud dio error La clave queda libre: corrija y repita con la misma clave

La clave vale por escuela y por 24 horas. "Misma solicitud" significa el mismo método, la misma dirección y los mismos datos, en cualquier orden de los campos.

Cuándo repetir

  • 429: después del Retry-After.
  • 500, 502, 503 o tiempo agotado: con espera creciente (1 s, 2 s, 4 s...) y la misma Idempotency-Key.
  • 400, 401, 403, 404, 409 y 422: no sirve repetir igual. Corrija la solicitud, la clave o el permiso.