# Capability Spec: webhook-client **Package**: `@suaveplan/webhook-client` **Version**: 0.0.0 (genesis) **Status**: ADDED --- ## ADDED Requirements ### WH-01 — Signature schemes `SignatureScheme` MUST include `'hmac-sha256'` and `'jws'`. `WebhookVerifier.verify(request, config)` MUST compute the signature per scheme and compare in constant time. Mismatches MUST throw `WEBHOOK.INVALID_SIGNATURE`. ### WH-02 — Replay protection `WebhookConfig.maxSkewSeconds` (default 300) MUST bound the accepted timestamp delta. Requests outside the skew MUST throw `WEBHOOK.REPLAY_DETECTED`. The verifier MUST include the timestamp in the signing-string. ### WH-03 — Parse contract `WebhookParser.parse(request)` MUST accept `application/json`, `application/x-www-form-urlencoded`, and `text/plain`. Payloads MUST be Zod-validated against the configured `WebhookSchema`. Validation failures MUST throw `WEBHOOK.SCHEMA_MISMATCH`. ### WH-04 — Receiver `WebhookReceiver.handle(request)` MUST run verify → parse → dispatch-listeners. Listener exceptions MUST be captured per-listener, emit `WEBHOOK.LISTENER_ERROR` with context, and continue with the remaining listeners. ### WH-05 — Hooks `webhookHooks.delivering` MUST fire with `WebhookDeliveringHookData { event, listener, startedAt }` before each listener invocation. Handlers MUST be able to veto delivery by throwing. ### WH-06 — Observability Every `handle` call MUST record `webhook.receive.duration_ms`; every verify MUST record `webhook.verify.duration_ms`; outcome counters MUST label `scheme` and `result`.