Create a webhook in the ABV dashboard specifying where to send prompt change notifications.Navigate to Prompts → Webhooks:Click Create Webhook:Choose integration type:
Send notifications to Microsoft Teams, Discord, or custom chat platforms
Update documentation systems (Notion, Confluence, internal wikis)
Log changes to audit systems for compliance
Alert monitoring tools (PagerDuty, Datadog, New Relic)
Best for: Teams needing custom integrations beyond Slack, or requiring complex processing logic.Setup: See Custom Webhook Setup below.
Signature Verification (Security Best Practice)
Verify that webhook requests actually come from ABV and haven’t been tampered with using HMAC SHA-256 signatures.Why verify signatures:
Prevent unauthorized requests from malicious actors
Ensure payload integrity (data not modified in transit)
Production security requirement for sensitive systems
How it works:
ABV generates a signing secret when you create the webhook
ABV signs each request with HMAC SHA-256 using the secret
Signature included in x-abv-signature header (format: t=timestamp,s=signature)
Your endpoint recreates the signature and compares
Signature format:
x-abv-signature: t=1720701136,s=0123abcdef...
Security tip: Use constant-time comparison (hmac.compare_digest in Python, crypto.timingSafeEqual in Node.js) to prevent timing attacks.Implementation: See Signature Verification Code below.
Event and Prompt Filtering
Reduce noise by filtering which events trigger webhooks and which prompts are monitored.Event filtering:
Select which actions trigger webhooks:
Created: Only fire when new prompt versions are created
Updated: Only fire when labels or tags change
Deleted: Only fire when prompt versions are deleted
Default: all events selected.Prompt filtering:
Optionally filter to specific prompts by:
Prompt name patterns (e.g., only production/* prompts)
Tags (e.g., only prompts tagged critical)
Labels (e.g., only prompts with production label)
Example use case:
Production monitoring: Filter to only production-labeled prompts for critical alerts
Team-specific notifications: Filter by tags to route notifications to relevant Slack channels
Reduce noise: Only notify on created events, ignore label changes
Configuration: Set filters when creating or editing webhooks in the ABV UI.
Idempotent Handling (Reliability)
Design webhook handlers to be idempotent, as ABV retries failed webhook deliveries.Retry behavior:
ABV retries webhooks that return non-2xx status codes
Exponential backoff strategy (retries with increasing delays)
Continues until successful delivery or maximum retry limit
Idempotent handler design:
# Example: Use event ID to deduplicateprocessed_events = set() # In production, use Redis or databasedef handle_webhook(event): event_id = event["id"] # Skip if already processed if event_id in processed_events: return {"status": "already_processed"} # Process event send_slack_notification(event) # Mark as processed processed_events.add(event_id) return {"status": "success"}
Best practices:
Use event id for deduplication
Store processed event IDs in Redis, database, or cache
Always return 2xx on success to stop retries
Design operations to be safely repeatable (e.g., upsert instead of insert)
Webhook signature verification ensures requests actually come from ABV and haven’t been tampered with.Security benefits:
Authentication: Confirm request originated from ABV, not a malicious actor
Integrity: Verify payload wasn’t modified in transit
Non-repudiation: Prove ABV sent the specific payload
When verification is critical:
Production deployments triggered by webhooks
Webhooks that modify databases or external systems
Compliance requirements (audit trails, data integrity)
Public endpoints accessible from the internet
How it works:
ABV generates a signing secret when you create the webhook (copy and store securely)
For each request, ABV computes HMAC SHA-256 of timestamp.payload using the secret
Signature included in x-abv-signature header: t=<timestamp>,s=<signature>
Your handler recreates the signature and compares
Signature format:
x-abv-signature: t=1720701136,s=a1b2c3d4e5f6...
t: Unix timestamp when signature was generated
s: HMAC SHA-256 hex digest
Python Implementation
Verify webhook signatures in Python using the hmac module.Implementation:
import hmacimport hashlibfrom typing import Optionaldef verify_abv_signature( raw_body: str, signature_header: str, secret: str,) -> bool: """ Validate a ABV webhook/event signature. Parameters ---------- raw_body : str The request body exactly as received (no decoding or reformatting). signature_header : str The value of the `x-abv-signature` header, e.g. "t=1720701136,s=0123abcd...". secret : str Your ABV signing secret. Returns ------- bool True if the signature is valid, otherwise False. """ # Split "t=timestamp,s=signature" into the two expected key/value chunks try: ts_pair, sig_pair = signature_header.split(",", 1) except ValueError: # wrong format / missing comma return False # Extract values (everything after the first "=") if "=" not in ts_pair or "=" not in sig_pair: return False timestamp = ts_pair.split("=", 1)[1] received_sig_hex = sig_pair.split("=", 1)[1] # Recreate the message and compute the expected HMAC-SHA256 hex digest message = f"{timestamp}.{raw_body}".encode("utf-8") expected_sig_hex = hmac.new( secret.encode("utf-8"), message, hashlib.sha256 ).hexdigest() # Use constant-time comparison on the *decoded* byte strings try: return hmac.compare_digest( bytes.fromhex(received_sig_hex), bytes.fromhex(expected_sig_hex) ) except ValueError: # received_sig_hex isn't valid hex return False
Usage in FastAPI:
from fastapi import FastAPI, Request, HTTPException, HeaderWEBHOOK_SECRET = "your-signing-secret-from-abv"@app.post("/api/webhooks/abv-prompts")async def handle_webhook( request: Request, x_abv_signature: str = Header(...)): # Read raw body (important: don't decode or parse yet) raw_body = await request.body() # Verify signature if not verify_abv_signature(raw_body.decode(), x_abv_signature, WEBHOOK_SECRET): raise HTTPException(status_code=401, detail="Invalid signature") # Parse JSON after verification payload = await request.json() # Process webhook... return {"status": "received"}
Security notes:
Use hmac.compare_digest() for constant-time comparison (prevents timing attacks)
Verify signature before parsing or processing payload
Store signing secret in environment variables, not code
JavaScript/TypeScript Implementation
Verify webhook signatures in Node.js using the crypto module.Implementation:
Get alerted immediately when production prompts are updated to coordinate deployments and monitor for unexpected changes.Setup:
Create Slack webhook filtered to production label
Subscribe #production-alerts channel
Configure to trigger on created and updated events
Workflow:
Engineer updates prompt and assigns production label
Slack notification sent to #production-alerts
Team aware of change, can monitor for issues
If problems arise, easy to correlate with prompt update
Example Slack message:
🚨 Production Prompt UpdatedName: customer-support/billingVersion: 12Action: createdLabel: productionCommit: "Updated refund policy for EU customers"@channel - New billing prompt deployed
Team can immediately investigate if customer support tickets spike after the change.
Team Coordination
Keep cross-functional teams informed about prompt changes that affect their work.Setup:
Create multiple webhooks for different teams
Filter by tags (e.g., team:customer-support, team:marketing)
Route notifications to team-specific Slack channels
Example:
Customer support team: Notified of prompts tagged customer-support
Marketing team: Notified of prompts tagged marketing
Engineering team: Notified of all production prompts
Benefit: Each team sees only relevant changes, reducing notification fatigue while ensuring visibility.
Automated CI/CD Pipelines
Trigger automated testing and deployment workflows when prompts change.Setup:
Configure custom webhook to trigger GitHub Actions, Jenkins, or GitLab CI