Overview
Webhooks let AIRMY notify your system when important events happen — agent runs complete, deployments succeed or roll back, alerts fire. They are more efficient than polling the API and enable real-time integrations with your existing ops tooling.
When to use webhooks vs polling: use webhooks when you need near-real-time notification of events. Use polling (e.g. GET /runs/{id}) when you need the result of a specific operation synchronously.
Configuring Webhooks
Via Dashboard
Navigate to Settings → Webhooks → Create Webhook. Enter your endpoint URL, select the events to subscribe to, and optionally provide a signing secret.
Via API
POST /webhooks
{
"url": "https://your-app.example.com/hooks/airmy",
"events": ["run.completed", "run.failed", "deployment.rollback"],
"secret": "whsec_...",
"active": true
}Event Types
| Event | Fired When | Payload |
|---|---|---|
| run.completed | Agent run finished successfully | Full run object |
| run.failed | Agent run failed or timed out | Run object + error details |
| deployment.created | New deployment created | Deployment object |
| deployment.rollback | Rollback triggered | Deployment object + reason |
| alert.triggered | Monitoring alert fired | Alert + metric snapshot |
| agent.updated | Agent configuration changed | Agent diff (old + new) |
| pipeline.completed | Pipeline run finished | Pipeline run object |
Payload Structure
All webhook payloads share a standard envelope:
{
"id": "evt_01HXYZ",
"type": "run.completed",
"created_at": "2026-03-22T14:30:00Z",
"data": {
"id": "run_01HXYZ123",
"agent_id": "ag_01HXYZ",
"status": "completed",
"output": { "result": "..." },
"latency_ms": 48,
"tokens_used": 1247
}
}Verifying Signatures
AIRMY signs every webhook delivery with an HMAC-SHA256 signature using your signing secret. The signature is sent in the X-AIRMY-Signature header.
Python
import hmac, hashlib
def verify(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)Node.js
const crypto = require('crypto');
function verify(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected), Buffer.from(signature)
);
}Go
func verify(payload []byte, sig, secret string) bool {
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(payload)
expected := hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(expected), []byte(sig))
}Retry Policy
AIRMY makes 3 delivery attempts with exponential backoff: 1s, 5s, 30s. A delivery is considered acknowledged when your endpoint returns a 2xx status code within 10 seconds.
View delivery history for any webhook from the dashboard under Settings → Webhooks → [webhook] → Deliveries. Each delivery shows the request body, response, and HTTP status code.
Testing Webhooks
Send a test event from the CLI:
airmy webhooks test <webhook-id>Or use the “Send Test Event” button in the dashboard on any webhook's detail page. The test payload uses the same schema as real events with a "type": "test" field.