Scale Commands
Scale commands are server-initiated actions sent to the terminal via the scale_commands table. The terminal receives them in real-time via WebSocket INSERT events.
Command Types
| Command | Payload | Description |
|---|---|---|
push_weight | {} | Terminal patches scale with current weight and truck info; pass commandId in the PATCH body to auto-complete |
pull_state | {} | Terminal gets scale state and locks itself (displays session info); complete by patching with commandId only |
upload_photos | { "orderId": "uuid" } | Terminal uploads all camera photos via batch endpoint with commandId → command auto-completes |
⚠️ The single-photo endpoint (
POST /api/terminal/orders/{orderId}/cameras/{cameraId}/photos) is deprecated — it has nocommandIdsupport. Always use the batch endpoint.
Command Status Flow
PENDING → ACKED → COMPLETED
↓
FAILED (if error)
The ACKED step is optional and can be skipped. Commands complete server-side automatically when the terminal includes commandId in the relevant PATCH or upload request.
Processing Guidelines
- Idempotency — check command status before executing; handle already-completed commands gracefully
- Sequence — each command has
scaleSeq; use it to detect missed commands on reconnect - Error handling — if command fails, PATCH with
status: "FAILED"anderrormessage - Acknowledgment — optionally ACK before executing
Executing: push_weight
- Read current weight and truck info from the scale
- Optionally acknowledge:
PATCH /api/terminal/scales/{scaleId}/commands/{commandId}withstatus: "ACKED" - Patch scale state with weight data and
commandId:
Endpoint: PATCH /api/terminal/scales/{scaleId}
{
"commandId": "command-uuid",
"stableWeight": 25000,
"truckNumber": "AA1234BB",
"truckTrailerNumber": "AA5678CC",
"axis": {
"axis1": 5000,
"axis2": 5000,
"axis3": 5000,
"axis4": 5000,
"axis5": 5000
}
}Response 200:
{
"id": "scale-uuid",
"name": "Scale 1",
"stableWeight": 25000,
"truckNumber": "AA1234BB",
"activeSessionId": "session-uuid",
"activeSession": {
"id": "session-uuid",
"lockedBy": "USER",
"lockedUntil": "2025-10-27T15:30:00.000Z"
},
"latestCommand": {
"id": "command-uuid",
"name": "push_weight",
"status": "COMPLETED"
}
}Including commandId automatically marks the command as COMPLETED.
Executing: pull_state
- Get scale state:
GET /api/terminal/scales/{scaleId} - Lock the terminal UI (display session info)
- Complete command by patching with
commandIdonly (no weight fields required):
{ "commandId": "command-uuid" }Executing: upload_photos
Command payload contains orderId. Terminal should:
- Optionally acknowledge the command
- Capture photos from all cameras
- Upload via batch endpoint — including
commandIdauto-completes the command:
Endpoint: POST /api/terminal/scales/{scaleId}/orders/{orderId}/photos/batch
commandId: <command-uuid>
cameraId: <camera-uuid-1>
file: [binary image 1]
cameraId: <camera-uuid-2>
file: [binary image 2]
Acknowledge Command (Optional)
Endpoint: PATCH /api/terminal/scales/{scaleId}/commands/{commandId}
{
"status": "ACKED",
"ackedAt": "2025-10-27T15:00:01.000Z"
}Related
- order-flows — how commands fit into the User-Driven and Terminal-Driven flows
- websocket-realtime — how the terminal receives new commands in real-time
- integration-guide — architecture overview