endDate is still running.
Standard CRUD applies. See standard endpoints.
For a single read across both work sessions and attendance, use
timesheets instead.
Processed and original clock times
startDate and endDate are the effective times used by BuildingSwell reporting. The hours-rounding job can rewrite these boundaries after a session closes. Do not assume they are the original clock times or that a closed record will never change.
rawStart and rawEnd preserve the original boundary when that side is processed. They are independent: one can be populated while the other is null. A non-null raw value means that boundary was processed, even if its value equals the effective time. There is no separate rounded flag.
For original clock times, use rawStart ?? startDate and rawEnd ?? endDate. For processed hours, use startDate and endDate, accounting for unpaid breaks. Raw fields are read-only; editing time can reset the processing state. Reconcile previously fetched closed records when importing hours.
Fields
Every property the API returns for a work session.shiftWorkHours
Each entry in
breaks:
What BuildingSwell fills in for you
Two fields are resolved on create when you leave them out, which is usually what you want:shiftWorkHourscomes from the person’s shop shift forstartDate, with the shop’s timezone stamped onto it. That timezone is whatbreakTimeInSecanchors break times to, so letting the server fill this in keeps break math correct.metadata.costCodeis resolved from the deliverable, then its station, then its ancestors, then the project, then the route. If none of those carry a cost code, the key is left off rather than written asnull. See cost code resolution.
metadata.unionCode is different: it is written only when a session is created by
assigning someone to a deliverable, and it is set to that person’s unionCode or
null. A session you create with a direct POST has no unionCode key at all.
Both are copies of a value, taken at the moment the session was created. They are
not links into the code lists, so editing or deleting a code
later leaves every existing session untouched.
Break time
breakTimeInSec is computed by the database from shiftWorkHours.breaks, carving
out only the break time that overlaps the session’s own window. It is read-only,
and it reports 0 while the session is open. The rule is worked through in full
under break time and how it is carved out.
One open session per pair
A person can hold only one open session per deliverable. A second attempt comes back as409, which makes retries safe: if your first request timed out but
landed, the retry tells you so rather than double-counting the hours.
Save assignments
POST /deliverable/work-sessions/save sets who is working on what and works out
the difference itself, so you send the desired end state rather than a list of
changes.
assignments is keyed by person id, and each value is that person’s full list of
deliverables, with at least one entry. shopId is required, and startDate
defaults to now.
The call compares your list against each person’s currently open sessions: it
starts sessions for deliverables you added and stops sessions for ones you dropped.
Someone marked absent gets a saved plan instead of a live session, which starts
when they check in. Responds 204 with no body.
Stop sessions
deliverableIds or workerIds. A request with neither is
rejected: there is deliberately no way to stop every open session in one call.
endDate defaults to now. Responds 204 with no body.
Two behaviors to know about when someone is on several deliverables at once:
- The elapsed time is split evenly across all of that person’s open sessions, so an hour spent across three deliverables books 20 minutes each rather than an hour three times.
- Any session you did not explicitly stop is restarted from that point, so dropping one deliverable from a batch does not stop the rest.
endDate earlier than a session’s own start collapses that session to zero
duration instead of writing negative time.
Find problem sessions
POST /deliverable/work-sessions/error-ids returns the ids of sessions that
overlap another session for the same person, or that run past the shift they belong
to. It takes the same filters as the list endpoint, in the body, so you can check a
whole pay period in one call before you trust the hours in it.