airmy.dev / developers / webhooks

Webhooks

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

EventFired WhenPayload
run.completedAgent run finished successfullyFull run object
run.failedAgent run failed or timed outRun object + error details
deployment.createdNew deployment createdDeployment object
deployment.rollbackRollback triggeredDeployment object + reason
alert.triggeredMonitoring alert firedAlert + metric snapshot
agent.updatedAgent configuration changedAgent diff (old + new)
pipeline.completedPipeline run finishedPipeline 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.