Skip to content

API Guide

This page is a map of Slotify's public API. For exact signatures, the installed package version is the source of truth.

SlotGenerator

Creates timezone-aware slots from scheduling rules.

generate()
generate_for_date()
upcoming()

Configuration includes:

start / end
windows
schedule
duration
interval
timezone
weekdays
breaks
excluded_dates
dst_ambiguous
dst_nonexistent

Schedule

Defines recurring availability and exceptions.

weekly
overrides
closed_dates
annual_closed_dates

Slot

Represents an appointment interval.

start
end
duration
start_utc
end_utc
overlaps()
contains()
in_timezone()
to_dict()

AvailabilityEngine

Adds availability and booking behavior.

available_slots()
upcoming_available()
reserve()
reserve_first_available()
reserve_recurring()
cancel()
reschedule()
capacity
buffers
booking policies
resource_id
resource_ids

Booking

Represents a reservation and its protected time interval.

Additional v0.2.0 fields include:

resource_ids
series_id
rescheduled_count

Useful methods include:

cancel()
reschedule()
to_dict()
to_ics()

RecurrenceRule

Defines weekly recurring appointment series with weekdays, interval, count, or an end date.

RecurrenceRule(weekdays=(0, 2), count=6, interval=1)

count and until are mutually exclusive.

BookingPolicy

Defines booking restrictions such as:

  • minimum notice
  • maximum booking horizon
  • blocked periods

BookingStore

The storage abstraction used by the booking layer.

Slotify includes:

BookingStore
InMemoryBookingStore

Use the in-memory implementation for tests and simple single-process applications.

For multi-process/distributed production systems, provide durable transactional storage appropriate to your application.

Exceptions

The package exposes scheduling and booking exceptions including:

SlotifyError
ConfigurationError
InvalidTimeError
InvalidDateRangeError
InvalidTimezoneError
DSTTransitionError
SlotConflictError
SlotUnavailableError
BookingConflictError
BookingNotFoundError

iCalendar export

ics_text = booking.to_ics(summary="Doctor Appointment")

Exports a single booking as an iCalendar event without a runtime dependency.

Timezone helpers

get_timezone()
to_utc()
convert_timezone()
resolve_local_datetime()

Public imports

from slotify import (
    AvailabilityEngine,
    Booking,
    BookingPolicy,
    BookingStore,
    InMemoryBookingStore,
    RecurrenceRule,
    Schedule,
    Slot,
    SlotGenerator,
    TimeWindow,
)

v0.3.0 availability APIs

AvailabilityResult

check_availability() returns a structured result:

result = engine.check_availability(slot)

result.slot
result.available
result.reason
result.resource_id

This is useful when an application needs to explain why a slot cannot be booked.

Resource pools

Use resource_pool when an appointment can be handled by any one resource:

AvailabilityEngine(
    generator,
    resource_pool=("doctor-1", "doctor-2", "doctor-3"),
)

The selected resource is stored on the resulting Booking. resource_pool cannot be combined with resource_id or resource_ids.

Named schedules

Multiple SlotGenerator profiles can be configured:

AvailabilityEngine.from_schedules(
    {
        "default": default_generator,
        "evening": evening_generator,
    },
    default_schedule="default",
)

Select one per query with schedule_name. All profiles on one engine must use the same timezone.

Availability queries

engine.next_available(start_date, end_date=None, now=None, schedule_name=None)
engine.available_between(start_datetime, end_datetime, now=None, schedule_name=None, limit=None)
engine.available_for_duration(duration, start_date, end_date=None, now=None, schedule_name=None, limit=None)

available_between() requires timezone-aware datetimes and only returns slots fully contained in the requested interval.

available_for_duration() generates slots using the requested appointment duration while retaining the configured schedule, interval, timezone, breaks, exclusions, and DST behavior.

available_slots() and upcoming_available() also accept schedule_name and limit.

Booking limits

BookingPolicy additionally supports:

BookingPolicy(
    max_bookings_per_day=3,
    max_bookings_per_week=10,
    max_upcoming_bookings=5,
    min_gap_between_bookings=timedelta(minutes=15),
)

These limits are evaluated against confirmed bookings visible through the configured BookingStore.

RecurrenceRule v0.3.0

RecurrenceRule supports daily, weekly, monthly, and yearly recurrence.

RecurrenceRule(
    frequency="monthly",
    day_of_month=15,
    count=6,
)

Skip specific dates:

RecurrenceRule(
    frequency="weekly",
    weekdays=(0,),
    count=12,
    excluded_dates=("2026-11-02",),
)

weekdays is valid for weekly recurrence. day_of_month is used for monthly/yearly recurrence. When a monthly day does not exist in a month, the last valid day of that month is used. count counts emitted occurrences, so excluded dates do not consume the count.

v0.5.0 external busy periods

Use BusyPeriod for conflicts supplied by another calendar or application:

from slotify import BookingPolicy, BusyPeriod

policy = BookingPolicy(
    busy_periods=(
        BusyPeriod(
            start=calendar_start,
            end=calendar_end,
            reason="External calendar event",
        ),
    ),
)

Busy periods are evaluated alongside Slotify's own booking rules.

v0.5.0 availability diagnostics

AvailabilityResult includes a machine-readable code in addition to the human-readable reason.

Common codes include:

available
policy
hold_conflict
capacity_conflict
resource_unavailable

v0.5.0 idempotent reservations

Pass an idempotency key when an API request may be retried:

booking = engine.reserve(
    slot,
    idempotency_key="payment-attempt-123",
)

A store should enforce idempotency atomically in production.

v0.4.0 holds

Temporary checkout holds are represented by BookingHold.

from datetime import datetime

hold = engine.hold(
    slot,
    expires_at=datetime.fromisoformat("2026-10-05T09:10:00+05:30"),
)

booking = engine.confirm_hold(hold.hold_id)

The public hold storage API includes HoldStore and InMemoryHoldStore.

BookingHold
HoldStore
InMemoryHoldStore
HoldExpiredError
HoldNotFoundError

v0.4.0 resource strategies

Resource pools accept resource_strategy:

AvailabilityEngine(
    generator,
    resource_pool=("doctor-1", "doctor-2", "doctor-3"),
    resource_strategy="least_loaded",
)

Supported values:

first_available
round_robin
least_loaded