Requests

Preview a request (dry run)

Answer what POST /requests would do with this payload without creating anything: the workday duration, its split by fiscal year, whether the member's allowance covers it, the existing requests it would collide with, and a single can_create verdict.

Input: identical to POST /requests, so one payload can be sent to both URLs. reason, representative_member_ids and ignoreRepresentativeRequirement are evaluated exactly as on create.

Duration: duration.workday_absence_duration uses the same days-vs-minutes rule as workday_absence_duration on GET /requests (days for day and half-day leave units, minutes for hour units); preview and created request always agree. For day-based leave types the time of day in start / end is ignored, exactly as on create.

Allowance: is_allowance_sufficient: false means POST /requests with this payload fails with the allowance error; true means it passes that check. Leave types that do not deduct return takes_from_allowance: false, allowance_type: null and is_allowance_sufficient: true.

Conflicts: conflicts lists the member's existing requests that overlap this absence and would block creation. Every leave type counts, including informational ones such as home office; only declined or cancelled requests are ignored.

Rejection: the preview runs the same validations as POST /requests, in the same order, with one difference: an overlapping request is not a rejection but goes to conflicts, so where POST /requests would stop with the overlap error the preview keeps going and may name a later rule in rejection while the overlap sits in conflicts. When a rule fails, the response is still 200 with rejection set instead of a 400, and can_create is false. Match on rejection.code: START_AFTER_END, HALF_DAY_NOT_ALLOWED_FOR_FULL_DAY_LEAVE_TYPE, LEAVE_TYPE_DISABLED (disabled for this member), REASON_REQUIRED, REASON_TOO_LONG, OUTSIDE_FISCAL_YEAR_WINDOW, PAST_DATE_NOT_ALLOWED (manager or self-service retroactive limits), OUTSIDE_EMPLOYMENT_PERIOD, REPRESENTATIVE_CONFLICT (the member is someone else's accepted representative in that period), MAX_ABSENT_REACHED (department limit), NO_APPROVER_SET (the leave type needs approval and the member has no approver), REPRESENTATIVES_INVALID, REQUIRED_REPRESENTATIVES_COUNT_NOT_MET. Permission and scoping failures stay real 403 / 404 responses.

Verdict: can_create is true only when rejection is null, conflicts is empty and the allowance covers the absence. It is the one field to gate a create call on.

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/preview

Request body

startstring required

Start/end of the request in ISO 8601. For day-based leave types (leave_unit: days) send the date at midnight UTC (e.g. 2026-06-01T00:00:00Z) and use start_at / end_at to set half-days. For hour-based leave types include the exact time of day (e.g. 2026-06-01T09:00:00Z); start_at / end_at are then ignored.

endstring required

Start/end of the request in ISO 8601. For day-based leave types (leave_unit: days) send the date at midnight UTC (e.g. 2026-06-01T00:00:00Z) and use start_at / end_at to set half-days. For hour-based leave types include the exact time of day (e.g. 2026-06-01T09:00:00Z); start_at / end_at are then ignored.

start_at'morning' | 'afternoon'

For day-based leave types: whether the absence starts in the morning (the whole first day counts) or afternoon (only the second half of the first day). Ignored for hour-based leave types.

end_at'lunchtime' | 'end_of_day'

For day-based leave types: whether the absence ends at lunchtime (only the first half of the last day) or end_of_day (the whole last day counts). Ignored for hour-based leave types.

leave_type_idstring uuid required
reasonstring
requester_member_idstring uuid required
representative_member_idsstring[]

Member IDs to assign as representatives. Required for leave types that mandate representatives; omitting them returns REQUIRED_REPRESENTATIVES_COUNT_NOT_MET (as a 400 on create, as rejection.code on preview).

ignoreRepresentativeRequirementboolean

Skip the representative requirement. Only honored when the API key's member is an admin and the request is created for another member.

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.

takes_from_allowanceboolean required
is_allowance_sufficientboolean nullable required

True means the allowance covers this payload, false means creating it fails with the allowance error. Always true for leave types that do not deduct. Null when rejection is set: the allowance was not evaluated. conflicts is reported separately and does not affect this flag.

Changes

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