Skip to main content
Webhooks allow you to receive real-time notifications when events occur in your Kodo account.

How It Works

  1. You provide an endpoint URL
  2. Kodo sends HTTP POST requests when events occur
  3. Your server processes the events

Webhook Payload

All webhooks include this structure:
{
  "event": "incident.created",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    // Event-specific data
  }
}

Event Types

Incident Events

{
  "event": "incident.created",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "id": "uuid",
    "title": "Database connectivity issues",
    "status": "investigating",
    "severity": "major",
    "services": ["API", "Database"],
    "message": "We are investigating..."
  }
}

Service Events

{
  "event": "service.status_changed",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "id": "uuid",
    "name": "API Gateway",
    "previous_status": "operational",
    "new_status": "degraded"
  }
}

Monitor Events

{
  "event": "monitor.down",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "id": "uuid",
    "name": "API Health Check",
    "url": "https://api.example.com/health",
    "error": "Connection timeout"
  }
}

Verifying Webhooks

We sign all webhook requests with your signing secret. Verify the signature to ensure requests are from Kodo:
const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// In your webhook handler
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-kodo-signature'];
  const payload = JSON.stringify(req.body);

  if (!verifyWebhook(payload, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  // Process webhook
  const { event, data } = req.body;
  // ...

  res.status(200).send('OK');
});

Retry Policy

If your endpoint returns a non-2xx status code, we retry:
AttemptDelay
1st retry1 minute
2nd retry5 minutes
3rd retry30 minutes
4th retry2 hours
5th retry24 hours
After 5 failed attempts, the webhook is disabled and you’re notified.

Best Practices

Return a 2xx response immediately, then process asynchronously. We timeout after 30 seconds.
Use the event ID to deduplicate. Network issues may cause retries even on success.
Always verify the webhook signature in production.
Webhook URLs must use HTTPS for security.

Managing Webhooks via CLI

# List webhooks
kodo webhooks list

# Create webhook
kodo webhooks create \
  --name "Deploy hook" \
  --url "https://example.com/webhook" \
  --events "incident.created,incident.resolved"

# View details and delivery history
kodo webhooks get WEBHOOK_ID

# Test a webhook
kodo webhooks test WEBHOOK_ID

# Activate/deactivate
kodo webhooks update WEBHOOK_ID --active
kodo webhooks update WEBHOOK_ID --inactive

# Delete
kodo webhooks delete WEBHOOK_ID --force

Testing Webhooks

kodo webhooks test WEBHOOK_ID
You can also use a service like webhook.site during development.