Skip to main content

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:

HeaderValue
Content-Typeapplication/json
X-Idempotency-Key`sha256(schedule_id
X-Schedule-IdSchedule UUID
X-Run-IdJobRun UUID
X-AttemptAttempt number, starting at 1
X-Scheduled-ForCanonical un-jittered planned instant, RFC 3339 UTC
X-Signaturesha256=<hex> — HMAC-SHA256 of the raw request body, keyed with the schedule's write-only secret
traceparentW3C 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

Acknowledged — run transitions to succeeded (any 2xx accepted)