concepts / sinks

Sinks

A sink is where Kite delivers an event after it leaves the relay. Sinks can be a terminal window, an HTTP endpoint, a file, or an agent runtime. Use a manifest to route one event to multiple sinks simultaneously.

Sink types

terminal

Stream events to stdout. Default sink when running kite stream.

$ kite stream
http

Forward events to a local or remote HTTP endpoint.

$ kite listen stripe --forward http://localhost:8080/webhook
file

Append events to a newline-delimited JSON file.

$ kite stream --json >> events.ndjson
openclaw

Feed events directly into an OpenClaw agent runtime via Unix socket.

$ kite listen --sink openclaw://localhost:5000

Delivery guarantees

Kite delivers to HTTP sinks with at-least-once semantics. If your sink returns a non-2xx response, Kite retries with exponential backoff and jitter:

AttemptDelay
1st retry1 s + jitter
2nd retry4 s + jitter
3rd retry16 s + jitter
4th retry64 s + jitter
Give upEvent logged as undelivered

Idempotency is derived from the CloudEvent id + source. Your handler should be idempotent for safe retries.

Multi-sink routing via manifest

Use kite.json to fan out one event to multiple sinks, or route by event type:

{
  "sources": [
    { "name": "stripe", "type": "stripe",
      "verify": { "secretEnv": "STRIPE_WEBHOOK_SECRET" } }
  ],
  "sinks": [
    { "name": "agent",  "type": "http",      "url": "http://localhost:8080/webhook" },
    { "name": "log",    "type": "file",      "path": "./events.ndjson" },
    { "name": "alerts", "type": "openclaw",  "url": "openclaw://localhost:5000" }
  ],
  "routes": [
    { "match": { "type": "com.stripe.payment_intent.payment_failed" },
      "to": ["agent", "alerts"] },
    { "match": { "type": "com.stripe.*" },
      "to": ["agent", "log"] }
  ]
}

Routes are evaluated top-to-bottom. An event matches the first rule whose match expression is satisfied. See the manifest reference for filtering, enrichment, and scoring options.

OpenClaw agent sink

The openclaw sink delivers CloudEvents directly into an agent loop via Unix socket or TCP. The agent receives a fully verified CloudEvent and can act autonomously — no polling, no web server required.

$ kite listen github --sink openclaw://localhost:5000

Next: Security

Learn how Kite verifies signatures and protects your webhook pipeline in the Security guide.