Skip to main content
The state machine exposes a REST API for subscription management, event state, track/zone queries, and replay sessions. Base URL: http://n8n-state-machine:8080 (default)

Health

GET /health

Check if the service is running.
curl http://n8n-state-machine:8080/health
{ "status": "ok" }

Subscriptions

POST /api/subscriptions/

Register or update a webhook subscription.
curl -X POST http://n8n-state-machine:8080/api/subscriptions/my-workflow \
  -H "Content-Type: application/json" \
  -d '{
    "webhook_url": "http://n8n:5678/webhook/detections",
    "workflow_name": "obstruction-detection",
    "mode": "streaming",
    "signal_type": "track_state",
    "filters": {
      "datasource_ids": ["507eaeca-cc89-4501-9e0d-0d062a8f355d"],
      "tags": ["forklift", "person"]
    },
    "credentials": {
      "graphql_url": "https://your-instance.worlds.io/graphql",
      "ws_url": "wss://your-instance.worlds.io/graphql",
      "x_token_id": "your-token-id",
      "x_token_value": "your-token-value"
    }
  }'

GET /api/subscriptions

List all active subscriptions.

GET /api/subscriptions/

Get a specific subscription.

DELETE /api/subscriptions/

Remove a subscription. The state machine stops delivering signals for this subscription.
Subscriptions are managed automatically by the trigger nodes. You typically don’t need to call these endpoints directly.

Events (Event Orchestrator)

POST /api/events/

Check or create event state for a scope. Used by the Event Orchestrator node.
curl -X POST http://n8n-state-machine:8080/api/events/track-uuid-here \
  -H "Content-Type: application/json" \
  -d '{
    "scope_type": "track",
    "workflow_id": "workflow-uuid",
    "workflow_name": "obstruction-detection",
    "conditions_met": true
  }'

PATCH /api/events/

Update event state (e.g., store the global event ID after creation).

Track State

GET /api/tracks/

Query the current state of a track.
curl http://n8n-state-machine:8080/api/tracks/019bb7ea-4050-7e9b-8761-f8df773fd3e5
Returns the full track state object (position, velocity, zones, etc.).

GET /api/tracks/closest-frame

Find the detection frame closest to a given timestamp.
curl "http://n8n-state-machine:8080/api/tracks/closest-frame?track_id=019bb7ea&timestamp=2026-01-13T15:12:52Z"

POST /api/tracks/snapshot

Compute position, velocity, and zone membership for one or more tracks at specific historical timestamps. The endpoint analyzes raw detections within a configurable time window around each requested timestamp.
curl -X POST http://n8n-state-machine:8080/api/tracks/snapshot \
  -H "Content-Type: application/json" \
  -H "x-token-id: your-token-id" \
  -H "x-token-value: your-token-value" \
  -H "x-graphql-url: https://your-instance.worlds.io/graphql" \
  -d '{
    "tracks": [
      {
        "track_id": "019bb7ea-4050-7e9b-8761-f8df773fd3e5",
        "timestamp": "2026-01-13T15:12:52.000Z"
      }
    ],
    "window_seconds": 10
  }'
Request body:
FieldTypeRequiredDescription
tracksArrayYesOne or more track queries
tracks[].track_idStringYesTrack UUID to query
tracks[].timestampStringYesISO 8601 timestamp to compute the snapshot at
window_secondsNumberNoSeconds before and after the timestamp to include (default: 10)
Headers: x-token-id, x-token-value, and x-graphql-url are required when the track’s detections are not already cached in Redis (DB 3). The endpoint will fall back to the Worlds GraphQL API to fetch detections. Response body:
FieldTypeDescription
snapshotsObjectMap of track ID to snapshot (null if the track could not be resolved)
snapshots[].track_idStringTrack UUID
snapshots[].tagStringObject type tag (e.g., Person, Vehicle)
snapshots[].timestampStringThe requested timestamp
snapshots[].window_secondsNumberThe window used for computation
snapshots[].detections_in_windowNumberNumber of raw detections found in the window
snapshots[].positionObjectInterpolated position at the timestamp
snapshots[].position.methodStringreal, linear, forward_extrapolation, or backward_extrapolation
snapshots[].position.offset_msNumberMilliseconds between the requested timestamp and the nearest real detection
snapshots[].position.pixObjectPixel coordinates (x, y)
snapshots[].position.geoObjectGeographic coordinates (lon, lat), if available
snapshots[].position.polygonArrayInterpolated bounding box as a 4-point polygon
snapshots[].motionObjectVelocity and direction computed from detections in the window
snapshots[].motion.pixObjectPixel-space motion (avg_velocity, max_velocity, direction, sample_count)
snapshots[].motion.geoObjectGeographic motion (same fields), if available
snapshots[].zonesObjectZone membership at the timestamp
snapshots[].zones.active_at_timestampObjectMap of zone ID to zone data for zones the track intersected at the timestamp

Zone State

GET /api/zones/

Query the current state of a zone (active tracks, occupancy count).

Replay

POST /api/replay/

Start a replay session for testing.
curl -X POST http://n8n-state-machine:8080/api/replay/test-session \
  -H "Content-Type: application/json" \
  -d '{
    "track_ids": ["019bb7ea-4050-7e9b-8761-f8df773fd3e5"],
    "mode": "auto"
  }'

GET /api/replay/

Get replay session status.

DELETE /api/replay/

Stop and clean up a replay session.
Replay sessions are managed automatically by the Replay Trigger node. These endpoints are documented for debugging purposes.