NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

Open source

Appointments for Laravel

Install
composer require roundly-consulting/appointments-for-laravel
Requires: PHP ^8.4 · Laravel ^12.0|^13.0

Overview

A scheduling toolkit for Laravel. Create appointments with durations and time zones, attach any Eloquent model as a participant, block double-bookings, move bookings through a guarded status lifecycle, generate recurring series and export standards-compliant .ics calendar files. One Appointments facade covers it all, with the same API injectable as AppointmentManager. It builds on Roundly’s own provider packages for venue geolocation, guest contacts, booking approvals and post-visit reviews — MIT-licensed, with no third-party dependencies beyond Laravel.

What you get

Facade, DI or actions

Book with Appointments::schedule()->startingAt()->lasting()->create(), inject AppointmentManager, or run the actions with typed DTOs.

Any model as a participant

Users, customers, rooms or vehicles join through one polymorphic table — with a role and per-participant meta.

Guarded status lifecycle

Pending → confirmed → completed, plus cancelled, declined and no-show. Illegal moves throw; every change fires an event.

Double-booking protection

Opt in per call or globally: overlapping bookings for any participant throw — even when two arrive at once, thanks to row locks.

Recurring series

Daily, weekly or monthly rules with interval, count, until and weekday filters — created all-or-nothing in one transaction.

Calendar export & a recording fake

RFC 5545 .ics for one booking or a whole feed; Appointments::fake() records every write for assertScheduled() and friends.

Approvals, reviews & venues

Booking sign-off drives the status, post-visit reviews are verified by attendance, venues support radius search.

Documentation

Installation

Install via Composer, publish the publish-only migrations for appointments and its provider packages, then optionally the config.

Configuration

Every config key and its default — models, key type, table names, time zone, duration, conflicts, recurrence, reviews and approvals.

Schema & custom models

The appointments and participants tables, UUID/ULID participant keys, and how to swap in your own Appointment and Participant models.

The Appointments facade

Tour the Appointments facade — the schedule() builder, DTO creates, the for() handle with participants(), availability, ICS feeds and previews.

DI and actions

Inject AppointmentManager instead of the facade, or run the six actions directly — plus the complete facade method → action map.

Typed DTOs

AppointmentData, ParticipantData and RecurrenceData — the typed DTOs behind create(), createRecurring(), the fluent builder and the actions.

Creating appointments

Create appointments with the fluent Appointments::schedule() builder or a typed DTO — every chainable method, the defaults and the terminal calls.

Durations & time zones

How start, end and duration derive from each other, why instants are stored in UTC, and how to read local times.

Participants

Attach any Eloquent model as a participant with a role and meta, list a model’s appointments with HasAppointments, and add or remove people later.

Status lifecycle

The guarded status state machine — transitions, helper methods, labels, colours and the InvalidStatusTransitionException.

Conflict detection

Block double-bookings per call or globally, inspect the clashing appointments, and check availability with Appointments::isAvailable().

Rescheduling

Move an appointment to a new start, keep or change its duration, guard against conflicts and react to AppointmentRescheduled.

Recurring appointments

Daily, weekly or monthly series with interval, count, until and weekday rules — created all-or-nothing and linked by a group UUID.

Querying

Query scopes for upcoming, past, overlapping and per-participant appointments, plus status filters and ordering.

Calendar export (ICS)

Export one appointment or a whole schedule as RFC 5545 .ics text — status mapping, escaping, GEO, ORGANIZER and ATTENDEE lines.

Venue location

Give appointments a venue name and coordinates, measure distance and find appointments within a radius.

Guest contacts

Store booking emails and phone numbers on an appointment and turn them into calendar ORGANIZER and ATTENDEE mailto lines.

Booking approvals

Require sign-off before a booking is confirmed — flat, quorum, staged or preset workflows that drive the appointment status.

Post-visit reviews

Collect post-visit reviews stamped verified for real attendees, plug in your own attendance resolver and read rating summaries.

Events & exceptions

The seven appointment and participant events, their payloads and when they fire, plus every exception the package throws.

Testing

Record every booking write with Appointments::fake() and its assert methods, then use the model factory and example Pest tests for the rest.

Requirements

PHP 8.4+, Laravel 12 or 13, and six Roundly provider packages installed automatically by Composer.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.