Fivexer

Time off & cover

Time off and urgent cover are related but different workflows.

  • Time off records a request and a decision, normally before publication.
  • Cover handles an absence or no-show against a published roster.

Decide time off with impact visible

ts
const requests = await fivexer.timeOff.list({ status: 'pending' });
const impact = await fivexer.timeOff.impact(requestId);

if (impact.affected.every((roster) => roster.droppedShifts === 0)) {
  await fivexer.timeOff.approve(requestId);
} else {
  await fivexer.timeOff.deny(requestId, { note: 'Discuss alternative dates' });
}

Approved requests constrain future drafts and solves. Pending requests appear in publish preflight. Denied and cancelled requests remain part of the decision record but do not block scheduling.

Report an absence

ts
const cover = await fivexer.rosters.reportCover(rosterId, {
  workerId: 'worker_anna',
  reason: 'sick',
  fromDate: '2026-09-03',
  toDate: '2026-09-04',
  note: 'Reported before day shift',
});

For a no-show on one occurrence, send shiftInstanceId. Otherwise, every assignment for that worker in the date range becomes an opening. The original roster and the absence record remain distinguishable.

Find cover

ts
const result = await fivexer.rosters.coverCandidates(rosterId, cover.id);

Candidates are grouped by operationally useful tiers:

  • home: based at the shift’s own site;
  • nearby: a known journey away;
  • unknown: no travel time was supplied;
  • unplaced: no useful origin is known.

Within each tier, candidates include eligibility, rationale, marginal cost, fairness debt, origin site, travel time, and blockers. unknown never means zero travel; it means the system refuses to invent a journey.

Fill directly or make an offer

Use direct fill when the supervisor has already confirmed the replacement:

ts
await fivexer.rosters.fillCover(rosterId, cover.id, openingId, {
  workerId: 'worker_ben',
});

Use an offer when the worker must choose:

ts
await fivexer.rosters.offerCover(rosterId, cover.id, openingId, {
  workerIds: ['worker_ben', 'worker_cora'],
  expiresInMinutes: 30,
});

The offer snapshots its travel context so later site edits do not rewrite what the worker was asked to accept. Workers can accept or decline through their portal. An accepted offer fills the opening; a decline leaves it open for the next candidate.

Drop an opening only when it no longer needs cover. Cancel the cover request when the absence itself was withdrawn. These are different actions and preserve different histories.

Keep the change small

The cover workflow ranks a replacement against the same constraint set used to build and validate the roster. Untouched shifts stay untouched. This avoids turning one sick call into a completely different month for everybody else.

For location-aware candidate ordering, configure multi-site planning.

Was this page helpful?