Errores y límites

Códigos que no cambian nunca, cuotas generosas y una forma segura de reintentar.

Forma de todos los erroresjson
{
  "error": {
    "code": "forbidden",
    "message": "Esta credencial no tiene el permiso «access:write»."
  }
}

El code es estable: programa contra él. El message está escrito para la persona que lee el log y puede cambiar de redacción.

Códigos

HTTPcodeCuándo
400invalid_requestFalta un parámetro o el cuerpo no cuadra. El detalle viene en `details`.
401unauthorizedNo hay credencial, o está revocada o caducada.
403forbiddenLa clave existe pero no tiene ese permiso, o una regla de negocio lo impide.
404not_foundNo existe (o no es de tu recinto, que para ti es lo mismo).
409conflictEl estado no lo permite: plaza ya reservada, clave de idempotencia reutilizada.
429rate_limitedSe superó algún límite. Respeta la cabecera Retry-After.
503unavailableUn sistema del que dependemos no responde (la cerradura, la pasarela).

Límites

  • 600 peticiones por minuto y clave.
  • 1.200 por minuto y dirección IP, se use la credencial que se use.
  • 30 intentos fallidos de autenticación por minuto e IP.
  • Cuerpo máximo de 256 KB.

Cada respuesta correcta trae X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset (epoch en segundos), para que puedas autorregularte sin tener que provocar un 429 para descubrir dónde está el techo.

Para hacerte una idea: una cámara de matrículas en un área concurrida hace unas pocas decenas de peticiones al día. Estos límites frenan bucles, no integraciones.

Reintentar sin duplicar

Toda escritura acepta la cabecera Idempotency-Key. Si repites la petición con la misma clave recibes la respuesta de la primera vez, en lugar de que el efecto vuelva a ocurrir.

Por qué importa aquí más que en otras APIs

La barrera es de pulso: un impulso la abre y el siguiente la cierra. Un reintento a ciegas tras un timeout de red podría cerrarla encima del coche que está pasando.
curl -X POST https://pernocta.app/api/v1/access/plate \
  -H "Authorization: Bearer pna_live_TU_CLAVE" \
  -H "Idempotency-Key: lectura-carril1-20260821T180000-1234ABC" \
  -H "Content-Type: application/json" \
  -d '{"plate": "1234ABC"}'
  • Usa una clave distinta por operación real. Un buen patrón: dispositivo + instante + dato.
  • Repetir la clave con un cuerpo distinto devuelve 409: casi siempre es un error de quien integra.
  • Las claves se recuerdan siete días.

Además, y aunque no mandes la cabecera, la misma matrícula no vuelve a abrir en 30 segundos. Una cámara real no manda una lectura por coche: manda varias mientras lo tiene encuadrado. La respuesta te lo indica con cooldown: true y sigue diciendo authorized: true.

Cuando algo no cuadra

Toda respuesta lleva X-Request-Id. Mándanoslo junto al problema y encontramos la petición exacta en nuestros registros: es mucho más rápido que describir lo que pasó.