Realtime — executor to planner¶
Realtime endpoints carry continuous, best-effort feedback from the floor. The expected latency budget is sub-second to a few seconds, but the contract tolerates eventual consistency — corrections may arrive later through the confirmation path.
Endpoints¶
Endpoint |
What the executor posts |
|---|---|
|
One or more completed inventory movements ( |
|
Short-pick, damaged product, wrong SKU, robot stuck, worker unavailable, device fault, subsystem offline. |
|
Task lifecycle transitions: |
|
Periodic floor / fleet capacity snapshot for dashboards: active workers, idle robots, conveyor utilization, zone WIP. Optional. |
movements and exceptions are the required minimum for a useful executor implementation. work-status enables document-detail visibility on the planner side. capacity exists for dashboards only — it must never feed inventory or accounting.
What the planner does with each stream¶
Stream |
Planner behavior |
|---|---|
Movements |
Apply to the inventory ledger immediately. Tag with |
Exceptions |
Surface in a supervisor queue. Trigger the planner’s notification model with severity ( |
Work-status |
Persist as task lifecycle. Drives the planner’s document-detail UI; no ledger impact. |
Capacity |
Dashboards and trend charts only. Never used for inventory math or accounting. |
Movement kinds¶
Kind |
Meaning |
|---|---|
|
Take from a source location toward outbound staging. |
|
Place into a destination location. |
|
Relocate within the warehouse (not tied to a document line). |
|
Compensating adjustment from cycle count or discrepancy resolution. |
|
Work order input consumed. |
|
Work order output produced. |
|
Inbound receipt. |
|
Outbound shipment. |
When the SKU is lot- or serial-tracked, the executor sends lot or serial (or both) alongside the quantity. The planner remains authoritative for SKU, UoM, and location validation; a payload referencing an unknown SKU or location is rejected with 422. See Data mapping for the full envelope.
Idempotency¶
Every realtime call carries a correlation_id. A retry with the same (partner_id, correlation_id) returns 200 OK with replay: true and produces no additional ledger movement, exception, work-status, or capacity record. See Idempotency and ordering for the full rules.
Batching¶
Each endpoint accepts either a single record or an array. Batching is the recommended steady-state mode for executors with high movement rates — pack movements into batches of 10–200 per call to amortize TLS handshake and authentication cost. Each item in a batch carries its own correlation_id; the planner reports per-item results.
Generalized exception envelope — event_type discriminator (v1.3+)¶
Per WES ADR-0022, the /wes/v1/realtime/exceptions endpoint (and the underlying confirmation.realtime.v1 Kafka topic for Kafka transport) is semantically generalized from “exceptions only” to “realtime observations” as of OpenAPI v1.3. The envelope is extended with an event_type discriminator; the existing failure-event types continue to work without change.
|
Class |
Meaning |
|---|---|---|
|
failure |
Existing — observed pick quantity less than expected |
|
failure |
Existing — damaged unit found at pick or pack |
|
failure |
Existing — scanned barcode does not match expected SKU |
|
positive |
Any label scan event; carries |
|
positive |
Operator requested label void (damage / unreadable / supervisor override) |
|
positive |
Custody-point reached; planner should issue a label via |
|
positive |
Container attached to AMR/station slot |
|
positive |
Container removed from slot |
|
positive |
Container arrived at PackStation / RecoveryStation / dock |
|
positive |
Operator scanned a pre-printed pool label; needs binding from planner |
|
positive (v1.4) |
Multi-picker scan-at-induction commits operator to next cartonization position |
Envelope additions (all event_type values):
{
"event_uuid": "01J7Y6K1NQ3W2C0X4V0R5T6E7N",
"event_type": "label_scanned",
"correlation_id": "frn:wms:intl:order/ORD-2026-000183",
"agent_id": "frn:wes:intl:agent/op-jane.doe",
"context": {
"label_id": "1Z999AA10123456784",
"binding_id": "frn:wes:intl:label_binding/LB-2026-04823",
"scanned_at": "2026-05-29T09:14:33.221Z",
"scan_location": "frn:wes:intl:artifact/packstation-04"
}
}
The context payload is per-event_type discriminated; the full per-type schema is in the OpenAPI reference.
POST /wes/v1/labels/issue round-trip (v1.3+)¶
Pairs with the label_print_requested observation. The planner replies synchronously with the issued label_bindings[], then publishes a dispatch.label-issued.v1 follow-up event so the executor’s binding table is reconciled identically on both transports.
POST /wes/v1/labels/issue
{
"label_print_request_uuid": "01J7Y6K1NQ3W2C0X4V0R5T6E7Q",
"label_bindings": [
{
"bound_to_type": "container",
"bound_to_id": "frn:wes:intl:container/CTN-2026-001924",
"context_summary": {
"order_ids": ["ORD-2026-000183"],
"fulfilled_lines": 4,
"weight_g": 1320
}
}
]
}
200 OK
{
"issued_labels": [
{
"label_id": "1Z999AA10123456790",
"external_label_uri": "https://carrier.example/track/1Z999AA10123456790",
"bound_to_type": "container",
"bound_to_id": "frn:wes:intl:container/CTN-2026-001924",
"print_state": "printed",
"print_payload_uri": "https://planner.example/labels/print-payload/1Z999AA10123456790.zpl"
}
]
}
See the Label printing guide for end-to-end flow per pattern and the Advanced cartonization guide for the cartonizer-with-label sub-pattern variant.
Backpressure¶
If the planner returns 429 Too Many Requests, the executor must honor Retry-After and back off. Realtime is best-effort; missing one second of realtime is fine because the confirmation path is authoritative. Do not retry-storm on 429.