Skip to content

Webhooks notify external services when events occur in your repository. Build integrations, trigger deployments, and automate workflows.

Event Types

EventDescription
pushCode pushed
pull_requestPR opened, updated, merged
issueIssue created, updated, closed
commentComment added
releaseRelease published
pipelineCI/CD status changed
agentAgent action performed

Creating Webhooks

Via Web UI

  1. Go to SettingsWebhooks
  2. Click Add Webhook
  3. Configure:
    • Payload URL: Your endpoint
    • Content Type: application/json
    • Secret: For HMAC verification
    • Events: Select which to receive
  4. Click Add Webhook

Via API

bash
curl -X POST /api/v1/repos/org/repo/webhooks \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "url": "https://example.com/webhook",
    "content_type": "json",
    "secret": "your-webhook-secret",
    "events": ["push", "pull_request"]
  }'

Payload Format

Push Event

json
{
  "event": "push",
  "repository": {
    "name": "my-repo",
    "full_name": "org/my-repo",
    "url": "https://kizuna.example.com/org/my-repo"
  },
  "ref": "refs/heads/main",
  "before": "abc123...",
  "after": "def456...",
  "commits": [
    {
      "id": "def456...",
      "message": "Fix authentication",
      "author": {
        "name": "Alice",
        "email": "alice@example.com"
      }
    }
  ],
  "sender": {
    "login": "alice",
    "type": "User"
  }
}

Pull Request Event

json
{
  "event": "pull_request",
  "action": "opened",
  "number": 42,
  "pull_request": {
    "title": "Add OAuth support",
    "body": "Implements OAuth2...",
    "state": "open",
    "head": {
      "ref": "feature/oauth",
      "sha": "abc123..."
    },
    "base": {
      "ref": "main",
      "sha": "def456..."
    }
  },
  "repository": { ... },
  "sender": { ... }
}

Securing Webhooks

HMAC Verification

Kizuna signs payloads with your secret:

X-Kizuna-Signature: sha256=abc123...

Verify in your endpoint:

python
import hmac
import hashlib

def verify_signature(payload, signature, secret):
    expected = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)

IP Allowlisting

Webhook requests come from:

203.0.113.0/24
198.51.100.0/24

Allow only these IPs in your firewall.

Delivery

Retry Logic

Kizuna retries failed deliveries:

AttemptDelay
1Immediate
21 minute
35 minutes
430 minutes

Delivery Status

View in SettingsWebhooks:

Webhook: https://example.com/webhook
├── Deliveries: 1,247
├── Successful: 1,245
└── Failed: 2

Recent Deliveries:
├── 2026-03-10 09:00:00 ✓ Success
├── 2026-03-10 08:55:00 ✓ Success
└── 2026-03-10 08:50:00 ✗ Failed (500)

Redeliver

Manually retry failed deliveries:

bash
curl -X POST /api/v1/webhooks/123/deliveries/456/retry \
  -H "Authorization: Bearer $TOKEN"

Example Integrations

Slack Notifications

javascript
// Webhook endpoint
app.post('/webhook', (req, res) => {
  const { event, pull_request } = req.body;
  
  if (event === 'pull_request' && req.body.action === 'opened') {
    slack.send({
      channel: '#dev',
      text: `New PR: ${pull_request.title}`
    });
  }
  
  res.sendStatus(200);
});

Deploy on Merge

python
@app.route('/webhook', methods=['POST'])
def webhook():
    data = request.json
    
    if data['event'] == 'pull_request':
        if data['action'] == 'closed' and data['pull_request']['merged']:
            deploy_to_production()
    
    return '', 200

Update External Systems

javascript
app.post('/webhook', async (req, res) => {
  const { event, issue } = req.body;
  
  if (event === 'issue') {
    await jira.syncIssue({
      key: issue.number,
      title: issue.title,
      status: issue.state
    });
  }
  
  res.sendStatus(200);
});

Testing Webhooks

Ping Event

Test webhook without real events:

bash
curl -X POST /api/v1/webhooks/123/ping \
  -H "Authorization: Bearer $TOKEN"

Local Testing

Use ngrok for local development:

bash
# Start ngrok
ngrok http 3000

# Use ngrok URL as webhook URL
# https://abc123.ngrok.io/webhook

Managing Webhooks

List Webhooks

bash
curl /api/v1/repos/org/repo/webhooks

Update Webhook

bash
curl -X PATCH /api/v1/repos/org/repo/webhooks/123 \
  -d '{"events": ["push", "pull_request", "release"]}'

Delete Webhook

bash
curl -X DELETE /api/v1/repos/org/repo/webhooks/123

Summary

Webhooks enable:

  • Real-time integration — React to events instantly
  • External automation — Trigger outside systems
  • Notifications — Slack, email, etc.
  • Custom workflows — Build your own logic

They're the bridge between Kizuna and your external tools.