Laravel Zap logo
Guides

Query & Check

How to get bookable slots, check availability, and retrieve schedules.

Query & Check

This page answers: How do I get bookable slots? How do I check if a time is free? How do I list schedules for a date? For defining when a resource can be booked, see Schedule patterns and Quick start.

I want to…

GoalMethod / API
Know if there is any bookable slot on a date$model->isBookableAt('2025-01-15', 60) or isBookableAt('date', duration, bufferMinutes)
Check if a specific time range is free$model->isBookableAtTime('2025-01-15', '09:00', '10:00', null, 60)
List all bookable slots for a date$model->getBookableSlots('2025-01-15', 60, 15)
Find the next available slot$model->getNextBookableSlot('2025-01-15', 60, 15)
List schedules on a date$model->schedulesForDate('2025-01-15')->get()
List schedules in a date range$model->schedulesForDateRange('2025-01-01', '2025-01-31')->get()
Check for overlapping schedules (conflicts)Zap::findConflicts($schedule) / Zap::hasConflicts($schedule)
Filter by type (appointment, availability, blocked)$model->appointmentSchedules(), availabilitySchedules(), blockedSchedules()
Deprecation:isAvailableAt() is deprecated. Use isBookableAt(), isBookableAtTime(), or getBookableSlots() for all new code.

Check availability (bookable slots)

// Check if there is at least one bookable slot on the day
$isBookable = $doctor->isBookableAt('2025-01-15', 60);

// With buffer between slots (e.g. 15 minutes)
$isBookable = $doctor->isBookableAt('2025-01-15', 60, 15);

// Check if a specific time range is bookable
$isBookable = $doctor->isBookableAtTime('2025-01-15', '09:00', '10:00');

// Get all bookable slots (date, slot duration in minutes, buffer in minutes)
$slots = $doctor->getBookableSlots('2025-01-15', 60, 15);

// Find the next available slot (from date, duration, optional buffer)
$nextSlot = $doctor->getNextBookableSlot('2025-01-15', 60, 15);

Check if a specific time range is bookable

The isBookableAtTime() method checks whether a specific time range is available for booking.

public function isBookableAtTime(
    string $date,
    string $startTime,
    string $endTime,
    ?Collection $schedules = null,
    int $slotDuration = 60
): bool
ParameterTypeDefaultDescription
$datestringrequiredThe date to check (Y-m-d format)
$startTimestringrequiredStart time (H:i format)
$endTimestringrequiredEnd time (H:i format)
$schedulesCollection|nullnullPre-loaded schedules (for performance)
$slotDurationint60Slot granularity in minutes

Usage examples

// Check if 09:00-09:30 is bookable using default 60-minute slots
$user->isBookableAtTime('2025-01-06', '09:00', '09:30');

// Check if 09:30-10:00 is bookable using 30-minute slots
// Useful when your booking system allows finer granularity
$user->isBookableAtTime('2025-01-06', '09:30', '10:00', null, 30);

// With preloaded schedules and custom slot duration
$schedules = $user->schedules()->active()->forDate('2025-01-06')->get();
$user->isBookableAtTime('2025-01-06', '09:30', '10:00', $schedules, 30);

Understanding slot duration

By default, isBookableAtTime() generates 60-minute slots to check availability. If your application allows shorter bookings (e.g., 15 or 30-minute appointments), pass a custom $slotDuration to ensure the requested time range aligns with valid slot boundaries.

For example, with 60-minute slots starting at 09:00, a request for 09:30-10:00 would fail because it doesn't align with slot boundaries. Using $slotDuration = 30 generates 30-minute slots (09:00-09:30, 09:30-10:00, etc.), making the 09:30-10:00 request valid.

Conflicts

$conflicts = Zap::findConflicts($schedule);
$hasConflicts = Zap::hasConflicts($schedule);

Retrieve schedules

// By date or range
$doctor->schedulesForDate('2025-01-15')->get();
$doctor->schedulesForDateRange('2025-01-01', '2025-01-31')->get();

// By type: appointment, availability, blocked
$doctor->appointmentSchedules()->get();
$doctor->availabilitySchedules()->get();
$doctor->blockedSchedules()->get();

Inspect a schedule

$schedule->isAvailability();
$schedule->isAppointment();
$schedule->isBlocked();