> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# The WFM model: forecasting, scheduling, adherence, and the labor market

> The concept map for workforce management — what planning vs. adherence means, the six domains (forecasts, schedules, assignments, staffing, adherence/timekeeping, labor market + wellness), the request/approval loop, role split, and how scores roll up.

# The WFM model

Workforce management (WFM) answers four questions every contact center asks every day: **how much work is coming in**, **when should each agent work**, **did they do what the schedule said**, and **how do we rebalance when reality drifts from the plan**. Orbit mounts the whole surface under `/api/v1/wfm` as one coherent model — not a grab-bag of endpoints — and this page explains that model once so the operator workflows and API reference stay thin.

WFM splits into two halves. **Planning** is everything that happens before the day: forecast demand, build shift templates, generate schedules, publish assignments. **Adherence measurement** is everything that happens during and after the day: compare what the schedule said against what agents actually did in the ACD (their aux states — online, on a call, on break, in training, logged out) and score the difference. The first half is worthless if the second never runs; the second has nothing to score without the first.

The model is also **two-sided** by design. Managers (owner/admin) build forecasts and schedules, publish coverage, approve or deny submissions, and read the rollups. Agents self-serve: file exception requests, bid on open shifts, claim overtime or voluntary time off, and see the schedule that comes back — scoped to their own records. Every endpoint sits on one of those two sides.

## 1. The six WFM domains

The `/wfm` prefix groups its endpoints into six domains. Each domain answers one question and owns one cluster of endpoints; the domains chain together into the planning → adherence loop.

### Domain 1 — Forecasts: how much work is coming in

Forecasting turns historical traffic into projected demand per channel and interval. The surface:

* `GET/POST /wfm/forecasts` — create and read forecast rows (required agents per channel per interval).
* `POST /wfm/forecasts/recompute` — rebuild a forecast from current history.
* `GET /wfm/forecasts/accuracy` — measure forecast-vs-actual so you know how much to trust the next recompute.
* `POST /wfm/forecasts/what-if` — scenario a demand change before you commit a schedule to it.

A forecast is the input every downstream domain consumes; schedules generated without one are guesswork with timestamps.

### Domain 2 — Schedules and shifts: when each agent should work

A **shift** is a reusable time template; **shift activities** are the segments inside it (work, break, training); a **generated schedule** maps agents onto shift windows for a period. The surface:

* `GET/POST /wfm/shifts`, `GET/PATCH/DELETE /wfm/shifts/:id` — shift template CRUD.
* `GET/POST /wfm/shifts/:shiftId/activities` — the activity segments inside a shift.
* `POST /wfm/schedules/generate` then `POST /wfm/schedules/generate/commit` — draft schedules against a forecast, then publish. The two-step split means generation is a proposal until a manager commits it.

### Domain 3 — Assignments: the published roster

An **assignment** is the committed line that says "agent X works shift Y on date Z." It is the roster entry adherence scoring compares reality against:

* `GET/POST /wfm/assignments`, `GET/PATCH/DELETE /wfm/assignments/:id` — assignment CRUD.
* `POST /wfm/assignments/bulk` — build a full roster in one call (typical after a schedule commit).

### Domain 4 — Staffing and capacity: am I covered, what coverage costs

Given the published roster, staffing answers "do I have enough people, where, and when" — and capacity planning asks the longer-horizon question "how much coverage should the week/month carry, accounting for shrinkage" (time lost to leave, holidays, training, no-shows):

* `GET /wfm/intraday/staffing` — required vs. scheduled agents per interval, today.
* `POST /wfm/staffing/optimize` — the optimization pass that suggests roster changes.
* `GET /wfm/capacity/plan` — capacity against shrinkage-adjusted availability.
* `GET /wfm/shrinkage`, `POST /wfm/shrinkage/recompute` — shrinkage measurement and rebuild.
* `POST /wfm/rebalancing/recommend` and `POST /wfm/rebalancing/apply` — propose coverage fixes, then apply them (extend/trim assignments for the drift the staffing read found).

Holiday calendars sit in this domain: the forecaster and the scheduler both treat holiday dates as reduced-capacity days, so a public-holiday week does not come out over-staffed by accident.

### Domain 5 — Adherence and timekeeping: did the day go as planned

Adherence compares the published assignments against the live agent-state feed from the ACD and scores the divergence; timekeeping records the payable time on agents' timesheets:

* `GET /wfm/adherence/intraday` — today's per-agent adherence score; `GET /wfm/adherence/conformance` — schedule-conformance detail; `GET /wfm/adherence/team` — the team rollup.
* `GET /wfm/rta/stream` — the server-sent-events wallboard supervisors watch live; `GET /wfm/rta/breaches` — the currently-open adherence breaches without a stream.
* `GET /wfm/timesheets` — timekeeping records per agent.

Adherence only reads truth when agents set their aux state (online / break / training / wrap) in the dialer or inbox — the comparison input is the state feed, not login time.

