Requests

Preview recurring requests (dry run)

Answer what POST /requests/recurring would do with this payload without creating anything: the number of occurrences, the summed workday duration and its split by fiscal year, whether the member's allowance covers the whole series, and the per-occurrence conflicts.

Input: identical to POST /requests/recurring. files is accepted and ignored. reason, admin_approval_option, ignoreMaximumAbsence and representative_member_ids are validated exactly as on create.

Duration: duration.workday_absence_duration follows the same days-vs-minutes rule as workday_absence_duration on GET /requests and is the sum over all occurrences; preview and created series always agree. per_year splits that sum by fiscal year.

Allowance: is_allowance_sufficient is one verdict for the whole series, matching the all-or-nothing behaviour of POST /requests/recurring: false means creating the series fails with the allowance error and leaves nothing behind. Leave types that do not deduct return true.

Conflicts: conflicts lists occurrences overlapping the member's existing requests, department_limit_conflicts the occurrences on which a department's maximum absent limit is already reached, representative_overlaps the occurrences on which the member is someone else's representative (pending or accepted), and representative_unavailable the occurrences on which a passed representative is absent.

Rejection: when the payload would be rejected with 400 by POST /requests/recurring, the response is still 200 with rejection set and can_create: false. Match on rejection.code: neither until nor count given (RECURRENCE_END_REQUIRED), day/month/pos/weekDays not matching repeat (RECURRENCE_RULE_INVALID), a series reaching more than 365 days into the future (RECURRENCE_WINDOW_EXCEEDED), fewer than two occurrences (RECURRENCE_TOO_FEW_OCCURRENCES), an hour-based leave type without a valid start_time/end_time (HOUR_LEAVE_TYPE_REQUIRES_TIME_RANGE), a half_day on a full-day-only leave type (HALF_DAY_NOT_ALLOWED_FOR_FULL_DAY_LEAVE_TYPE), or an occurrence outside the member's employment period (OUTSIDE_EMPLOYMENT_PERIOD). After that the rules the create endpoint applies to every occurrence follow, in its order: a leave type disabled for the member (LEAVE_TYPE_DISABLED), a missing or too long reason (REASON_REQUIRED, REASON_TOO_LONG), an occurrence outside the bookable fiscal-year window (OUTSIDE_FISCAL_YEAR_WINDOW) or too far in the past for the caller's role (PAST_DATE_NOT_ALLOWED), an occurrence on which a non-admin is someone else's accepted representative (REPRESENTATIVE_CONFLICT), a leave type needing approval while the member has no approver (NO_APPROVER_SET), and the representative requirement (REPRESENTATIVES_INVALID, REQUIRED_REPRESENTATIVES_COUNT_NOT_MET). A workspace without the Essentials plan, or a non-admin passing admin_approval_option: approve_request_immediately, gets the same 403 as the create endpoint.

Verdict: can_create is true only when rejection is null, conflicts is empty, department_limit_conflicts is empty (or the caller is an admin passing ignoreMaximumAbsence) and the allowance covers the series. representative_unavailable is informational.

Side effects: no request, approver, notification, webhook or calendar sync entry is created. Safe to repeat; each call evaluates the data as it is at that moment.

post/requests/recurring/preview

Request body

leave_type_idstring uuid required
requester_member_idstring uuid required
reasonstring
repeat'daily' | 'weekly' | 'monthly' required
intervalinteger required
fromstring required

Date/time in ISO 8601 format, e.g. 2026-06-01 (interpreted as UTC midnight) or 2026-06-01T09:00:00Z. Always include a time zone designator (Z for UTC) when sending a time of day. Localized formats such as 01.06.2026 or 06/01/2026 are misinterpreted and must not be used.

untilstring nullable required

Date/time in ISO 8601 format, e.g. 2026-06-01 (interpreted as UTC midnight) or 2026-06-01T09:00:00Z. Always include a time zone designator (Z for UTC) when sending a time of day. Localized formats such as 01.06.2026 or 06/01/2026 are misinterpreted and must not be used.

countinteger nullable required
half_day'full_day' | 'morning' | 'afternoon'
weekDaysstring nullable required
monthinteger nullable required
exDatesstring[]
filesstring[]
representative_member_idsstring[]
ignoreMaximumAbsenceboolean
admin_approval_option'approve_request_immediately' | 'go_through_the_normal_approval_process'

Response

Successful response

can_createboolean required

The one-line verdict: true means POST with this payload passes every rule the create endpoint applies, as of the data at preview time; false means it fails. False whenever rejection is set, a blocking conflict is listed or is_allowance_sufficient is false. Two things the preview cannot see: requests created in between, and changes to the member's approvers that the create call makes when approver sync from Microsoft 365 is on. A snapshot, not a reservation. department_limit_conflicts block unless the caller is an admin passing ignoreMaximumAbsence; representative_unavailable never blocks.

occurrence_countinteger required
takes_from_allowanceboolean required
is_allowance_sufficientboolean nullable required

Verdict for the whole series: true means the allowance covers it, false means creating it fails with the allowance error and leaves nothing behind. Always true for leave types that do not deduct. Null when rejection is set: the allowance was not evaluated. The conflict arrays are reported separately and do not affect this flag.

Changes

Changed in 1 of the 13 revisions of this API.1