---
title: "Preview upcoming occurrence dates for a recurrence config"
method: POST
path: "/api/v1/schedules/preview"
tags: ["Schedules"]
---

# Preview upcoming occurrence dates for a recurrence config

`POST /api/v1/schedules/preview`

## Request

- Base URL: `https://volunteerreminder.com`
- URL: `https://volunteerreminder.com/api/v1/schedules/preview`
- Auth: HTTP bearer

PURE and side-effect-free: no schedule is read or written. Wraps domain/recurrence.ts + domain/timezone.ts to show the next occurrence dates a recurrence configuration would produce, so an agent can confirm with the human before calling POST /schedules. Requires the `read` scope.

## Request body

- SchedulePreviewRequest
  - `schedule_type` 'weekly' | 'biweekly' | 'monthly_fixed' | 'monthly_nth' | 'bimonthly_fixed' | 'bimonthly_nth' | 'custom', required: Recurrence shape. 'weekly' recurs on one or more days of the week; 'biweekly' is the same weekday mask every 14 days (start_date picks which week — it is not BiMonthly, which is every other MONTH); 'monthly_fixed' / 'bimonthly_fixed' recur on a fixed day of the month; 'monthly_nth' / 'bimonthly_nth' recur on the Nth weekday of the month; the 'bimonthly_*' variants additionally alternate months starting from start_month; 'custom' uses an explicit list of dates.
  - `days_of_week` string[]: Days of the week this recurs on. Required (non-empty) when schedule_type is 'weekly' or 'biweekly'; ignored for every other schedule_type.
  - `nth_weekday` 'sunday' | 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'null', nullable: The weekday that recurs. Used by schedule_type 'monthly_nth' / 'bimonthly_nth'; defaults to Sunday if omitted for those types.
  - `week_of_month` integer: Which occurrence of the weekday in the month (1st through 5th). Used by 'monthly_nth' / 'bimonthly_nth'; defaults to 1.
  - `day_of_month` integer: Fixed day of the month. Used by 'monthly_fixed' / 'bimonthly_fixed'; defaults to 1. Clamped to the last day of shorter months (e.g. 31 in February becomes the 28th/29th).
  - `start_month` integer: Anchor month (1=January .. 12=December) the every-other-month cadence steps from. Used by 'bimonthly_fixed' / 'bimonthly_nth'; defaults to the account's current month.
  - `time` string, nullable: Wall-clock time of day "HH:mm" (24h) in the account's timezone, or null for no specific time (midnight).
  - `start_date` string, nullable: "yyyy-MM-dd" in the account's timezone before which no occurrences materialize, or null for no lower bound. For 'biweekly' this date also picks which week the 14-day rotation lands on (Sunday-week of this day is an on-week). When omitted for biweekly, the server stores the first selected weekday with a shift still ahead (today if it is selected and its start time hasn't passed, else the next selected weekday; the first shift), and the rotation counts from there. On PATCH of an existing biweekly schedule, null keeps the stored date (the rotation only moves when you send a new date).
  - `end_date` string, nullable: "yyyy-MM-dd" in the account's timezone after which occurrence materialization stops, or null for no end date.
  - `custom_dates` string[]: Explicit list of "yyyy-MM-dd" dates. Required (non-empty) when schedule_type is 'custom'; ignored otherwise.
  - `count` integer: How many upcoming occurrences to return (default 8, max 52).

## Response `200`

The computed occurrence dates.

- SchedulePreviewResponse
  - `occurrences` PreviewOccurrence[], required: Up to `count` upcoming occurrence dates for this configuration. Empty when the recurrence shape yields none within the lookahead window.
    - `date` string, required: "yyyy-MM-dd" civil date.
    - `weekday` string, required: Full weekday name.
    - `time` string, nullable, required: Wall-clock "HH:mm", or null.
    - `label` string, required: Human-readable label.
  - `time_zone` string, required: IANA timezone used to compute dates.

## Other responses

- `400`: The request failed schema validation (`validation_error`). On the import endpoints, also when the text is UTF-16 (Excel "Unicode Text"; `unsupported_encoding`): resend it as CSV UTF-8.
- `401`: Missing or invalid API key.
- `403`: The API key lacks a scope required by this endpoint.

---

[API](https://skmtc.dev/volunteerreminder/apis/volunteerreminder-api.md) · [All operations](https://skmtc.dev/volunteerreminder/apis/volunteerreminder-api/llms.txt) · [OpenAPI document](https://skmtc.dev/volunteerreminder/apis/volunteerreminder-api/revisions/f8e7e26ba96f?raw)
