Webhooks
Receiving and verifying webhook events from SwiftClaw
Webhooks
Webhooks allow SwiftClaw to notify your application when events occur.
Setting Up Webhooks
Create Webhook Endpoint
# Register webhook URL
swiftclaw webhooks create my-agent \
--url https://yourapp.com/webhooks/swiftclaw \
--events agent.invoked,agent.completed,agent.failedConfigure Events
Choose which events to receive:
swiftclaw webhooks update my-agent webhook-123 \
--events agent.invoked,agent.completed,agent.failed,agent.timeoutWebhook Events
Agent Events
agent.invoked: Agent received requestagent.completed: Agent finished processingagent.failed: Agent encountered erroragent.timeout: Agent exceeded time limit
Deployment Events
deployment.started: Deployment initiateddeployment.completed: Deployment successfuldeployment.failed: Deployment failed
System Events
system.maintenance: Scheduled maintenancesystem.incident: System incident
Webhook Payload
Example Payload
{
"id": "evt_abc123",
"type": "agent.completed",
"created": 1709884800,
"data": {
"agent": "my-agent",
"request_id": "req_xyz789",
"duration": 1250,
"tokens_used": 450,
"response": {
"message": "Task completed successfully"
}
}
}Verifying Webhooks
Signature Verification
SwiftClaw signs all webhooks with HMAC-SHA256:
import hmac
import hashlib
def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
# Usage
@app.post("/webhooks/swiftclaw")
async def handle_webhook(request):
payload = await request.body()
signature = request.headers.get("X-SwiftClaw-Signature")
if not verify_webhook(payload, signature, webhook_secret):
return {"error": "Invalid signature"}, 401
# Process webhook
event = json.loads(payload)
await process_event(event)
return {"received": True}Node.js Example
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
app.post('/webhooks/swiftclaw', (req, res) => {
const signature = req.headers['x-swiftclaw-signature'];
if (!verifyWebhook(req.rawBody, signature, webhookSecret)) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process webhook
const event = req.body;
processEvent(event);
res.json({ received: true });
});Handling Webhooks
Idempotency
Handle duplicate webhooks:
processed_events = set()
async def handle_webhook(event):
event_id = event["id"]
# Check if already processed
if event_id in processed_events:
return {"status": "already_processed"}
# Process event
await process_event(event)
# Mark as processed
processed_events.add(event_id)
return {"status": "processed"}Error Handling
Return appropriate status codes:
@app.post("/webhooks/swiftclaw")
async def handle_webhook(request):
try:
event = await request.json()
await process_event(event)
return {"received": True}, 200
except ValueError:
return {"error": "Invalid JSON"}, 400
except Exception as e:
# Log error
logger.error(f"Webhook processing failed: {e}")
# Return 500 to trigger retry
return {"error": "Processing failed"}, 500Retry Logic
SwiftClaw retries failed webhooks:
- Retry Schedule: 1m, 5m, 15m, 1h, 6h
- Max Retries: 5 attempts
- Success Codes: 200-299
- Retry Codes: 500-599
Return 2xx for Success: Always return 200-299 status codes for successfully processed webhooks.
Testing Webhooks
Test Endpoint
# Send test webhook
swiftclaw webhooks test my-agent webhook-123Local Testing
Use ngrok for local development:
# Start ngrok
ngrok http 3000
# Register ngrok URL
swiftclaw webhooks create my-agent \
--url https://abc123.ngrok.io/webhooks/swiftclawManaging Webhooks
List Webhooks
swiftclaw webhooks list my-agentUpdate Webhook
swiftclaw webhooks update my-agent webhook-123 \
--url https://newurl.com/webhooks \
--events agent.completed,agent.failedDelete Webhook
swiftclaw webhooks delete my-agent webhook-123Webhook Logs
View webhook delivery logs:
# View recent deliveries
swiftclaw webhooks logs my-agent webhook-123
# View failed deliveries
swiftclaw webhooks logs my-agent webhook-123 --failedBest Practices
1. Verify Signatures
Always verify webhook signatures:
if not verify_webhook(payload, signature, secret):
raise Unauthorized("Invalid signature")2. Process Asynchronously
Queue webhooks for background processing:
@app.post("/webhooks/swiftclaw")
async def handle_webhook(request):
event = await request.json()
# Queue for processing
await queue.enqueue(process_event, event)
# Return immediately
return {"received": True}3. Handle Duplicates
Use idempotency keys:
@app.post("/webhooks/swiftclaw")
async def handle_webhook(request):
event = await request.json()
event_id = event["id"]
# Check if processed
if await db.exists(event_id):
return {"status": "already_processed"}
# Process and store
await process_event(event)
await db.store(event_id)
return {"status": "processed"}4. Monitor Failures
Set up alerts for webhook failures:
swiftclaw alerts create \
--agent my-agent \
--metric webhook-failures \
--threshold 5 \
--window 1hNext Steps
How is this guide ?
Last updated on