API Documentation

Use planningWindow and freePeriodPlans when the assigned duties must leave enough protected free-period capacity for weekly rest, fixed free dates, or replacement rest. An employee plan may also contain a conditional A1 comp-time plan. These facts do not create shifts and the solver does not choose visible PF, FO, AD, or A1 markers.

{
  "planningWindow": {
    "start": "2026-01-05T00:00:00+01:00",
    "end": "2026-01-12T00:00:00+01:00",
    "timeZone": "Europe/Copenhagen"
  },
  "freePeriodPlans": [
    {
      "employeeId": 1,
      "boundaryDuties": [
        {
          "id": "approved-duty:10",
          "source": "approved_adjacent_schedule_duty",
          "dutyId": 10,
          "scheduleId": 50,
          "startsAt": "2026-01-04T08:00:00+01:00",
          "endsAt": "2026-01-04T16:00:00+01:00"
        }
      ],
      "fixedPfLocalDates": ["2026-01-12"],
      "weeklyRestWeeks": [
        {
          "weekStart": "2026-01-05",
          "shortMinimumMinutes": 2100,
          "connectedMinimumMinutes": 3300,
          "ineligibleLocalDates": ["2026-01-07"]
        }
      ],
      "fixedDateObligations": [
        {
          "id": "fo-entitlement:20",
          "localDates": ["2026-01-08"],
          "minimumMinutes": 2100
        }
      ],
      "replacementRestObligations": [
        {
          "id": "replacement-rest-obligation:30",
          "windowStart": "2026-01-05T00:00:00+01:00",
          "windowEnd": "2026-01-12T00:00:00+01:00",
          "minimumMinutes": 2100
        }
      ],
      "a1CompTimePlan": {
        "openingBalanceLots": [{"id": 7, "minutes": 180, "expiresOn": "2026-12-31"}],
        "cycles": [{
          "id": "2026-01-05",
          "startsOn": "2026-01-05",
          "endsOn": "2026-02-02",
          "occurrence": {
            "id": "a1-template:9:2026-01-06",
            "templateId": 9,
            "wishId": 12,
            "startsAt": "2026-01-06T07:00:00+01:00",
            "endsAt": "2026-01-06T15:00:00+01:00",
            "requiredMinutes": 480,
            "suppressedByFixedFact": false
          },
          "projectedSundayCredits": [{"shiftId": 31, "minutes": 300, "expiresOn": null}]
        }]
      }
    }
  ]
}

weekStart defines the Monday-Sunday plan week. An interval belongs to the week in which its exact protected interval begins. Its visible dates are normally in that week, but may include the following Monday when the interval began on Sunday. The wider planning window and boundary duties prove interval length; an interval beginning after Sunday cannot satisfy the preceding week. Request edges are definitive when an adjacent authoritative duty is unavailable, including a completely work-free planning window.

One short capacity unit requires shortMinimumMinutes. Two connected units require connectedMinimumMinutes, normally 55 hours, and are capped at 64 hours. Two short periods must be exact and non-overlapping. Every further connected unit requires another 24 hours. The evaluator matches complete weekly bundles and source-backed obligations across the employee; local dates, exact intervals, and connected capacity cannot be reused between weekly rest, FO, and replacement rest.

An A1 cycle pools unexpired opening lots and the projected Sunday credits of shifts assigned anywhere in that cycle. When the pool covers the occurrence's exact duration, A1 becomes hard unavailability and consumes those minutes in expiry order. A suppressed occurrence consumes nothing, excess carries to the next cycle, and at most one occurrence is activated per cycle. Omit the whole a1CompTimePlan to retain legacy behavior. Activated A1 dates and intervals cannot be reused by PF, FO, or replacement rest.

protectedFreePeriodA1Adjacency prefers PF on the immediately preceding or following calendar day without weakening feasibility or coverage. The Gateway enables this at the important score level when an A1 plan is present unless the request explicitly configures another level. a1CompTimeOccurrenceOverlap is the corresponding hard overlap constraint.

fixedPfLocalDates protects PF already established on an approved plan or by an active recurring PF template. It is employee-plan data because a visible Monday PF may belong to the preceding week. fixedDateObligations represents source-backed FO dates. replacementRestObligations represents additional flexible obligations. ineligibleLocalDates excludes absence such as ferie, sygdom, or afspadsering. A weekly rest entry is applicable only when at least two local dates remain eligible. One eligible date cannot provide either two distinct short periods or the two-date connected period, so payload producers must omit that week just as they omit a fully absent week.

When the optional protectedFreePeriodWeekendPattern setting is enabled, the evaluator also prefers a connected Saturday-Sunday rest on a free weekend. On a worked weekend, it prefers two short periods with one before Saturday and one after Sunday. For responsive search, weekly options are penalty-sorted and the quality score uses the first globally feasible allocation found by the existing hard-feasibility search; it does not exhaustively minimize a second allocation. Existing fixed PF dates filter those options, and dates or intervals cannot be reused across PF, FO, or replacement rest. The setting is disabled by default and its priority is independent from weekly work-target deviation.

The response contains the normal score and constraint-match information only. The consuming workforce-management system owns the later designation and publication of exact protected intervals and day markers. Laravel must replay the same A1 funding and allocation after assignment and reject a mismatch.

Gateway v1 is strict. Unknown fields at any nesting level return 422. Retired fields such as freePeriodRequirements, preferredLocalDates, and per-week fixedLocalDates are rejected rather than ignored. The protected-period hard constraint is activated automatically whenever freePeriodPlans is present; only the additional weekend-pattern preference is configurable.