Skip to main content
One generic model carries the whole work tree. A node’s type decides which domain concept it represents, from an order at the top down to a single step. Search columns: name, identifier Standard CRUD applies. See standard endpoints.
These raw endpoints do not enforce the concept rules. A step under an order, or a stage node with no station, is accepted here and leaves a tree the app cannot display. For validated writes use the domain concepts endpoints.
Hierarchy in brief: the roots are order, route, overhead, and template-phase. The containers order, phase, and component nest freely and hold stage nodes. step and qcstep are leaves under a stage.

Fields

Every property the API returns for a deliverable.

type values

Ten concepts share this one model.

Custom property values

Orders store catalog-defined values at data.properties.<key>. Nonempty property maps merge by key; {} or null clears all values. The rollout flag, value types, and query examples are covered in custom properties.

schedule

This is the stored shape, returned by GET. You do not write it directly: it is the result of the schedule action endpoints, whose request bodies use a different shape with epoch-second times.

progress

hasBeenReworked, updatedById, and updatedAt are server-managed. hasBeenReworked flips to true the first time a node enters rework and stays true afterwards, so it tells you whether rework ever happened rather than whether it is happening now.

computed

All read-only. BuildingSwell derives these from the tree on every read, so anything you send is ignored.
alertType and alertTypeOrdinal are derived the same way but are returned at the top level of the record, not inside computed. They are in the field table above.

Extra endpoints

Read a whole subtree

Returns { "values": Deliverable[], "totalCount": number } with the node and every node beneath it.

Group by a domain dimension

groupBy takes project, phase, stage, people, root, or tags. Use this when you want counts by something the model does not store as a plain column; POST /deliverable/group-and-count covers raw columns.

Reorder under a root

The list becomes the new sequence, and the dependency links are rewritten to match. Responds 204 with no body.

Crew time

Returns a map keyed by deliverable id. Set breakdown to split the totals out per person and station.
GET /deliverable/crew-time is deprecated. Repeating deliverableId in the query string exceeds URL length limits once you ask about many orders at once. Use the POST form above.

Schedule a node

The body is an action union keyed on type, not { startDate, endDate }. Times are epoch seconds, and you send only one of newStart or newFinish: the engine derives the other from duration and dependencies.
Responds 204 with no body. Re-read the node with GET /deliverable/{id} to see the resulting schedule.

Schedule in a batch

Same action union, wrapped per item. Responds 204 with no body.

Update progress

Another action union, rather than a patch of the progress object:
set-percentage is not allowed on qcstep nodes. Responds 200 with { "kickedWorkers": [...] }, the ids of anyone whose open work sessions and daily-plan assignments were stopped because their deliverable reached done. It does not return the updated node, so re-read it if you need the new progress.
To show someone the consequences of a destructive action such as rework before committing, call POST /concepts/root/{rootId}/progress/{id}/plan first. It computes the effect and writes nothing.

What you can write

Everything else in the table above is set by BuildingSwell.

Archive and restore

There is no separate archive endpoint. Flip isArchived with a PATCH, and BuildingSwell handles the rest.
When you archive:
  • identifier gets an - (archived <timestamp>) suffix, where <timestamp> is the archive time in epoch milliseconds. Match it with a pattern, not a literal string.
  • archivedAt is stamped with the current time.
  • Archiving cascades to every node beneath the one you archive, and then re-rolls the parent’s times and progress, because removing the last incomplete step can make a stage done. Restoring cascades the same way and re-rolls again.
When you restore, the suffix comes off, and a colliding identifier is given the next free variant. Archived records drop out of list results by default. Ask for them with an explicit filter:

Deleting

DELETE /deliverable/{id} is destructive.Permanently removes the node and every node beneath it. This is not the archive operation and it cannot be undone. Prefer PATCH /deliverable/{id} with { "isArchived": true }, which cascades the same way and is reversible.Before the rows go, BuildingSwell relinks what pointed at them so you do not silently lose time or QC history:
  • Work sessions and QC entries on any deleted node are moved onto the nearest surviving ancestor.
  • Dependency links touching any deleted node are removed with it.
  • When there is no surviving ancestor, which is the case when you delete a root order, the call is rejected with 400 if the subtree has work sessions or QC entries. Archive it instead.
See archiving and deleting for the full picture across resources.