Why it exists
Raw detection streams from the Worlds API arrive at high frequency — potentially hundreds of detections per second across multiple cameras. Processing these directly in the Workflow Builder would cause:- Race conditions — multiple detections for the same track arriving simultaneously
- Incomplete data — individual detections lack context like velocity, dwell time, and zone intersection
- Resource exhaustion — the Workflow Builder would need a WebSocket connection per workflow per camera
What it does
Track state management
The state machine aggregates individual detections into coherent tracks. Each track maintains:- Current position (pixel + geo)
- Velocity (rolling average in px/s and m/s)
- Active zones with dwell times and intersection percentages
- Zone history (previously visited zones)
- Zone sequence (order of zone visits)
- Detection count and age
Signal generation
The state machine emits three track signal types to your workflows:Zone state management
The state machine also tracks zone state — aggregate occupancy for the zones you’re monitoring, independent of any single track. Zone state is available only in streaming mode; zones don’t expire the way tracks do, so there’s no batch equivalent. Each zone maintains:- Active tracks, with per-track dwell time and zone intersection percentage
- Total active track count
- The filtered object composition (tag → count) for each subscription watching the zone
Composition emit mode
By default (zone_emit_mode: "all"), a subscription receives zone_updated on every detection in an occupied zone. Opt in per subscription with zone_emit_mode: "composition" to instead emit zone_updated only when the zone’s composition changes:
- Composition is a tag → count map of the subscription’s filtered view of the zone — a subscription filtered to
[person, dock door]isn’t woken when a forklift enters. Composition is compared by tag counts, not track IDs, so re-identification churn (the same physical object briefly reassigned a new track ID) stays suppressed, while a real change like person 2 → 1 always emits. zone_occupiedandzone_emptyalways emit regardless of mode — onlyzone_updatedis subject to comparison.- Lazy heartbeat: if a
zone_updatedwould otherwise be suppressed butheartbeat_seconds(default 30) has elapsed since the last emit for that zone, the state machine emits anyway. There are no background timers — the heartbeat piggybacks on the incoming detection stream, so it only fires while the zone remains occupied. - Emit reason: composition-mode
zone_updatedpayloads carry a top-levelemit_reasonfield —"composition_changed"for a real change (or the first emit after a restart),"heartbeat"for a periodic re-emit — so workflows can distinguish a change from a retry tick. The field is absent in"all"mode and onzone_occupied/zone_empty. - Suppression state is held in memory. A state machine restart causes one unconditional
zone_updatedemit per occupied zone — a harmless “no change” execution downstream. Streaming auto replay uses an isolated emitter; manual replay routes through the production emitter.
zone_emit_mode and heartbeat_seconds fields on POST /api/subscriptions/{id}, or via the Zone Emit Mode / Heartbeat (Seconds) options under Advanced Options on the Detection Webhook Trigger.
Per-datasource ordering
Detections are processed sequentially per data source (camera). This prevents race conditions — your workflow is guaranteed to process signals for a given camera in order.Subscription management
Workflows register with the state machine via webhook URLs. The state machine:- Matches detections against registered subscriptions by data source, object type, and zone
- Delivers only matching signals to each workflow
- Reuses WebSocket connections across subscriptions sharing the same credentials
Architecture
Redis database layout
The state machine uses multiple Redis databases for isolation:Configuration
Key environment variables:Batch processing
For workflows that need complete track data and track-to-track interactions, the state machine supports batch mode:- Stores raw detections in DB3
- Emits tracks only when they expire (complete lifecycle)
- Calculates track-to-track interactions (bounding box overlap, proximity)
- Delivers batch payloads at configurable intervals

