Skip to main content
Most flows are guided: a run starts, events flow, the run reaches terminal and ends. A chat bot, a support inbox, or any webhook-driven service is different — it must be already running when the outside world calls. That is a standing flow: Swarm creates the flow’s instance and its webhook endpoint before reporting ready, keeps them alive across restarts — so the first webhook never arrives at a flow that isn’t up yet.

Declaring a standing flow

Activation is declared on the package’s flow entry — explicitly, never inferred:
package.yaml
The rules, all checked at verify:
  • activation: standing is valid only for mode: singleton flows (one instance for the whole system).
  • Standing without ingress is valid — a timer-driven or connect-fed always-on service.
  • ingress requires activation: standing, and its alias defaults to the flow id. The alias is one URL path segment: the endpoint is /webhooks/{alias}/{provider} — here, /webhooks/chat/telegram.
  • signing_secret is a deployment credential reference (resolved from the credential store at boot); the package never carries the value.
  • Every provider binding must line up with an external input pin consuming that provider’s events — a dangling ingress or an unfed pin is a verify error, not a runtime surprise.

Provider events, normalized

A provider pack (Telegram, Slack, Stripe, …) declares which webhooks it accepts and how they’re checked (admission), plus the normalized events — small, flat, typed versions of the provider payload that your flow subscribes to. Your contracts consume inbound.telegram.text_message with typed flat fields; the pack owns signature verification, payload dispatch, and field extraction. You never parse a raw webhook body in a handler.
agents.yaml
If a provider has no signature scheme, or you’re testing locally, say so explicitly in the admission declaration; otherwise Swarm warns at boot that a public endpoint is unsigned.

Lifecycle: what “standing” means operationally

  • Materialized before ready: the standing instance, its routes, and its agents exist before the runtime reports readiness — the first webhook never races activation.
  • Durable across restarts: the service’s identity is stable (derived from package + flow id); a restart reconciles the declared set against the store and resumes, it does not re-create. Removing or renaming the flow in a later revision marks the old service as orphaned: it stops taking work but stays paused and inspectable rather than deleted.
  • Operator control: suspend, resume, and reset act on the same durable identity and survive restart.
For exposing the local endpoint during development (for example through a tunnel to receive real provider webhooks), see Running the runtime.