Skip to content

Webhook Events

Cortex delivers events to registered webhook URLs via HTTP POST. Use webhooks for event-driven automation, CI/CD integration, and alerting.

Registering a Webhook

bash
curl -X POST https://api.cortex.acrobi.com/api/webhooks/register \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/cortex-webhook",
    "events": ["agent.completed", "agent.failed", "task.status_changed"],
    "secret": "your-webhook-secret"
  }'

Response:

json
{
  "id": "wh-abc123",
  "url": "https://your-server.com/cortex-webhook",
  "events": ["agent.completed", "agent.failed", "task.status_changed"],
  "createdAt": "2026-04-03T12:00:00.000Z"
}

Supported Events

EventTrigger
task.createdNew task created
task.completedTask moved to done status
task.status_changedAny task status transition
agent.spawnedAgent execution started
agent.completedAgent execution finished successfully
agent.failedAgent execution errored

Webhook Payload

All webhooks deliver a JSON payload with this structure:

json
{
  "event": "agent.completed",
  "data": {
    "agentId": "agent-123",
    "agentName": "my-coder-agent",
    "taskId": "task-456",
    "result": "Code review completed",
    "duration": 12500,
    "timestamp": "2026-04-03T12:05:00.000Z"
  },
  "timestamp": "2026-04-03T12:05:00.123Z"
}

Security Headers

Every webhook delivery includes these verification headers:

HeaderDescription
X-Cortex-SignatureHMAC-SHA256 signature of the payload body
X-Cortex-EventEvent type (e.g., agent.completed)
X-Cortex-DeliveryUnique delivery ID (UUID)
X-Cortex-TimestampISO 8601 timestamp of the delivery

Verifying Webhook Signatures

Verify the X-Cortex-Signature header to ensure the payload is authentic:

Node.js

javascript
const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(`sha256=${expected}`)
  );
}

// In your handler:
app.post('/cortex-webhook', (req, res) => {
  const payload = JSON.stringify(req.body);
  const signature = req.headers['x-cortex-signature'];
  
  if (!verifyWebhook(payload, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process the event
  const { event, data } = req.body;
  console.log(`Received ${event}:`, data);
  res.status(200).send('OK');
});

Python

python
import hmac
import hashlib

def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    expected = 'sha256=' + hmac.new(
        secret.encode(), payload, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

Testing Webhooks

Send a test payload to verify your endpoint:

bash
curl -X POST https://api.cortex.acrobi.com/api/webhooks/wh-abc123/test \
  -H "Authorization: Bearer $TOKEN"

Delivery History

View delivery attempts and their status:

bash
curl https://api.cortex.acrobi.com/api/webhooks/wh-abc123/deliveries \
  -H "Authorization: Bearer $TOKEN"

Response:

json
{
  "deliveries": [
    {
      "id": "del-001",
      "event": "agent.completed",
      "status": "delivered",
      "responseCode": 200,
      "duration": 150,
      "timestamp": "2026-04-03T12:05:00.000Z"
    },
    {
      "id": "del-002",
      "event": "agent.failed",
      "status": "failed",
      "responseCode": 500,
      "retries": 3,
      "timestamp": "2026-04-03T12:10:00.000Z"
    }
  ]
}

Extended Activity Events (WebSocket Only)

These additional events are available via WebSocket but not delivered to webhooks:

EventDescription
agent.statusReal-time status changes (error/blocked)
task.updatedTask detail modifications
task.deletedTask removals
chief.plan.createdChief coordinator created a plan
chief.task.assignedChief assigned task to agent
chief.task.progressTask progress update
swarm.phase.startedSwarm entered new phase
swarm.phase.completedSwarm phase finished
gate.passedQuality gate passed
gate.failedQuality gate failed
chat.messageNew chat message

Built by Acrobi