Antes de crear una reserva necesitas saber qué espacios existen, cuándo están libres y cuánto cuestan. Tres endpoints de solo lectura lo resuelven.
Listar espacios
Requiere spaces:read. Devuelve los espacios activos del club a los que la credencial tiene acceso, ordenados por sort_order y luego por id, con paginación por cursor.
curl -s "$PRANARP_URL/api/v1/spaces?limit=50" \
-H "Authorization: Bearer $PCK_TOKEN"
{
"data": [
{
"id": 7,
"name": "Pista 1",
"code": "P1",
"sport": "padel",
"space_type": { "slug": "padel-court", "name": "Pista de pádel" },
"indoor": false,
"surface": "cristal",
"min_players": 2,
"max_players": 4,
"booking_step_minutes": 30,
"min_booking_minutes": 60,
"max_booking_minutes": 120,
"parent_id": null
}
],
"meta": { "next_cursor": null }
}
GET /spaces/{id} devuelve un solo espacio. Los espacios inactivos o eliminados responden 404 not_found, y uno fuera de los permitidos de la credencial responde 403 space_not_allowed.
Los campos booking_step_minutes, min_booking_minutes y max_booking_minutes marcan las reglas de duración que se aplican al reservar: la hora de inicio y la duración deben respetar el paso, y la duración debe estar entre el mínimo y el máximo.
Consultar disponibilidad
Requiere availability:read. Devuelve los tramos libres de un espacio dentro de [from, to), ya fusionados y con el desfase horario del club.
curl -s -G "$PRANARP_URL/api/v1/availability" \
-H "Authorization: Bearer $PCK_TOKEN" \
--data-urlencode "space_id=7" \
--data-urlencode "from=2026-10-22T08:00:00+02:00" \
--data-urlencode "to=2026-10-22T22:00:00+02:00"
{
"data": {
"space_id": 7,
"timezone": "Europe/Madrid",
"slots": [
{ "starts_at": "2026-10-22T09:00:00+02:00", "ends_at": "2026-10-22T11:30:00+02:00" },
{ "starts_at": "2026-10-22T16:00:00+02:00", "ends_at": "2026-10-22T22:00:00+02:00" }
]
}
}
Qué tiene en cuenta el cálculo y qué debes saber:
- Se aplican los horarios de apertura, los descansos, las excepciones, las reservas existentes y los bloqueos.
- El rango máximo es de 14 días; si lo superas, recibes
422 validation_failed. - Lo que ya ha pasado nunca se ofrece: el instante actual se redondea hacia arriba al siguiente múltiplo de
booking_step_minutes(contado desde la medianoche local). - Los tramos más cortos que la reserva mínima del espacio (
min_booking_minutes, o el valor por defecto del club) se descartan. - Un tramo libre es un rango continuo, no una lista de reservas posibles: tú eliges dentro de él un inicio y una duración válidos.
fromytoson ISO 8601 estricto; sin desfase se interpretan en la zona horaria del club. Más detalles en Fechas y zonas horarias.
La disponibilidad es una foto del momento. Aunque un tramo aparezca libre, otra reserva puede ocuparlo antes que la tuya: al crear la reserva recibirás 409 slot_unavailable si ha ocurrido.
Pedir un presupuesto
Requiere spaces:read. Calcula el precio de usar un espacio entre dos instantes con la tarifa de no socio, sin crear nada. Los importes son enteros en céntimos.
curl -s -G "$PRANARP_URL/api/v1/quote" \
-H "Authorization: Bearer $PCK_TOKEN" \
--data-urlencode "space_id=7" \
--data-urlencode "starts_at=2026-10-22T18:00:00+02:00" \
--data-urlencode "ends_at=2026-10-22T19:30:00+02:00"
{
"data": {
"space_id": 7,
"starts_at": "2026-10-22T18:00:00+02:00",
"ends_at": "2026-10-22T19:30:00+02:00",
"minutes": 90,
"total_amount_cents": 3600,
"currency": "EUR",
"priced": true,
"reason": null,
"segments": [
{ "starts_at": "2026-10-22T18:00:00+02:00", "ends_at": "2026-10-22T19:30:00+02:00", "minutes": 90, "price_unit": "hour", "amount_cents": 3600 }
]
}
}
Si no se puede calcular un precio, la respuesta sigue siendo 200, con total_amount_cents: 0, priced: false y un reason:
reason |
Significado |
|---|---|
pricing_disabled |
El club no tiene activada la función de tarifas. |
no_price |
El espacio no tiene precio para ese tramo. |
multi_day_not_supported |
El rango cruza la medianoche. Solo se admite un ends_at exactamente a las 00:00 del día siguiente (por ejemplo, de 22:00 a 00:00). |
Los espacios inactivos, en mantenimiento, eliminados o de otro club responden 404.
De la disponibilidad a la reserva
Cuando hayas elegido un tramo, crea la reserva con POST /bookings, tal y como se describe en la referencia. Envía siempre una cabecera Idempotency-Key para poder reintentar sin duplicar.