Skip to main content
Stay updated with the latest enhancements, features, and improvements to the Solvice Fill API. Each release brings new capabilities to help you assign employees to shifts while respecting skills, availability, and labor rules.
Explainability parity: unserved reasons and typed constraints

🔍 Why Was This Shift Left Unassigned?

The response now includes unservedReasons: for every unassigned shift, the specific hard constraints that blocked assignment.

🏷️ Typed Constraint Vocabulary

Constraints in unresolved and alternative violations are now returned as a typed FillConstraint value instead of a free-text name, and each FillConflict can include a human-readable description and a relation (e.g. the other shift involved in a minimum-rest conflict). Note that FillConflict.constraint (in conflicts) remains a free-text string.

🎯 Scope Alternatives to Unassigned Shifts

A new options.explanation.onlyUnassigned flag limits alternative-assignment computation to shifts that ended up unassigned, reducing explanation cost on large requests.

🛡️ More Accurate Explanations

Fixed a bug where, when multiple shifts were simultaneously unfillable, unrelated constraint violations from other shifts could leak into a given shift’s or candidate employee’s explanation.
Declarative rule engine with per-rule weights

📋 Declarative Rule Engine

The Fill solver now ships a full declarative rule engine. Counter rules, sequence rules, rest rules, and shift patterns are all enforced together and can each be tuned independently through the top-level weights object.

New MAX_CONSECUTIVE_DAYS rule type

A new rule type bounds the longest run of consecutive working days directly. Pair it with a COUNTER constraint and a max: the solver finds the longest consecutive-day streak and penalizes anything above the limit.
The full set of rule types is now: HOURS_WORKED, DAYS_WORKED, DAYS_IDLE, WEEKENDS_WORKED, WEEKENDS_IDLE, SHIFT_TYPES_WORKED, SHIFT_TYPES_HOURS_WORKED, and MAX_CONSECUTIVE_DAYS.

Per-rule-type weights

Every rule family now has its own weight, so you can decide exactly how hard the solver pushes on each one. Set them under the request’s top-level weights object, using the <weight><priority> format where priority is hard, medium, or soft.
Weights for COUNTER rules — how strongly to respect counts over a period.

Conditional rules and fixed-length windows

Rules can chain with then to trigger a follow-up rule when a threshold is crossed, and a period.duration tiles any rule into fixed-length, non-overlapping windows across the planning horizon (not a sliding/rolling window — align duration to your horizon’s start date for a clean weekly/monthly cap).
Learn more:
Reliability and scoring fixes

🛡️ Employee Reference Validation

Requests that reference an employee that does not exist — in a shift’s employees list or its blocklist — are now validated up front instead of failing deep inside the solver. This produces clearer errors and prevents silent mis-assignments.
Every name used in a shift’s employees list or blocklist must match a name declared in the top-level employees list. Unknown references are rejected during validation with a clear error message.

💶 Wage Costs Scoring Fix

The Wage Costs constraint could produce a negative match weight in some configurations, distorting the soft score. Match weights are now clamped so wage-based optimization behaves as expected.
Assignment control and API hardening

🎚️ Control Solve Time with millis

The solve endpoint accepts a new millis query parameter to cap how long the solver runs, giving you direct control over the latency/quality trade-off.

🔢 max Drives Shift Assignment Count

The number of assignments generated for a shift is now taken from the shift max field, falling back to the deprecated value field when max is absent.
value continues to work for backward compatibility but is deprecated. Use min and max to express an exact staffing range.

✅ Additional API Changes

  • Optional rule periodperiod on a period rule is now optional and defaults to the entire planning horizon when omitted.
  • Input hardening — null-byte sanitization and string-list validation were added across Fill request fields, including preference, employees, and blocklist.
Fill API v2 launch

🎉 Fill API v2

Fill API v2 is a ground-up redesign of shift filling: assign employees to shifts while respecting skills, availability, labor rules, and preferences.

Endpoints

Retrieve results asynchronously with GET /v2/fill/jobs/{id}/status, .../solution, and .../explanation.

Core capabilities

  • Multi-level skill matching (required skills as hard constraints, proficiency levels, soft-skill preferences)
  • Time-based availability windows and day-of-week restrictions
  • Locked (pre-assigned) and blocked employee–shift pairs

Migrating from v1

Several v1 fields were renamed or replaced for consistency and flexibility.

Fill Migration Guide

Full list of breaking changes and new features when moving to v2