The Schedule API does what the Schedule pages do: it reads the board, adds imposed jobs, changes the
plan, and records what happens on the floor. Use it to feed the Schedule from a machine's own controller, show the
queue on another screen, or add jobs from another system. Every endpoint is under your team, at
/a/<team_slug>/schedule/api/v1/.
Every call takes the same authentication as the rest of the API: an API key of a team member, or a signed-in session that also sends its CSRF token when it changes data (see authentication).
Ids are numbers. An object of another team is a 404. Every member can read. Changing the setup (machines, hours,
routes, ready checks and settings) needs a team administrator (403 for other members); planning endpoints need a
planner (see Schedule settings).
Times, revisions and polling#
- Times are Unix times in seconds (UTC). The board's
tzis your team's time zone, for showing them. - Revision. The team's schedule has a revision number,
rev, that goes up with every change. Every change answers with the newrev. - Polling. Send the last
revyou have inIf-None-Matchwhen you read the board: an unchanged schedule answers304 Not Modifiedat once.?since=<rev>returns only what changed since. - Stale changes. A plan change sends the
revit was based on. If the plan changed in between, the answer is409withcode: "stale"and what changed. Moves are relative ("after step 88"), so you can usually send them again. Every refusal also hasdetail, a sentence to show people;codeis for your code.
BASE="https://app.example.com/a/<team_slug>/schedule/api/v1" # your team's slug
AUTH="Authorization: Api-Key $API_KEY"
# The board for one day, then poll it (304 while nothing changed)
curl -s "$BASE/board/?from=1790000000&to=1790086400" -H "$AUTH"
curl -s -o /dev/null -w "%{http_code}" "$BASE/board/" -H "$AUTH" -H 'If-None-Match: "214"'
The board#
GET board/ returns the machines, their working time, downtime, jobs and steps in one answer, with short keys:
{
"rev": 214,
"now": 1790000000,
"tz": "Europe/London",
"resources": [{"id": 1, "name": "Press 1", "kind": "press_offset", "dept": "Print", "state": "running"}],
"windows": {"1": [[1789970400, 1790002800]]},
"downtime": [{"id": 5, "r": 1, "kind": "maintenance", "s": 1790010000, "e": 1790013600, "reason": "Blanket wash"}],
"orders": {"42": {"job": 42, "name": "Postcard A", "customer": "C-102", "due": 1790200000, "prio": 3,
"status": "scheduled", "ready": true, "risk": "ok"}},
"ops": [{"id": 88, "o": 42, "k": "print", "n": "Print", "r": 1, "seq": 3, "s": 1790003600, "e": 1790011200,
"su": 2400, "st": "ready", "pin": null, "km": true, "preds": [87]}],
"tray": [43, 44]
}
In ops, r is the machine, seq the place in its queue, s and e the planned start and end, su the makeready
in seconds, st the status and km Only this machine. GET today/ gives the phone view's summary per machine,
its counts (late, at risk, machines down, ready to place: the board's own counts) and the jobs ready to place, and
GET stations/<machine id>/ a station's current step, Up next and Later today.
Jobs#
| Call | What it does |
|---|---|
GET orders/ |
Jobs, filtered with status, risk, customer or q. |
POST orders/ with {"job": 42} |
Adds imposition job 42 to the tray (409 with no_layout when it has no selected layout); a finished job is added again as a reprint, or refused with 409 finished when you send "reprint": false. {"jobs": "all"} adds every imposed job with a selected layout that was never scheduled. {"name", "customer", "due_at", "priority", "route", "quantity", "notes"} adds a job that isn't imposed. |
PATCH orders/<id>/ |
{"status": "hold", "hold_reason": "…"} holds a job; {"status": "scheduled"} releases it. Also notes, release_at (not before) and route; a job that isn't imposed also takes name, customer, due_at and priority. |
DELETE orders/<id>/ |
Removes the job from the schedule. The imposition job isn't touched. |
POST orders/<id>/refresh/ |
Times the job again from its layout. |
POST orders/<id>/steps/, DELETE orders/<id>/steps/<step id>/ |
Adds a step to the job, or skips one that hasn't started. |
PATCH orders/<id>/checks/<key>/ |
{"state": "passed"} or "pending", with eta and note, ticks a manual ready check. Planners may also send "waived". |
Due dates, customers and priorities belong to the imposition job: change them with the Imposition API.
Plan changes#
| Call | Body |
|---|---|
POST operations/<id>/move/ |
{"resource": 2, "after": 91, "rev": 214} (or before). Answers the new rev and the steps that changed; 409 with stale, cycle or ineligible. |
POST operations/<id>/pin/ |
{"at": 1790020000, "rev": 214}; unpin/ removes it. |
POST operations/<id>/keep-machine/ |
{"value": false, "rev": 214} switches Only this machine. |
POST plan/preview/ |
{"mode": "place", "orders": [42, 43]}, or no orders for everything ready. Answers a preview_id, a summary and the steps that would change; nothing is saved. |
POST plan/apply/ |
{"preview_id": "…"} applies a preview, or 409 when the plan changed too much since (plan_changed) or the preview is older than 10 minutes (expired). |
POST activity/<id>/undo/, POST activity/<id>/redo/ |
Undoes a change from GET activity/, or redoes an undo. Steps that changed or started since are kept and listed. |
Floor events#
POST operations/<id>/events/ records what happened at a machine: start, makeready_done, pause, resume,
progress, done, problem, resolve, note, and check, which ticks a manual ready check the way Stock
arrived does. Planners can also send reopen (a done step, within 24 hours) and skip (a step that hasn't
started).
curl -s -X POST "$BASE/operations/88/events/" -H "$AUTH" -H "Content-Type: application/json" \
-d '{"kind": "done", "client_id": "00000000-0000-0000-0000-000000000000", "qty_good": 2100, "qty_waste": 40}'
client_idmakes the call safe to repeat: the same id twice records one event (201the first time,200after).at(when it happened) defaults to now;reasonis a pause or problem reason (see The station),noteany text.resourcerecords a step started on another machine than planned;running_choice(pauseorfinish) says what to do with the step already running there.- An event that doesn't fit the step answers
409withinvalid_transition, orcheck_pendingwhen a ready check holds it back. A planner can send"override": trueto start anyway.
Setup#
resources/ (with import-equipment/), downtime/, routes/ (with <id>/test/?job=42), checks/ and settings/
create, read, change and delete the machines, downtime, routes, ready checks and settings. Changes need a team
administrator, except POST resources/<id>/down/ and up/, which any member can call to report a machine down or back
up. PATCH settings/ also takes timezone, the team's time zone (an IANA name such as Europe/London; blank for
UTC), the same field as the team settings: the shop hours are re-timed in it.
GET activity/ lists the last 50 plan changes, and GET alerts/ the open alerts (POST alerts/<id>/ack/ acknowledges
one).
Every Schedule endpoint#
| Method | Path | What it does |
|---|---|---|
| GET | /a/{team_slug}/schedule/api/v1/activity/ | List the latest plan changes and floor decisions, newest first. |
| POST | /a/{team_slug}/schedule/api/v1/activity/{id}/redo/ | Redo an undone change (the undo's id). |
| POST | /a/{team_slug}/schedule/api/v1/activity/{id}/undo/ | Undo a plan change (steps changed or started since are kept). |
| GET | /a/{team_slug}/schedule/api/v1/alerts/ | List the open alerts. |
| POST | /a/{team_slug}/schedule/api/v1/alerts/{id}/ack/ | Acknowledge an alert. |
| GET | /a/{team_slug}/schedule/api/v1/board/ | Read the planning board: machines, working time, downtime, jobs and steps. |
| GET | /a/{team_slug}/schedule/api/v1/checks/ | Read the team's ready checks. |
| PATCH | /a/{team_slug}/schedule/api/v1/checks/ | Switch built-in ready checks, set custom checks and Require a proof. |
| GET | /a/{team_slug}/schedule/api/v1/downtime/ | List downtime and overtime (open and coming). |
| POST | /a/{team_slug}/schedule/api/v1/downtime/ | Add downtime (closed, maintenance, breakdown) or overtime to a machine or the whole shop. |
| PATCH | /a/{team_slug}/schedule/api/v1/downtime/{id}/ | Change a downtime. |
| DELETE | /a/{team_slug}/schedule/api/v1/downtime/{id}/ | Remove a downtime. |
| POST | /a/{team_slug}/schedule/api/v1/operations/{id}/events/ | Record a floor event on a step: start, pause, resume, done, problem and more. |
| GET | /a/{team_slug}/schedule/api/v1/operations/{id}/explain/ | Explain a step: why it starts when it does, other machines, late causes and fixes. |
| POST | /a/{team_slug}/schedule/api/v1/operations/{id}/keep-machine/ | Switch Only this machine for a step. |
| POST | /a/{team_slug}/schedule/api/v1/operations/{id}/move/ | Put a step on a machine, after or before another step of that machine. |
| POST | /a/{team_slug}/schedule/api/v1/operations/{id}/override/ | Set a step's duration by hand, or go back to the estimate. |
| POST | /a/{team_slug}/schedule/api/v1/operations/{id}/pin/ | Pin a step: keep it on its machine, not before a time. |
| POST | /a/{team_slug}/schedule/api/v1/operations/{id}/unpin/ | Remove a step's pin. |
| GET | /a/{team_slug}/schedule/api/v1/orders/ | List the schedule's jobs. |
| POST | /a/{team_slug}/schedule/api/v1/orders/ | Send an imposition job (or all of them) to the schedule, or add a manual job. |
| GET | /a/{team_slug}/schedule/api/v1/orders/{id}/ | Read a job with its steps and ready checks. |
| PATCH | /a/{team_slug}/schedule/api/v1/orders/{id}/ | Hold or release a job, or change its notes, not-before time or route. |
| DELETE | /a/{team_slug}/schedule/api/v1/orders/{id}/ | Remove a job from the schedule. |
| PATCH | /a/{team_slug}/schedule/api/v1/orders/{id}/checks/{key}/ | Tick, untick or waive a job's ready check. |
| POST | /a/{team_slug}/schedule/api/v1/orders/{id}/refresh/ | Time a job again from its layout (Review new times). |
| POST | /a/{team_slug}/schedule/api/v1/orders/{id}/steps/ | Add a step to a job. |
| DELETE | /a/{team_slug}/schedule/api/v1/orders/{id}/steps/{op_id}/ | Skip a step of a job that hasn't started. |
| POST | /a/{team_slug}/schedule/api/v1/plan/apply/ | Apply a previewed plan as one change you can undo. |
| POST | /a/{team_slug}/schedule/api/v1/plan/preview/ | Preview Place (new steps only) or Re-plan: nothing changes until you apply it. |
| GET | /a/{team_slug}/schedule/api/v1/plan/preview/{task_id}/ | Read a background preview: 202 while it is still working. |
| GET | /a/{team_slug}/schedule/api/v1/resources/ | List the schedule's machines. |
| POST | /a/{team_slug}/schedule/api/v1/resources/ | Add a machine. |
| GET | /a/{team_slug}/schedule/api/v1/resources/{id}/ | Read a machine. |
| PATCH | /a/{team_slug}/schedule/api/v1/resources/{id}/ | Change a machine. |
| DELETE | /a/{team_slug}/schedule/api/v1/resources/{id}/ | Remove a machine that has no work or history. |
| POST | /a/{team_slug}/schedule/api/v1/resources/{id}/down/ | Report a machine down (a breakdown with an expected end). |
| POST | /a/{team_slug}/schedule/api/v1/resources/{id}/up/ | Report a machine back up (closes its breakdown). |
| POST | /a/{team_slug}/schedule/api/v1/resources/import-equipment/ | Add equipment from the equipment library as machines (all of it, or the listed items). |
| GET | /a/{team_slug}/schedule/api/v1/routes/ | List the routes jobs follow. |
| POST | /a/{team_slug}/schedule/api/v1/routes/ | Add a route. |
| GET | /a/{team_slug}/schedule/api/v1/routes/{id}/ | Read a route. |
| PATCH | /a/{team_slug}/schedule/api/v1/routes/{id}/ | Change a route (jobs already on the schedule keep their steps). |
| DELETE | /a/{team_slug}/schedule/api/v1/routes/{id}/ | Remove a route (not the fallback route). |
| GET | /a/{team_slug}/schedule/api/v1/routes/{id}/test/ | Test a route with an imposition job: its steps, every machine's time, the machines that can't. |
| GET | /a/{team_slug}/schedule/api/v1/settings/ | Read the schedule's settings. |
| PATCH | /a/{team_slug}/schedule/api/v1/settings/ | Change schedule settings (shop hours, time fence, automation, who can plan…). |
| GET | /a/{team_slug}/schedule/api/v1/stations/{id}/ | Read one machine's queue: the step on it, up next, later today and other work it could run. |
| GET | /a/{team_slug}/schedule/api/v1/today/ | Read today's floor per machine: its state, the step on it and what is next. |