Clubs, courts, slots and bookings
A partner website, aggregator or bot can show AISOLUS clubs, free times and prices without authorization, and book on behalf of a player who signed in by SMS.
Public methods: clubs and slots
curl "https://your-server/api/v1/clubs"
# → {"items": [{"id": "c1", "name": "…", "address": "…",
# "courts": 6, "priceFrom": 3500, "hasAI": true, "lat": null, "lon": null}, …]}
curl "https://your-server/api/v1/clubs/c1/courts"
# → {"items": [{"id": "7d1e3b5a-…", "name": "…", "indoor": true, "hasAI": true}, …]}
curl "https://your-server/api/v1/clubs/c1/slots?day=2026-10-03"
# → {"day": "2026-10-03", "items": [
# {"time": "08:00", "free": true, "freeCourts": 2, "price": 2800, "priceLabel": "…"},
# {"time": "09:30", "free": false, "freeCourts": 0, "price": 3500, "priceLabel": ""}, …]}GET /v1/clubs— all clubs: court count, price from, whether courts have AI (hasAI), coordinates if set. Names and addresses are in Russian.GET /v1/clubs/{club_id}/courts— courts; theidlets you book a specific court.GET /v1/clubs/{club_id}/slots— 90-minute slots from club opening to closing. A slot is free if at least one court is free. The price follows the club grid for a regular player;priceLabelis set for happy hours. The personal price (customer category, promo code) applies at booking.
Unknown club — 404 club_not_found, invalid date — 400 bad_day.
Booking on behalf of a player
A booking is always made on behalf of a player and paid from the player's wallet. A partner obtains the player token through SMS sign-in (see Player token) and sends it in Authorization: Bearer. The API has no separate “partner” way to book without a player.
# club rules for this player
curl "https://your-server/api/v1/bookings/rules?club_id=c1" -H "Authorization: Bearer <player token>"
# → {"depthDays": 14, "cancelFreeHours": 24, "maxPerDay": 0, "maxActive": 0, "category": null, …}
# what a promo code gives (books nothing)
curl "https://your-server/api/v1/promo/check?club_id=c1&code=AUTUMN10&day=2026-10-03&at=18:00" \
-H "Authorization: Bearer <player token>"
# → {"code": "AUTUMN10", "price": 3500, "discount": 350, "total": 3150, "note": ""}
# booking
curl -X POST "https://your-server/api/v1/bookings" \
-H "Authorization: Bearer <player token>" -H "Content-Type: application/json" \
-d '{"club_id": "c1", "day": "2026-10-03", "time": "18:00", "promo_code": "AUTUMN10"}'
# → {"id": "b71c2e94-…", "clubId": "c1", "club": "…", "court": "…",
# "day": "2026-10-03", "time": "18:00", "durationMin": 90, "price": 3150, "status": "confirmed"}Booking checks, in order:
| Check | Response on failure |
|---|---|
| The club exists | 404 club_not_found |
| Date and time are well-formed, the time is a club slot start, the slot is not in the past | 400 bad_day_or_time, bad_slot_time, slot_in_past |
| Club rules for this player: booking depth, daily limit, active limit | 409 with error: too_far_ahead, day_limit, active_limit |
A free court (the one in court_id or any) | 409 slot_taken |
| The promo code applies | 4xx with the reason |
| Enough money in the wallet | 402 with {"error": "insufficient_funds", "balance": …, "price": …} |
Two players booking the same court at once — the second gets 409 slot_taken: the cloud never allows two confirmed bookings for one court and slot.
Managing a booking
GET /v1/bookings/my— the player's last 50 bookings with split shares.POST /v1/bookings/{booking_id}/reschedule— move to another slot in the same club; the price difference is charged or refunded.POST /v1/bookings/{booking_id}/cancel— cancel. If the time to start is at least the free-cancellation window (cancelFreeHoursfrom the rules), the price is refunded to the wallet; otherwiserefund: 0.POST /v1/bookings/{booking_id}/split— split the price with 1–3 players; each pays the share viaPOST /v1/bookings/splits/{split_id}/accept, the money goes to the booker. Who to invite —GET /v1/players/recent.POST /v1/bookings/waitlist— queue for a slot where all courts are taken. When a booking is cancelled, the first in the queue is notified.- Rentals:
GET /v1/bookings/rental— what the club has,POST /v1/bookings/{booking_id}/rental— add to a booking,GET /v1/bookings/{booking_id}/rental-pass— QR for the rental desk.
Booking and match video
On a court equipped with AISOLUS, a match played under a booking is linked to it automatically: the court server sees the current booking and its line-up (GET /v1/cv/court-bookings), and the match result is attached to the booking by court and time. Match participants get highlights and the analysis in the match card — see Live scores and replays.