Admin Timeslot Management

Create, update, repeat, and enrich fixed slots in the admin API. This guide is grounded in the current backend JSON contracts and the admin frontend workflows used by the timeslot detail editor.

For general conventions, see JSON-API Conventions. For booking lifecycle effects after a timeslot change, see Booking Lifecycle.


What a Timeslot Represents

A timeslot is a fixed start and end period attached to a resource or service. It can:

  • exist as a one-off slot
  • belong to one or more timeslot series
  • expose cached resource_info for cards and customer-facing summaries
  • use dynamic capacity based on resource allocations
  • have regular bookings linked to it

Core schema references:

  • reference/timeslots.v1.yaml
  • reference/timeslot-series.v1.yaml
  • reference/timeslot-resource-allocations.v1.yaml

Main endpoints:

  • GET /api/v1/timeslots
  • POST /api/v1/timeslots
  • GET /api/v1/timeslots/{record}
  • PATCH /api/v1/timeslots/{record}
  • DELETE /api/v1/timeslots/{record}
  • POST /api/v1/timeslots/preview
  • POST /api/v1/timeslots/{record}/extend

List and Filter Timeslots

Use the collection endpoint for admin calendar and editor views:

GET /api/v1/timeslots?filter[start_date]=2026-06-01T00:00:00Z&filter[end_date]=2026-06-30T23:59:59Z&filter[r]=12&include=resource,series,resource_allocations.resource,model_syncs

Confirmed query parameters:

Parameter Description
include resource, resource.parent, service, series, cover_image, resource_allocations, resource_allocations.resource, resource_allocations.resource.category, resource_allocations.resource.cover_image, model_syncs
sort period, start_date, end_date, created_at
filter[start_date] Return slots ending after this timestamp
filter[end_date] Return slots starting before this timestamp
filter[upcoming_only] Restrict to future slots
filter[past_only] Restrict to past slots
filter[resources] Filter by resource IDs
filter[r] Alias used by the admin calendar
filter[resource_groups] Filter by resource groups
filter[dynamic_capacity] Restrict to dynamic-capacity slots

Resource-scoped reads are also available:

GET /api/v1/resources/{resource_id}/timeslots
GET /api/v1/resources/{resource_id}/timeslot-series

Create a Single Timeslot

POST /api/v1/timeslots
Content-Type: application/vnd.api+json
{
  "data": {
    "type": "timeslots",
    "attributes": {
      "title": "Session 1",
      "title_i18n": {
        "en-us": "Session 1"
      },
      "start_date": "2026-06-08T10:00:00+02:00",
      "end_date": "2026-06-08T11:00:00+02:00",
      "dynamic_capacity": true,
      "base_quota": 0,
      "max_dynamic_quota": 5,
      "min_bookings_count": 2,
      "cancellation_offset_value": 24
    },
    "relationships": {
      "resource": {
        "data": {
          "id": "12",
          "type": "resources"
        }
      },
      "series": {
        "data": [
          {
            "id": "3",
            "type": "timeslot-series"
          }
        ]
      }
    }
  }
}

Common attributes used by the admin UI:

Attribute Notes
title, title_i18n Short display labels
description, description_i18n Optional content
start_date, end_date, timezone Period and editing timezone
quota Effective quota for non-dynamic slots
dynamic_capacity Enables allocation-driven quota
base_quota Static base capacity
max_dynamic_quota Upper quota cap
min_bookings_count Minimum accepted bookings before the slot is confirmed
cancellation_offset_type, cancellation_offset_value Automatic cancellation rules

Preview and Create Recurring Slots

The admin frontend does not blindly create recurring slots. It first previews generated occurrences, then saves one seed timeslot, then extends from that seed.

Preview request:

POST /api/v1/timeslots/preview
Content-Type: application/json
{
  "start_date": "2026-06-08T10:00:00+02:00",
  "end_date": "2026-06-08T11:00:00+02:00",
  "resource_id": "12",
  "timezone": "Europe/Berlin",
  "recurring": {
    "frequency": "weekly",
    "interval": 1,
    "days": [1],
    "count": 4
  }
}

Extend request:

POST /api/v1/timeslots/{record}/extend
Content-Type: application/json

Use the same recurring payload after the first timeslot has been created. The response returns the generated occurrences.

Use series when you need a named grouping for recurring slots. CRUD is available on:

  • GET /api/v1/timeslot-series
  • POST /api/v1/timeslot-series
  • GET /api/v1/timeslot-series/{record}
  • PATCH /api/v1/timeslot-series/{record}
  • DELETE /api/v1/timeslot-series/{record}

Manage Resource Allocations

Dynamic-capacity timeslots can attach secondary resources through timeslot resource allocations.

Endpoints:

  • GET /api/v1/timeslot-resource-allocations
  • POST /api/v1/timeslot-resource-allocations
  • GET /api/v1/timeslot-resource-allocations/{record}
  • PATCH /api/v1/timeslot-resource-allocations/{record}
  • DELETE /api/v1/timeslot-resource-allocations/{record}

Useful fields:

Field Notes
status provisioned or pending
capacity_multiplier Capacity contribution; 0 makes the allocation a required gate
is_required Required resource gate for the slot
is_externally_blocked Indicates external blockers during the slot period
visible_to_customer Controls whether the resource appears in cached resource_info
provisioned_at Timestamp when pending capacity became provisioned
provisioned_by_booking_id Booking that triggered provisioning

List filters include filter[is_required] in addition to status and visibility filters.


Reschedule or Update a Timeslot With Bookings

Updating a slot can affect linked regular bookings. When the period changes, the admin frontend sends extra query parameters on PATCH /api/v1/timeslots/{record}.

Query parameter Purpose
sync_bookings=1 Move exact-period regular bookings with the timeslot
status_reason=... Human-readable reason for the change
send_notification=1 Notify affected customers
lock_invoice=1 Lock invoice state during the reschedule flow

This is the flow used by the reschedule modal in the admin UI.


Retrieve Bookings for a Timeslot

Use the relationship endpoint to populate the Bookings tab:

GET /api/v1/timeslots/{record}/regular-bookings?include=customer&sort=-created_at&page[size]=10

This returns regular bookings currently linked to the slot.


Calendar Events and timeslot_id

Calendar event payloads can be correlated back to timeslot CRUD flows through timeslot_id.

Use this when you need to:

  • open the matching timeslot editor from a calendar event
  • fetch the canonical timeslot resource after a calendar query
  • reconcile resource_info shown in calendar cards with allocation-backed timeslot data

For the aggregate calendar surface, see Booking Calendars.