Skip to main content
The state machine is a Go service that sits between the Worlds detection API and your workflows. It subscribes to live detection streams, maintains track and zone state, and delivers enriched signals to your workflows via webhooks.

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
The state machine solves all three problems.

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_occupied and zone_empty always emit regardless of mode — only zone_updated is subject to comparison.
  • Lazy heartbeat: if a zone_updated would otherwise be suppressed but heartbeat_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_updated payloads carry a top-level emit_reason field — "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 on zone_occupied/zone_empty.
  • Suppression state is held in memory. A state machine restart causes one unconditional zone_updated emit per occupied zone — a harmless “no change” execution downstream. Streaming auto replay uses an isolated emitter; manual replay routes through the production emitter.
Configure this via the 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
See the Detection Webhook Trigger batch mode for configuration.