Webhooks

Subscribe to Asqav events and receive them as signed HTTP POSTs to your endpoint. Available on all tiers.

Create a webhook

The secret is generated server-side and returned exactly once. Store it. Use it to verify every incoming request.

bash
curl -X POST https://api.asqav.com/api/v1/alerts/webhooks \
  -H "X-API-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/asqav","events":["*"]}'

Response:

json
{
  "id": "wh_...",
  "url": "https://example.com/asqav",
  "secret": "whsec_...",
  "events": ["*"],
  "created_at": "2026-04-19T12:00:00+00:00"
}

Delivery format

Every delivery has two headers and a JSON body:

HeaderValue
X-Asqav-Signaturesha256=<hex>
X-Asqav-TimestampUnix seconds when the event was sent

The signature is HMAC-SHA256 over <timestamp>.<body> where body is the compact JSON with sorted keys.

Verification

Verify by recomputing HMAC-SHA256 over timestamp + '.' + body_compact_sorted with your webhook secret. Your receiver MUST parse the JSON body then re-serialize with json.dumps(body, sort_keys=True, separators=(',', ':')) before computing HMAC. Asqav's backend normalizes this way, and variations in whitespace will break verification.

Verify a delivery

python
import hmac, hashlib, json, time

def verify(secret, headers, raw_body, tolerance=300):
    ts = headers["X-Asqav-Timestamp"]
    sig = headers["X-Asqav-Signature"].split("=", 1)[1]

    if abs(time.time() - int(ts)) > tolerance:
        raise ValueError("stale webhook")

    body = json.dumps(json.loads(raw_body), separators=(",", ":"), sort_keys=True)
    expected = hmac.new(secret.encode(), f"{ts}.{body}".encode(), hashlib.sha256).hexdigest()

    if not hmac.compare_digest(expected, sig):
        raise ValueError("bad signature")

Rotate the secret

If a secret leaks, rotate it. The response returns a new secret once.

bash
curl -X POST https://api.asqav.com/api/v1/alerts/webhooks/wh_.../rotate \
  -H "X-API-Key: sk_live_..."
Integrations

If the URL points to Slack, Discord, or Microsoft Teams, Asqav formats the payload for that channel automatically. For generic endpoints you receive the raw event JSON.

Manage webhook subscriptions from the terminal with asqav webhooks (list, create, delete).