Webhooks
Webhooks deliver App-qualified events to an HTTPS endpoint bound to an entitled API client. Each request is signed over the exact payload bytes and a timestamp.
Webhook endpoint and secret administration is currently operator-managed in Vision. A public registration API and certified event catalog are not yet part of the preview OpenAPI contract.
Endpoint requirements
Endpoints must use HTTPS, match the environment allowlist, and resolve only to permitted public addresses. Loopback, private, link-local, reserved, and metadata-service destinations are rejected at registration and delivery.
Verify a delivery
Node.js verification outline
import { createHmac, timingSafeEqual } from 'node:crypto'
const signed = `${timestamp}.${rawBody}`
const expected = createHmac('sha256', webhookSecret)
.update(signed)
.digest('hex')
const expectedBytes = Buffer.from(expected, 'hex')
const signatureBytes = Buffer.from(signature, 'hex')
const valid =
expectedBytes.length === signatureBytes.length &&
timingSafeEqual(expectedBytes, signatureBytes)
Reject stale timestamps before processing. Compare signatures in constant time and record the event ID before applying side effects.
Retries and idempotency
Return a 2xx response only after durable acceptance. Retryable failures use bounded exponential delay. Permanent policy failures stop immediately, and exhausted deliveries remain visible to administrators.
Secret lifecycle
Webhook secrets are shown once, encrypted at rest with AES-256-GCM, and independently rotatable. During a bounded overlap, verify against the active and overlap secret versions. Never log the secret or complete signature header.