Local URL target
A local URL target is the HTTP-webhook side of Dial’s fan-out. You register a loopback URL with the listen daemon and, for every account event, the daemon POSTs the event JSON to that URL. Long-lived services on the same machine (an agent runtime, a workflow engine, a queue) pick the event up like any other webhook.
When to use it
- The receiver is a process that’s already running and listens on a loopback port.
- You want HMAC signing or a bearer token to authenticate Dial’s POSTs.
- You’re wiring into a product that already understands webhooks — most agent frameworks fall here.
If the receiver is a script you’d normally spawn from a shell, the CLI command target is simpler and avoids running an HTTP server.
Prerequisites
The listen daemon owns the fan-out queue and is what makes the outgoing POSTs. See Listen service.
Loopback only
The URL must be http:// or https:// and resolve to a local loopback host — 127.0.0.1, 0.0.0.0, localhost, ::1, or [::1]. Public URLs are rejected. This is intentional: Dial events stay on the machine the daemon runs on; cross-network delivery is a job for our forthcoming durable webhooks.
Register
For each event, the daemon issues:
See dial local-target add url for the full reference.
Authenticate the receiver
By default the POST has no auth — fine on loopback for casual setups, but most receivers want at least one of:
HMAC signing
The daemon computes HMAC-SHA256(secret, body) per request and puts the hex digest in the header named by --signature-header (defaults to X-Dial-Signature). The receiver recomputes the digest from the raw body and rejects mismatches. Good fit for systems that expect a per-subscription HMAC, like Hermes Agent.
Bearer token
The daemon sends Authorization: Bearer <token> on every POST. Good fit for systems that gate the endpoint with a shared static token, like OpenClaw.
You can also combine --bearer with --secret if the receiver wants both.
Delivery semantics
- 2xx — treated as delivered.
- Non-2xx, connection error, or timeout — the daemon retries the request once. If the retry also fails, the event is logged and dropped; nothing is queued for later.
- Timeout —
--timeout <seconds>per attempt, defaulting to5. - Concurrency — requests to the same target run independently; the daemon doesn’t serialize them, so make your handler safe to run twice in close succession (the once-retry can produce that).
- The event stream the daemon consumes is presence-based (not at-least-once), so an event the daemon never received cannot be recovered from the server side. For guaranteed delivery, register an at-least-once webhook.
Verify, list, remove
No daemon restart is required for any of these — the fan-out registry updates on the fly.