### Domain 6 — Wellness, risk, and the labor market

Two maintenance surfaces keep the roster healthy and keep gaps filled between planning cycles:

* **Wellness and risk** — `GET /wfm/agent-wellness` (burnout/strain indicators from adherence and overtime patterns) and `GET /wfm/agent-flight-risk` (churn-risk scoring per agent). Output feeds into coaching and capacity decisions.
* **The labor market** — the gap-filling surfaces: `/wfm/open-shifts` (publish unowned shifts, agents bid), `/wfm/overtime-offers` (add hours on already-scheduled agents), `/wfm/vto-offers` (release hours on a slow day), `/wfm/leave-policies` + `/wfm/leave-balances` (+ `/adjust`) (leave types and per-agent balances), and `/wfm/agent-skills` (the skill tags the other domains filter coverage by).

## 2. One aggregate read — `GET /wfm/summary`

The WFM dashboard home assembles its top-of-page cards from one request instead of fanning out six: `GET /wfm/summary` returns the day's forecast coverage, staffing totals, pending self-serve requests, open shifts, and pending bids for the tenant's local operating date (or a `date` override). It resolves the same operating date as `/wfm/adherence/intraday` and `/wfm/intraday/staffing`, so the summary cards and their drill-down panels always agree on which calendar day they show.

## 3. The request/approval loop

Every drift between plan and reality converges on the same state machine: **`pending → approved | denied`** (with `cancel` available while still pending). This holds across the whole surface:

* `/wfm/requests` — the agent self-serve queue (time off, swap offers, shift-change requests). An agent files in `pending`; a manager approves or denies; the requester (or a manager) can cancel a still-pending row; an offered swap is accepted with `/accept-swap`.
* `/wfm/adherence-exceptions` — carve-outs that excuse deviation minutes (a system outage, an all-hands meeting). Same loop: pending → approve (deviation excused) | deny (it still counts).
* `/wfm/open-shifts` — publish → agents bid → manager awards one bidder.
* `/wfm/overtime-offers` and `/wfm/vto-offers` — publish → eligible agents claim → manager awards (OT can award several claimants; VTO awards to release hours).

Two rules make the loop safe to automate around: only `pending` rows can be decided (a second decision returns `409`), and every approve/deny/award accepts a note or reason that persists with the row — the audit trail, not an implementation detail.

## 4. Data roles: management vs. self-serve

Role split across the whole prefix is consistent:

| Surface                                                    | Owner/admin              | Agent (non-manager)                |
| ---------------------------------------------------------- | ------------------------ | ---------------------------------- |
| Reads and rollups (`/wfm/summary`, adherence reads, lists) | tenant-wide              | scoped to their own records        |
| Publish (open shifts, overtime, VTO)                       | yes                      | no                                 |
| Decide (approve/deny/award/cancel offers)                  | yes                      | only cancel their own pending rows |
| File (requests, exceptions, bids, claims)                  | yes, on behalf of agents | yes, as themselves                 |
| Schedule/shift/assignment writes                           | yes                      | no                                 |

Non-manager callers listing exceptions, requests, or bids only ever see their own rows — the same scope rule as the rest of the tenant-isolated API. API keys carry `wfm:read` for reporting surfaces and `wfm:read` + `wfm:write` for anything that publishes, awards, approves, or denies.

## 5. How adherence scores roll up — and how exceptions carve minutes out

The scorer walks an agent's scheduled windows for the operating day and compares each interval's expected state from the assignment against the actual aux states the agent reported. The result is a per-agent intraday score plus a **breach** record for each window where reality diverged beyond the allowed threshold — breaches are what `GET /wfm/rta/breaches` lists and what the `/wfm/rta/stream` wallboard pushes live.

Approved **adherence exceptions** rewrite that math. While an exception is approved, its time window is excluded from the deviation base — the minutes stopped being "missed schedule" the moment a manager confirmed the agent was not at fault (a dialer outage is not agent behavior). This is why the exception queue is an operations queue and not just paperwork: approving or denying it directly moves team adherence numbers, and `GET /wfm/adherence-exceptions/trends` exposes that movement grouped by exception type and status.

Team rollups (`GET /wfm/adherence/team`) aggregate the same per-agent scores managers just adjusted, so the team number an executive reads already has approved carve-outs netted out — do not re-adjust on top.

## 6. Where the workflow guide and API reference live

This page is the concept map — plan before you operate. The procedures (file an exception, post an open shift, award a bid, close the loop) live on the [Workforce-management workflows guide](/guides/wfm-workflows), and the full endpoint inventory with request/response shapes lives on the [WFM API reference](/api-reference/wfm). Two sibling concept pages complete the picture of what the schedule adheres to: the [ACD queue model](/concepts/acd-queue-model) (the dispatch state adherence compares against) and [agent presence lifecycle](/concepts/agent-presence-lifecycle) (the aux-state feed adherence consumes).
