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

Guest bookings often have no user account behind them. Store the booking’s email and phone directly on the appointment — contacts-for-laravel is wired into the bundled model:

use RoundlyConsulting\Appointments\Facades\Appointments;

$appointment = Appointments::schedule('Guest booking')
    ->startingAt('2026-07-01 09:00')
    ->withContactEmail('[email protected]')
    ->withContactPhone('+441234567890')
    ->create();

$appointment->primaryEmail()?->value;          // "[email protected]"
$appointment->primaryPhone()?->value;          // "+441234567890"

withContactEmail() and withContactPhone() take the value, an optional label and a primary flag that defaults to true.

Contacts on an existing appointment

use RoundlyConsulting\Contacts\Enums\ContactType;

$appointment->addEmail('[email protected]');                  // not primary by default
$appointment->addPhone('+441234567891', 'Reception', primary: true);
$appointment->contactsOfType(ContactType::Email);             // every email contact
$appointment->contacts;                                       // all contacts (MorphMany)

Calendar addresses

The appointment’s primary email becomes the calendar ORGANIZER, named after the contact’s name or, failing that, its label:

Appointments::schedule('Clinic visit')
    ->startingAt('2026-07-01 09:00')
    ->withContactEmail('[email protected]', 'Front desk')   // ORGANIZER;CN=Front desk:mailto:[email protected]
    ->withParticipant($patient)
    ->create();

Participants are exported as ATTENDEE lines when their own model has a primary email — add HasContacts to your participant models:

use Illuminate\Database\Eloquent\Model;
use RoundlyConsulting\Appointments\Concerns\HasAppointments;
use RoundlyConsulting\Contacts\Concerns\HasContacts;

class Patient extends Model
{
    use HasAppointments;
    use HasContacts;
}

$patient->addEmail('[email protected]', primary: true);
// exported as ATTENDEE;CN=<the patient's name attribute>:mailto:[email protected]

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.