Outbound delivery to the schedule's target URL (action=webhook)
Webhook
For action: webhook, each due occurrence POSTs the schedule's payload
verbatim (JSON) to target.url, with target.headers applied and a hard
timeout of target.timeout_ms.
Headers sent on every attempt:
| Header | Value |
|---|---|
Content-Type | application/json |
X-Idempotency-Key | `sha256(schedule_id |
X-Schedule-Id | Schedule UUID |
X-Run-Id | JobRun UUID |
X-Attempt | Attempt number, starting at 1 |
X-Scheduled-For | Canonical un-jittered planned instant, RFC 3339 UTC |
X-Signature | sha256=<hex> — HMAC-SHA256 of the raw request body, keyed with the schedule's write-only secret |
traceparent | W3C trace context |
Semantics — at-least-once. A crashed executor or a 2xx lost on the wire
causes redelivery of the same run with the same X-Idempotency-Key (and an
incremented X-Attempt). Receivers MUST treat X-Idempotency-Key as the
dedupe key and make their side effects idempotent on it; do not dedupe on
X-Run-Id alone across catch-up replays, and never rely on at-most-once.
Receiver contract. Respond 2xx within timeout_ms to acknowledge
(response bodies are read at most 2 KiB, then discarded; only the status code
matters). Non-2xx handling: 408 and 429 are retried (429 honours a sane
Retry-After up to 1 h); other 4xx are permanent failures and are not
retried; 5xx, timeouts, and connection errors are retried with exponential
backoff and full jitter per the schedule's retry_policy, with the total
retry window capped at min(6h, schedule interval). Exhaustion marks the run
failed and emits schedule.run.failed.
Verify the signature by computing HMAC-SHA256(secret, raw_body) and
constant-time comparing against X-Signature after stripping the sha256=
prefix (same scheme as notification-service webhooks).
Request
Responses
- 200
Acknowledged — run transitions to succeeded (any 2xx accepted)