---
title: "Configuration — Appointments for Laravel | Roundly"
description: "Every config key and its default — models, key type, table names, time zone, duration, conflicts, recurrence, reviews and approvals."
url: https://roundly-consulting.com/open-source/docs/appointments-for-laravel/configuration
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Appointments for Laravel](https://roundly-consulting.com/open-source/docs/appointments-for-laravel.md)

# Configuration

The published config/appointments.php in full:

```php
use RoundlyConsulting\Appointments\Models\Appointment;
use RoundlyConsulting\Appointments\Models\Participant;
use RoundlyConsulting\Appointments\Reviews\DatabaseVerifiedAttendanceResolver;

return [
    'model' => Appointment::class,
    'participant' => Participant::class,

    // bigint | uuid | ulid — the key type of the polymorphic participant column
    'key_type' => env('APPOINTMENTS_KEY_TYPE', 'bigint'),

    'table_names' => [
        'appointments' => 'appointments',
        'participants' => 'appointment_participants',
    ],

    'timezone' => null,
    'default_duration_minutes' => 60,
    'prevent_conflicts' => false,

    'recurrence' => [
        'max_occurrences' => 365,
    ],

    'reviews' => [
        'verified_attendance_resolver' => DatabaseVerifiedAttendanceResolver::class,
        'require_verified_attendance' => false,
    ],

    'approvals' => [
        'enforce_transitions' => false,
    ],
];
```

## Every key

| Key | Default | Purpose |
| --- | --- | --- |
| `model` | Appointment::class | Appointment model. Point it at a subclass of the packaged model to customise behaviour; any other class throws InvalidConfigurationException. |
| `participant` | Participant::class | Participant model; same rules as model. |
| `key_type` | bigint | Key type of the polymorphic participant\_id column — bigint, uuid or ulid (env APPOINTMENTS\_KEY\_TYPE). Set before you migrate; any other value throws InvalidConfigurationException when the migrations run. |
| `table_names.appointments` | appointments | Table the migrations create and the Appointment model reads and writes. Set it before you migrate. Blank = not set (appointments); any other value must be a string. |
| `table_names.participants` | appointment\_participants | Table the migrations create and the Participant model reads and writes. Set it before you migrate. Blank = not set (appointment\_participants); any other value must be a string. |
| `timezone` | null | Zone stored on a new appointment when none is given, and the zone a wall-clock string without an offset is read in; not set (null or blank) uses config('app.timezone'), anything else must be a timezone PHP knows (Europe/Bratislava). Each appointment keeps the zone it was booked in, so changing this later doesn’t re-time existing ones. |
| `default_duration_minutes` | 60 | Duration applied when neither a duration nor an end time is given; ends\_at is derived from it. 1–525600. |
| `prevent_conflicts` | false | When true, creating, rescheduling or adding a participant throws on an overlapping booking for a participant. Can also be enabled per call. |
| `recurrence.max_occurrences` | 365 | Hard cap on the number of occurrences one recurring series may expand to, 1–100000. |
| `reviews.verified_attendance_resolver` | DatabaseVerifiedAttendanceResolver::class | Decides whether a review is verified (default: the author is a participant of a completed appointment). Must implement VerifiedAttendanceResolver. Not set (left out, null or blank) still binds DatabaseVerifiedAttendanceResolver; to never verify, name NullVerifiedAttendanceResolver::class explicitly. |
| `reviews.require_verified_attendance` | false | When true, review() throws for an unverified author instead of storing an unverified review. |
| `approvals.enforce_transitions` | false | When true, the approval status-sync listener respects the transition matrix — a mapped but illegal move is skipped. |

The bool keys also take env-style strings — true/1/on/yes and false/0/off/no — and the int keys take integer strings ('45'). A key that is not set (absent, null, or blank: '' or whitespace) takes its default. Anything else — a mistyped switch ('disabled'), a duration or cap that isn’t a whole number in range ('an hour', 0), a non-string table name, an unknown timezone, a resolver that isn’t a VerifiedAttendanceResolver — throws InvalidConfigurationException naming the key instead of quietly reading as a default.

## Environment

Only the participant key type is env-backed. It types a database column, so set it before you publish and run the migrations:

```bash
# bigint | uuid | ulid — set before you publish and run the migrations
APPOINTMENTS_KEY_TYPE=bigint
```

## The about command

php artisan about --only=appointments reports the effective setup:

- Model and Participant model — the short class names of the resolved models.
- Appointments table and Participants table — the configured table names.
- Default timezone — SET or APP DEFAULT. Only presence is reported, never the value.
- Default duration — e.g. 60 min — and Max occurrences, the recurrence cap.
- Prevent conflicts, Require verified attendance and Approval transitions — ON or OFF.
- Attendance resolver — the class name of the bound review resolver.

A malformed table name, timezone, default duration, occurrence cap or resolver shows as INVALID, so about still renders on a misconfigured host while the real read path throws.

## 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](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## 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.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/appointments-for-laravel.md)
