Skip to Content
GuidesWatch with triggers

Watch with triggers

A trigger evaluates a condition over a view as events arrive. When it fires, NavFlow pushes to any subscribed webhook — so an agent is woken with the relevant timeline instead of polling.

Have a view with a numeric field

Triggers aggregate a typed field, so the view must include a source that produces one. For example, a Prometheus source emitting rate_5xx, correlated into a service_timeline view keyed by service. See Connectors → prometheus and Concepts → views.

Define the trigger

A trigger names a view, a condition, what to emit, and a cooldown. Add it in the console (Views & Triggers) or in the catalog YAML:

triggers: - name: error_spike view: service_timeline condition: aggregate: max # count | sum | avg | max | min | any field: rate_5xx predicate: "> 1.0" # fire when max(rate_5xx) over the window exceeds 1.0 window: 1m group_by: [key_value] # evaluated per entity (per service) emit: kind: error_spike attach_view: true # include the entity's timeline in the dispatch context_window: 15m # how much timeline to attach cooldown: 5m # minimum gap between firings for the same entity

The condition is checked as events are ingested. group_by: [key_value] evaluates it per entity, so each service fires independently.

Subscribe an agent

An agent registers a webhook over MCP with the subscribe tool:

Use navflow to subscribe to the error_spike trigger and deliver to https://my-agent.example.com/hook.

subscribe(trigger, url) returns a subscription id. (You can also register via POST /subscribe.)

Receive dispatches

When the condition holds, NavFlow POSTs to each subscriber. With attach_view: true, the payload includes the entity’s correlated timeline over context_window — the deploy, the logs, the metrics around the spike — so the agent has context without making a follow-up call.

Firings and per-subscriber delivery status are listed in the console under Agents → Trigger dispatches.

cooldown prevents a flapping condition from firing repeatedly for the same entity. Pick different aggregates/fields for different incident shapes — e.g. max(p99_ms) > 1000 for latency vs max(rate_5xx) > 1.0 for an error storm.

Last updated on