Errores
Códigos HTTP estándar y cuerpos de error consistentes en toda la API.
Códigos de estado
| Campo | Tipo | Descripción |
|---|---|---|
200 | OK | Petición correcta. |
201 | Created | Recurso creado (p. ej. un check-in nuevo). |
400 | Bad Request | JSON inválido o validación fallida — el detalle indica el campo exacto. |
401 | Unauthorized | Falta la API key o no es válida (la rechaza el gateway). |
402 | Payment Required | Has agotado las reservas de prueba gratuitas. Añade una tarjeta para seguir creando reservas; lo ya enviado no se ve afectado. |
403 | Forbidden | Cuenta suspendida por impago (tenant_suspended): regulariza el pago en el panel (Facturación) para reactivar el servicio. O cuenta con la baja pedida (account_closing): solo responde /exports hasta que se reactive o la baja sea efectiva. |
404 | Not Found | El recurso no existe en tu cuenta (o aún no está disponible, p. ej. un contrato sin firmar). |
409 | Conflict | La operación no cabe en el estado actual del recurso (p. ej. añadir un huésped a una reserva completa, borrar uno cuyo parte ya se comunicó, cambiar las fechas de una reserva cuyo parte SES aún no ha confirmado, o descargar una exportación que aún se está generando). El campo error dice cuál. |
410 | Gone | El enlace del huésped ha caducado (14 días tras la salida), en las rutas públicas /c/…; o, en la API v1, el ZIP de una exportación ya se borró (siete días después de estar lista). |
429 | Too Many Requests | Cuota diaria de creación de check-ins alcanzada (se reinicia a medianoche UTC). Si tu operación real necesita más, contáctanos y la ampliamos. |
500 | Internal | Error nuestro. Reintenta; si persiste, contáctanos. |
502 | Bad Gateway | Un sistema externo falló (SES Hospedajes rechazó o no respondió). No es un error de tu petición: reintenta más tarde. |
503 | Service Unavailable | SES Hospedajes no respondió a una operación que tiene que salir bien ANTES de guardar tu cambio: anular un parte para cambiar las fechas de una reserva ya comunicada. No se ha guardado nada; reintenta más tarde. |
Códigos de error concretos
Más allá del status HTTP, el campo error del cuerpo identifica la causa exacta para que puedas ramificar sin analizar textos:
| Campo | Tipo | Descripción |
|---|---|---|
payment_method_required | 402 | Has agotado las reservas de prueba gratuitas. Añade una tarjeta en el panel (Ajustes → Facturación) para seguir creando reservas. Lo ya enviado no se ve afectado: los partes comunicados siguen comunicados y el panel sigue accesible. Solo lo devuelve POST /checkins. |
tenant_suspended | 403 | Cuenta suspendida por impago. Toda la API v1 queda bloqueada hasta regularizar. |
account_closing | 403 | La baja de la cuenta está pedida. Durante los 30 días de gracia toda la API v1 responde esto salvo /exports, para que puedas llevarte los registros. effectiveAt dice cuándo será definitiva; reactivando la cuenta desde el panel vuelve a funcionar todo. Ver Exportación y fin del servicio. |
validation | 400 | Datos inválidos. Viene con issues[] o details indicando el campo. |
invalid_url | 400 | URL de webhook rechazada: debe ser https y apuntar a un servidor público (se bloquean redes internas). |
full | 409 | La reserva ya tiene tantos huéspedes registrados como plazas confirmadas. |
already_submitted | 409 | No se puede eliminar el huésped: su parte ya se comunicó a SES. |
refiling_blocked | 409 / 503 | Se pidió cambiar las fechas de una reserva cuyo parte ya se comunicó y Kinapi no pudo anularlo para volver a comunicarlo. No se ha guardado nada. El campo code dice por qué: en_vuelo (409), el parte está enviado y SES aún no lo ha confirmado, reintenta en una hora; anulacion_fallida (503), SES no aceptó la anulación o no respondió, reintenta más tarde. |
not_ready | 409 | El parte aún no puede enviarse (sin huéspedes, sin firma cuando se exige, o propiedad sin código de establecimiento). O, en GET /exports/{id}/download, la exportación aún se está generando o falló. El motivo va en details. |
not_configured / disabled | 409 | Se pidió probar el webhook pero no hay ninguno configurado, o está desactivado. |
no_billing | 409 | Se pidió el portal de facturación pero la cuenta aún no tiene el pago configurado. |
no_guests | 404 | Se pidió el parte de viajeros de un check-in que todavía no tiene huéspedes. |
no_timestamp | 404 | Se pidió el sello de tiempo de un registro de evidencia que aún no lo tiene. details dice por qué; se reintenta cada hora. |
ses_error | 502 | SES Hospedajes rechazó el envío o no respondió. El detalle va en details. |
link_expired | 410 | Enlace del huésped caducado (rutas públicas /c/…). |
expired | 410 | Se pidió descargar una exportación cuyo ZIP ya se borró (siete días después de estar lista). Pide una nueva con POST /exports. |
Formato del error
Los errores de validación detallan cada campo problemático:
400 Bad Request
{
"error": "validation",
"details": {
"fieldErrors": {
"checkInDate": ["Invalid string: must match pattern"]
}
}
}404 Not Found
{ "error": "not found" }Con la baja de la cuenta pedida, el cuerpo lleva además la fecha en que será definitiva:
403 Forbidden
{
"error": "account_closing",
"details": "La baja de la cuenta está pedida y se hará efectiva el 2026-11-13. Hasta entonces la API solo permite exportar los registros (/exports); para volver a usarla, reactiva la cuenta desde el panel.",
"effectiveAt": "2026-11-13T09:00:00.000Z"
}Reintentos
La creación de check-ins es idempotente: reintentar un POST /checkins con el mismo reservationId devuelve el check-in existente (200) en vez de duplicarlo. Ante un 500 o un timeout, reintenta con backoff exponencial sin miedo.