Schema Reference¶
This page describes every section of the account manifest. The authoritative machine-readable definition is the published JSON Schema. If this page and the schema ever disagree, the schema wins, because it is generated from the same definitions Busroot validates with.
Conventions used throughout:
- Time values are in milliseconds unless stated otherwise.
- Fields marked system managed are written by Busroot itself (timestamps, runtime state). Leave them out when authoring a manifest by hand.
Top level¶
| Field | Type | Required | Description |
|---|---|---|---|
version |
"v1" |
Yes | Schema version. Currently always "v1". |
account |
object | Yes | The whole account configuration. Every other section nests inside it. |
Account¶
Account identity, account-wide settings, and the nested collections.
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Unique account identifier. On a self-hosted deployment this is fixed and must not be changed. |
domain |
string | Yes | Email domain of the account's users (e.g. acme.com). Users on this domain can log in without being added. |
currency |
string | No | ISO 4217 currency code (e.g. USD, EUR, GBP) used for every cost figure. |
electricalPricePerKwh |
number ≥ 0 | No | Cost per kilowatt-hour of electricity (e.g. 0.15). |
electricalCo2PerKwh |
number ≥ 0 | No | CO2 emissions per kilowatt-hour (e.g. 0.233). |
durationFormat |
months | days | hours | minutes |
No | The unit durations are displayed in. |
maxProductionCountPerSchedule |
integer 1–9,999,999 | No | Safety net on gross count errors: the most production units a single schedule may record. See Maximum production count per schedule. |
stationCountLimit |
integer ≥ 0 | No | Maximum number of stations allowed across all plants. |
dashboardConfig |
object | No | Custom dashboard configuration (key-value pairs), e.g. station ordering on the Production Progress dashboard. |
includeReasonCodes / excludeReasonCodes |
string[] | No | Restrict which reasons are available account-wide. See the include/exclude cascade. |
includeTaskListCodes / excludeTaskListCodes |
string[] | No | Restrict which Task lists apply account-wide. Same cascade as reasons, but with no include list anywhere nothing is available. See the cascade. |
includeTaskCodes / excludeTaskCodes |
string[] | No | Legacy, no longer read. Kept so manifests written before Task lists still load. |
shiftPatterns |
array | No | Shift patterns. |
reasons |
array | No | Reasons. |
tasks |
array | No | Tasks. |
taskLists |
array | No | Task lists. |
skus |
array | No | SKUs. |
plants |
array | Yes | Plants. At least one in any useful manifest. |
uploadTransforms |
string | No | Spreadsheet-upload transformation configuration (system managed). |
appUrls |
string | No | Custom application URLs (system managed). |
redshiftPassword |
string | No | Data-warehouse password (system managed). |
createdAt / updatedAt / archivedAt |
string (ISO 8601) | No | Timestamps (system managed). |
The account also carries feature-flag fields. At this level their value
is "on" or "off" (no "inherit", since there is nothing above the account to inherit
from).
Shift patterns¶
A shift pattern is a named weekly timetable of working periods. Station groups and stations
reference a pattern by its code; a station's pattern overrides its group's.
| Field | Type | Required | Description |
|---|---|---|---|
code |
string (max 64) | Yes | Unique identifier, referenced by shiftPatternCode on groups and stations. |
title |
string | Yes | Display name (e.g. default, 5-day, 24/7). Must be unique within the account. |
shifts |
array (min 1) | Yes | The working periods that make up the pattern. |
Each entry in shifts:
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Shift name. Multiple shifts may share a name to group split periods (e.g. Day Shift for 09:00–12:00 and 13:00–17:00). |
startHour |
number, 0 ≤ x < 24 | Yes | Start hour as a decimal: 14.5 is 14:30, 17.25 is 17:15. |
duration |
number, 0 < x ≤ 24 | Yes | Length in hours as a decimal (8, 4.5). A shift may run past midnight. |
weekDay |
string "1"–"7" |
Yes | Day the shift starts on: "1" = Monday … "7" = Sunday. |
Reasons¶
Reasons categorise non-productive time and rejected production. They form a tree: a reason
may nest child reasons to any depth (Maintenance → Preventive Maintenance → PM
Check).
| Field | Type | Required | Description |
|---|---|---|---|
code |
string | Yes | Unique reason code, referenced from include/exclude lists and recorded against downtimes. Must be unique within the account. |
description |
string | Yes | Human-readable description (e.g. Planned maintenance, Equipment breakdown). |
type |
array (min 1) of downtime | non-production | quality |
Yes | Where the reason may be used: downtime for unplanned stoppages, non-production for planned activities, quality for bad/rejected production. A reason can carry several types. |
requireNotes |
boolean | No | When enabled, operators must enter notes before the reason can be confirmed (downtime assignments only). Omit the field to inherit the nearest ancestor reason's setting; set false to explicitly opt out of an inherited true. |
reasons |
array | No | Child reasons: subcategories of this reason, nested to any depth. |
Tasks and Task lists¶
Tasks are recurring procedures operators complete in the Operator Interface, such as startup checklists
and quality inspections. Which stations a Task applies to is controlled by the
includeTaskListCodes/excludeTaskListCodes lists at each level: a Task reaches a station
through the Task lists it belongs to.
| Field | Type | Required | Description |
|---|---|---|---|
code |
string | Yes | Unique Task code (e.g. STARTUP-CHECK). Must be unique within the account. |
title |
string | Yes | Human-readable title (e.g. Machine Startup Checklist). |
description |
string | No | Detailed description of the Task and its purpose. |
trigger |
object | No | Legacy. Trigger moved to the Task list; this is kept only so manifests written before the move still load, and nothing reads it. |
requireNotes |
boolean | No | When enabled, operators must enter notes before the Task can be confirmed as complete. |
taskListCodes |
object[] | No at read time; at least one required when saving | The Task lists this Task belongs to, each { "code": "...", "order": n }. order is the Task's position within that list (decimals allowed, so a Task can be inserted between two others); it is required when saving and must be greater than 0 and at most 100. Manifests written before ordering existed may carry a plain array of code strings, which still loads. |
A Task with no list is scoped to nothing and appears on no station. Membership is what gives a Task both its trigger and its stations.
A Task list is the unit of operation: it carries the trigger every Task in it follows, is what the include/exclude cascade scopes to a station, and is a section of its own in the Operator Interface.
| Field | Type | Required | Description |
|---|---|---|---|
code |
string | Yes | Unique Task list code (e.g. DAILY-CHECKS). |
name |
string | Yes | Human-readable name (e.g. Daily Checks). |
description |
string | No | What this list groups together. |
trigger |
object | No at read time; required when saving | What makes every Task in this list pending; how often they must be completed. See below. A list written before the move has none and behaves as schedule. |
trigger is one of three shapes:
{ "type": "schedule" }: the list's Tasks must be completed once per production schedule.{ "type": "cron", "pattern": "...", "availableBeforeDeadlineMinutes": n }: the list's Tasks must be completed every cron period.patternis a standard 5-field cron expression (minute, hour, day-of-month, month, day-of-week), evaluated in the station's plant timezone; each cron fire is the deadline.availableBeforeDeadlineMinutescontrols how long before the deadline the Tasks appear in the Operator Interface, and must be shorter than the smallest gap between consecutive fires. It is required for new cron lists.{ "type": "on_demand" }: On Demand: no deadline. The operator starts the list in the Operator Interface, which makes every Task in it pending; each is completed individually and the list can be started again the moment it is done. They are never missed for time, only when the Task, list or station assignment is removed while a run is open. (A list of any trigger can also be started from the Operator Interface; such a run is an On Demand instance, and if the scheduled instance becomes pending while it is still open the run becomes that instance.)
Manifests written before the rename may still say frequency instead of trigger, and always
instead of on_demand. Both forms are accepted on read and by POST /api/manifest/apply, and
the next save writes the new form.
code (letters, digits, -, _; max 32), title (max 128) and description (max 300) are
validated when a Task or Task list is created or edited, not when the manifest is read.
pre-existing entries outside those limits keep loading and only have to conform when next saved.
A Task in two lists is completed independently in each: it gets its own rows and its own completion history per list, and follows each list's trigger.
SKUs¶
A SKU (part, product, component) is what production schedules are scheduled against. A schedule may only name a SKU that already exists in the manifest.
| Field | Type | Required | Description |
|---|---|---|---|
code |
string | Yes | Unique SKU code (e.g. WIDGET-001). Must be unique within the account. |
name |
string | Yes | Human-readable name (e.g. Widget Type A). |
specifications |
string | No | Detailed specifications or technical description. |
instructionsUrl |
string | No | URL to a process document for this SKU. |
cycleTime |
integer ms, 0 < x ≤ 12 h | No | Standard cycle time in milliseconds for producing this SKU (30000 = 30 seconds). For discrete operations with defined cycles. |
unitsPerMinute |
number > 0 | No | Standard production rate in units per minute. For moderate-speed processes. |
unitsPerHour |
number > 0 | No | Standard production rate in units per hour. For high-speed continuous manufacturing. |
partsPerCycle |
integer > 0 | No | Units produced in a single cycle, applied when production-complete signals are received. |
lineSpeedTarget |
number, 0 < x ≤ 99999 | No | Target line speed for this SKU. |
downtimeDurationThresholdMultiplier |
number > 0 | No | Multiple of cycle time used as the downtime threshold when production-based downtime detection is enabled (2.0 = downtime after 2× cycle time). |
value |
number ≥ 0 | No | Nominal value of one unit in the account currency. Used to calculate lost-production and quality cost. |
allowUseInQuickSchedule |
boolean | No | Whether this SKU can be selected when creating ad-hoc schedules from the Operator Interface. |
stationCodes |
string[] | No | If set, only these stations can be scheduled with this SKU. |
stationGroupCodes |
string[] | No | If set, only stations in these groups can be scheduled with this SKU. |
taskCodes |
string[] | No | Task codes linked to this SKU for reference. Validated against the account's Tasks, and a Task named here cannot be deleted; it has no effect on which stations see the Task. |
minimumCycleTime |
integer ms, 0 ≤ x ≤ 12 h | No | Minimum time between production signals while a schedule for this SKU is running; takes precedence over the station's own minimum cycle time. If multiple signals arrive within this period, only one unit is counted. Useful for filtering signals during setup. |
Set one of cycleTime, unitsPerMinute or unitsPerHour as the SKU's production
rate, whichever matches the process. SKU rates take precedence over the station's own
rate fields while a schedule for the SKU is running.
Plants¶
A plant is a physical site. Its timezone and day/week boundaries anchor every time-based calculation for the stations inside it.
| Field | Type | Required | Description |
|---|---|---|---|
code |
string, 3–55 chars, lowercase letters/numbers/dashes | Yes | Unique plant code. |
name |
string | Yes | Human-readable plant name (e.g. East Coast Plant). |
timezone |
string | Yes | IANA timezone name (e.g. Europe/London, America/New_York). |
dayStartHour |
integer 0–23 | Yes | Hour the production day starts (6 = 06:00, 0 = midnight). |
weekStartDay |
integer 0–6 (default 0) | No | Day the production week starts: 0 = Monday (ISO standard) … 6 = Sunday. |
includeReasonCodes / excludeReasonCodes |
string[] | No | Reason availability at this level. See the cascade. |
includeTaskListCodes / excludeTaskListCodes |
string[] | No | Task list availability at this level. |
includeTaskCodes / excludeTaskCodes |
string[] | No | Legacy, no longer read. Kept so manifests written before Task lists still load. |
totalEnergyStationCodes |
string[] | No | When set, this plant's energy (kWh, cost, CO2) is the sum of these stations' energy instead of the additive sum over member stations. See Energy totals. |
stationGroups |
array | Yes | Station groups. At least one in any useful plant. |
createdAt / updatedAt / archivedAt |
string (ISO 8601) | No | Timestamps (system managed). |
Plants also carry feature-flag fields (tri-state).
Station groups¶
A station group is a line or area within a plant. It is a level of the configuration hierarchy: shift pattern, reason/Task availability and feature flags set here apply to the member stations unless a station overrides them.
| Field | Type | Required | Description |
|---|---|---|---|
code |
string | Yes | Unique group identifier within the plant (e.g. LINE-01, PACKAGING). |
name |
string | Yes | Human-readable group name (e.g. Assembly Line 1). |
shiftPatternCode |
string | No | The shift pattern this group follows. |
includeReasonCodes / excludeReasonCodes |
string[] | No | Reason availability at this level. |
includeTaskListCodes / excludeTaskListCodes |
string[] | No | Task list availability at this level. |
includeTaskCodes / excludeTaskCodes |
string[] | No | Legacy, no longer read. Kept so manifests written before Task lists still load. |
totalEnergyStationCodes |
string[] | No | When set, this group's energy is the sum of these stations' energy instead of the additive sum over member stations. |
stations |
array | Yes | Stations. At least one in any useful group. |
createdAt / updatedAt |
string (ISO 8601) | No | Timestamps (system managed). |
Station groups also carry feature-flag fields (tri-state).
Stations¶
A station is a machine or workplace: the unit everything is recorded against. Its fields group by purpose.
Identity
| Field | Type | Required | Description |
|---|---|---|---|
code |
string, 1–32 chars of A–Z a–z 0–9 - _ |
Yes | The station's permanent identifier. Cannot be changed once the station has data. See the warning on the overview page. |
name |
string, 1–32 chars | Yes | Friendly display name (e.g. Assembly Station 1). |
description |
string | No | Brief description of the station's purpose or function. |
shiftPatternCode |
string | No | The shift pattern this station follows; overrides the group's pattern. |
Productive-status detection: how Busroot decides the station is running. See station behaviour settings.
| Field | Type | Required | Description |
|---|---|---|---|
productiveStatusMode |
productive_signal | electrical_usage | line_speed (default productive_signal) |
No | How value-adding activity is measured: a productive signal from the device, electrical consumption, or line speed. |
electricalUsageStoppedThresholdKw |
number ≥ 0 | No | With electrical_usage: below this power draw (kW) the station is regarded as stopped. |
lineSpeedStoppedThreshold |
number ≥ 0 | No | With line_speed: below this speed the station is regarded as stopped. |
productiveHoldOnTime |
integer ms, ≤ 1 day | No | How long the station stays "productive" after each productive signal; each new signal restarts the timer (300000 = 5 minutes). The admin UI presents this in minutes. |
Downtime detection
| Field | Type | Required | Description |
|---|---|---|---|
downtimeDetectionMode |
off | production | utilisation | line_speed (default utilisation) |
No | How stops are detected: not at all, from production cycle data, from utilisation signals (most common), or from line speed. |
utilisationDowntimeThreshold |
integer ms ≥ 0 | No | Minimum stop duration before a downtime is recorded (120000 = 2 minutes). Defaults to 1 hour when not set. The admin UI presents this in minutes. |
slowDurationThreshold |
integer ms ≥ 0 | No | Duration threshold for detecting slow operation. |
Speed signal scaling
| Field | Type | Required | Description |
|---|---|---|---|
speedScale |
number, −9999 to 9999 | No | Calibration multiplier when the reported speed doesn't reflect actual running speed (reported 20, actual 10 → scale 0.5). |
speedOffset |
number, −9999 to 9999 | No | Zero-offset fine-tuning (speed shows 0.5 when stopped → offset -0.5). |
speedToProductionRatio |
number, 0–99999 | No | Converts a speed value into a production count. Blank = no units counted from speed. |
Performance rates: the station's own targets, used when the running SKU doesn't define a rate.
| Field | Type | Required | Description |
|---|---|---|---|
cycleTime |
integer ms, 0 < x ≤ 12 h | No | Standard production cycle time in milliseconds. The admin UI presents this in seconds. |
unitsPerMinute |
integer > 0 | No | Expected production rate in units per minute. |
unitsPerHour |
integer > 0 | No | Expected production rate in units per hour. |
lineSpeedTarget |
number, 0 < x ≤ 99999 | No | Target operating speed. |
minimumCycleTime |
integer ms, 0 ≤ x ≤ 12 h | No | Minimum time between production signals. If multiple signals arrive within this period, only one unit is counted. This filters out repeated pulses for a single unit. A running schedule's SKU minimum cycle time takes precedence. The admin UI presents this in seconds. |
Cost and energy
| Field | Type | Required | Description |
|---|---|---|---|
idleCostPerMinute |
number, 0–99999 | No | Cost per idle minute in the account currency, used for scheduling, non-production and downtime losses when the SKU has no value. |
electricalPowerNominalKw |
number ≥ 0 | No | Expected power usage (kW) during normal operation. |
Reason and Task availability
| Field | Type | Required | Description |
|---|---|---|---|
includeReasonCodes / excludeReasonCodes |
string[] | No | Reason availability at this station, the final level of the cascade. |
includeTaskListCodes / excludeTaskListCodes |
string[] | No | Task list availability at this station. |
includeTaskCodes / excludeTaskCodes |
string[] | No | Legacy, no longer read. Kept so manifests written before Task lists still load. |
Runtime state (system managed): these appear in the schema because Busroot writes them at runtime; do not author them.
| Field | Type | Description |
|---|---|---|
statusCode / statusCodeUpdatedAt |
string / ISO 8601 | The station's current live status. |
currentOperatorInitials |
string (3–8 chars) | The initials of the operator currently signed in to the Operator Interface. |
alertMessage / alertExpiresAt |
string / ISO 8601 | The current station alert, if any. |
createdAt / updatedAt / archivedAt |
ISO 8601 | Timestamps. An archived station is hidden everywhere but keeps its history and its code stays reserved. |
Other
| Field | Type | Required | Description |
|---|---|---|---|
forceAllShiftTimeAsPlannedProduction |
boolean | No | Treat all shift time as planned production time: production signals are recorded even with no schedule running. Recorded output then has no SKU and no work order reference, so prefer running a continuous production schedule against a test SKU where possible. |
Stations also carry feature-flag fields (tri-state).
Feature flags¶
Feature flags gate optional behaviour. A flag can be configured at up to four levels (account → plant → station group → station), and each level stores one of three values:
"on": enabled from this level down."off": disabled from this level down."inherit"(or the field simply absent): no opinion at this level; the value comes from the nearest ancestor that sets one.
The nearest defined ancestor wins. If nothing in the chain sets a value, the flag is
off. At the account level only "on" and "off" are valid, because there is nothing above
the account to inherit from.
| Flag | Levels | Description |
|---|---|---|
enableProductionCorrection |
account, plant, group, station | Allow operators to correct production counting errors during a running schedule from the Operator Interface. |
enableHistoricalCorrection |
account | Correct production counts on schedules that have already ended. Available to admins from the action menu on the schedule list and Gantt chart. This is separate from the live correction in the Operator Interface. |
enableManualProduction |
account, plant, group, station | Allow operators to manually enter production quantities. |
enableQuickScheduleStart |
account, plant, group, station | Allow operators to start ad-hoc schedules from the Operator Interface. |
enableScheduleCutShort |
account, plant, group, station | Allow operators to end a schedule before its planned end. |
enableRejectProduction |
account, plant, group, station | Allow operators to reject (scrap) produced units. |
enableEditPartsPerCycle |
account, plant, group, station | Allow operators to override the parts-per-cycle value on a schedule. |
enableScheduleStationFlexibility |
account, plant, group, station | Allow schedules to run on any station within the group. |
enableManualDowntime |
account, plant, group, station | Allow operators and API users to manually trigger downtime on a station, blocking production while active. |
enableAlwaysConnected |
account, plant, group, station | Force the station to always show as connected, regardless of device signals. For stations with no physical device. |
enableSchedulingOnly |
group, station | Restrict the station to scheduling only (no live production capture). |
enableMeterOnly |
group, station | The station represents a physical energy meter (e.g. a plant incomer): it only publishes electrical signals and is hidden from production views, rollups and pickers by default. |
enableLostProductionCost |
account | Enable tracking of lost production costs. |
enableAutoEndOnQuantityComplete |
account | Automatically end schedules when their target quantity is reached (account default for new schedules). |
enableDragBetweenStationsOnGantt |
account | Allow schedules to be reassigned to a different station by dragging on the Gantt chart. |
enableTasks |
account | Turn on Tasks. Set by Output Industries. |
enableCycleTimeAnalysis |
account | Show the Cycle Time Analysis page. Set by Output Industries. |
See feature flags in practice for worked examples of the cascade.