Courts
Base path: /api/venues/{venue}/courts and /api/courts/{court}/...
Courts belong to a Venue. Customers need court details, availability, and pricing before booking.
Endpoints
GET /api/venues/{venue}/courts
List all active courts for a venue.
Auth: Not required
Path parameter: venue — venue ID (integer)
Response 200:
{
"data": [
{
"id": 1,
"venue_id": 1,
"name": "Court A",
"type": "cricket",
"sport": { "id": 5, "name": "Cricket", "slug": "cricket", "key": "cricket", "label": "Cricket" },
"price_per_hour": "2500.00",
"starting_price": 2500,
"description": "5-a-side synthetic turf",
"capacity": 10,
"is_active": true,
"images": [],
"schedules": [],
"pricing": [],
"created_at": "2025-01-01 10:00:00"
}
]
}GET /api/courts/{court}/availability
Check available time slots for a court on a given date.
Auth: Not required
Path parameter: court — court ID
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
date | date | Yes | YYYY-MM-DD — must be today or future |
Response 200:
{
"date": "2025-06-15",
"slot_minutes": 60,
"is_closed": false,
"open_time": "06:00",
"close_time": "22:00",
"slots": [
{
"start_time": "06:00",
"end_time": "07:00",
"is_available": true,
"price_per_hour": "800.00"
},
{
"start_time": "07:00",
"end_time": "08:00",
"is_available": false,
"price_per_hour": "800.00"
}
]
}Use this to render the time-slot picker in your booking flow. Only offer
is_available: trueslots for selection.
Slot length comes from the court's
slot_minutes(15/30/45/60/90/120, default 60).
If
is_closedis true (weekly off day),slotsis empty — do not allow booking that day.
Booking create also rejects closed days, outside hours, maintenance overlap, and already-booked overlaps with HTTP 409.
GET /api/courts/{court}/pricing
Get pricing rules for a court (used to show rate cards).
Auth: Not required
Response 200:
{
"data": [
{
"id": 1,
"type": "standard",
"day_of_week": null,
"start_time": "06:00:00",
"end_time": "18:00:00",
"price_per_hour": "800.00",
"is_active": true
},
{
"id": 2,
"type": "peak",
"day_of_week": 6,
"start_time": "18:00:00",
"end_time": "22:00:00",
"price_per_hour": "1200.00",
"is_active": true
}
]
}Pricing rule types:
standard— regular ratepeak— higher rate (evenings / weekends)off_peak— discounted rateholiday— applied on holidays
day_of_week: 0 = Sunday, 1 = Monday, ... 6 = Saturday. null = applies every day.
GET /api/courts/{court}/schedule
Get operating hours per day for a court.
Auth: Not required
Response 200:
{
"data": [
{
"id": 1,
"day_of_week": 0,
"day_name": "Sunday",
"open_time": "06:00:00",
"close_time": "22:00:00",
"is_closed": false
},
{
"id": 7,
"day_of_week": 6,
"day_name": "Saturday",
"open_time": "06:00:00",
"close_time": "22:00:00",
"is_closed": false
}
]
}CourtResource — Field Reference
| Field | Type | Notes |
|---|---|---|
id | integer | |
venue_id | integer | |
name | string | e.g. "Court A" |
type | string | e.g. "futsal", "basketball" |
description | string or null | |
capacity | integer | Max players per team (both teams combined) |
is_active | boolean | Only show active courts |
images | array | When loaded |
schedules | array | When loaded — daily open/close times |
pricing | array | When loaded — pricing rules |
created_at | datetime string |
Booking Flow — Court Selection
1. GET /api/venues/{slug} → pick a court
2. GET /api/courts/{court}/availability?date=YYYY-MM-DD → show slots
3. GET /api/courts/{court}/pricing → display rate card (optional)
4. POST /api/bookings → create the booking