API de Kai Manager
Referencia

Self-management · Reservas

Consultá horarios disponibles y creá reservas de tus espacios (canchas, salones…) con la misma configuración de Self-management → Plataforma → Reservas: espacios habilitados, duración de turno, días de anticipación, turnos seguidos, precios especiales y formas de pago.

Flujo típico: 1) traé las opciones (sedes y espacios) → 2) consultá la disponibilidad de un espacio → 3) creá la reserva → 4) si hay que pagar, mandá a la persona al paymentUrl y después consultá el estado.

Permisos del rol de la clave: API · Reservas → Consultar para los GET y Crear reservas para el POST. Fechas en YYYY-MM-DD y horas en HH:mm, en la zona horaria de la cuenta (timeZone).

1. Opciones de reserva

GET/api/v1/external/self-management/reservations/options

Reglas, sedes y espacios habilitados para reservar online.

Request
curl https://el-sistema-backend.fly.dev/api/v1/external/self-management/reservations/options \
  -H "X-Api-Key: $KAI_API_KEY"
Respuesta 200
{
  "timeZone": "America/Argentina/Buenos_Aires",
  "today": "2026-10-01",
  "lastBookableDate": "2026-10-15",
  "bookingRules": {
    "slotDurationMinutes": 60,
    "maxDaysInFuture": 14,
    "maxConsecutiveSlots": 2,
    "allowedPaymentOptions": ["no_deposit", "deposit", "full_payment"],
    "allowClientCancellation": true,
    "cancellationHoursBefore": 24,
    "cancellationText": "Podés cancelar hasta 24 h antes."
  },
  "locations": [
    { "id": "6a0f…", "name": "Sede Centro", "address": "Av. Siempre Viva 123" }
  ],
  "spaces": [
    {
      "id": "c21d…", "locationId": "6a0f…", "name": "Cancha 1", "type": "padel",
      "price": "20000", "promotionalPrice": null, "deposit": "5000",
      "scheduleOpen": "08:00", "scheduleClose": "23:00"
    }
  ]
}

2. Horarios disponibles

GET/api/v1/external/self-management/reservations/availability
ParámetroDescripción
spaceIdId del espacio (de options).
startDateDesde (YYYY-MM-DD). Si es anterior a hoy, arranca hoy.
endDateHasta (YYYY-MM-DD). Máximo 31 días por consulta; se corta en lastBookableDate.
Request
curl "https://el-sistema-backend.fly.dev/api/v1/external/self-management/reservations/availability?spaceId=c21d…&startDate=2026-10-01&endDate=2026-10-02" \
  -H "X-Api-Key: $KAI_API_KEY"
Respuesta 200
{
  "space": { "id": "c21d…", "locationId": "6a0f…", "name": "Cancha 1", "type": "padel" },
  "days": [
    {
      "date": "2026-10-01",
      "availableSlots": 9,
      "slots": [
        {
          "startTime": "18:00", "endTime": "19:00", "available": true,
          "priceTotal": 20000, "originalPriceTotal": 20000, "promotionalTotal": null,
          "specialPriceApplied": false, "durationMinutes": 60
        }
      ]
    }
  ]
}

Si en la Plataforma elegiste no mostrar turnos ocupados, solo vienen los libres; si no, vienen todos con available: false en los ocupados.

3. Crear una reserva

POST/api/v1/external/self-management/reservations

Para reservar varios turnos seguidos, mandá el startTime del primero y el endTime del último (hasta maxConsecutiveSlots). El cliente se busca por email; si no existe se crea, y nunca se pisan sus datos.

CampoDescripción
locationId, spaceIdSede y espacio (el espacio tiene que ser de esa sede).
date, startTime, endTimeTurno(s) a reservar, tal como vienen en la disponibilidad.
paymentOptionno_deposit (paga en el lugar), deposit (seña) o full_payment. Tiene que estar en allowedPaymentOptions.
customername, lastName, phone (mín. 6 caracteres) y email. Todos obligatorios.
paymentReturnUrlOpcional. URL https a la que Mercado Pago devuelve a la persona. Se le agregan payment (success / failure / pending) y attemptId. Sin este campo vuelve a tu Plataforma.
Request
curl -X POST https://el-sistema-backend.fly.dev/api/v1/external/self-management/reservations \
  -H "X-Api-Key: $KAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "locationId": "6a0f…",
    "spaceId": "c21d…",
    "date": "2026-10-01",
    "startTime": "18:00",
    "endTime": "20:00",
    "paymentOption": "deposit",
    "customer": {
      "name": "Ana",
      "lastName": "Pérez",
      "phone": "+5491122334455",
      "email": "ana@example.com"
    },
    "paymentReturnUrl": "https://miclub.com/reserva-finalizada"
  }'

Hay dos respuestas posibles (ambas 201):

Sin pago online → confirmada
{ "status": "confirmed", "attemptId": "e7a2…", "reservationId": "51bc…" }
Con seña o pago total → falta pagar
{ "status": "payment_pending", "attemptId": "e7a2…", "paymentUrl": "https://www.mercadopago.com.ar/checkout/…" }

Con payment_pending el turno queda retenido unos minutos (hasta 5). Si el pago no se aprueba a tiempo, se libera. La confirmación llega sola cuando Mercado Pago aprueba el pago; la persona recibe el mail de confirmación igual que desde la Plataforma. Si el horario se ocupó mientras tanto, responde 409.

4. Estado de una reserva

GET/api/v1/external/self-management/reservations/{attemptId}
Request
curl https://el-sistema-backend.fly.dev/api/v1/external/self-management/reservations/e7a2… \
  -H "X-Api-Key: $KAI_API_KEY"
Respuesta 200
{
  "id": "e7a2…",
  "status": "confirmed",
  "paymentOption": "deposit",
  "paymentStatus": "partial",
  "reservationId": "51bc…",
  "locationId": "6a0f…",
  "spaceId": "c21d…",
  "date": "2026-10-01",
  "startTime": "18:00",
  "endTime": "20:00",
  "priceTotal": 40000,
  "amountToPay": 5000,
  "amountPaid": 5000,
  "amountPending": 35000,
  "expiresAt": "2026-10-01T14:05:00.000Z",
  "confirmedAt": "2026-10-01T14:02:31.000Z",
  "createdAt": "2026-10-01T14:00:00.000Z"
}

status: payment_pending (esperando pago), confirmed (reserva creada en el calendario), expired (venció la retención sin pago) o cancelled.

Las reservas creadas por API aparecen en el Calendario como las de la Plataforma y quedan en Self-management → Registro de acciones con canal api. Las alertas de reserva online también se disparan.