Skip to main content
Documentation

Webhooks & Events

Real-time notifications for repository events, enabling CI/CD pipelines, Slack notifications, and automated workflows.

Event-Driven Automation

Webhooks deliver real-time notifications about repository activity, enabling powerful integrations and automated workflows across your creative pipeline.

25+
Event Types
Real-time
Delivery
Secure
Signatures

Supported Events

Repository Events
repo.created
New repository
repo.deleted
Repository removed
repo.updated
Settings changed
repo.transferred
Ownership changed
Push Events
push
Commits pushed
push.tag
Tag pushed
push.force
Force push
Branch & Tag Events
branch.created
New branch
branch.deleted
Branch removed
tag.created
New tag
Collaboration Events
member.added
User added
member.removed
User removed
lock.acquired
File locked

Webhook Configuration

Creating a Webhook

curl -X POST https://api.dits.io/v1/repos/123/webhooks \
  -H "Authorization: Bearer your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhook",
    "events": ["push", "repo.created"],
    "secret": "your_webhook_secret",
    "active": true
  }'

Webhook Payload Structure

{
  "event": "push",
  "repository": {
    "id": 123,
    "name": "my-project",
    "full_name": "user/my-project",
    "private": false
  },
  "sender": {
    "id": 456,
    "login": "octocat",
    "type": "user"
  },
  "commits": [
    {
      "id": "abc123...",
      "message": "Add new footage",
      "author": {
        "name": "Octocat",
        "email": "octocat@example.com"
      }
    }
  ],
  "head_commit": {
    "id": "abc123...",
    "message": "Add new footage"
  }
}

Security & Validation

HMAC Signatures
Verify webhook authenticity
const signature = crypto
  .createHmac('sha256', secret)
  .update(payload)
  .digest('hex');

const expected = 'sha256=' + signature;

Every webhook includes an X-Hub-Signature-256 header for verification.

Retry Logic
Automatic redelivery on failure
  • Immediate retry: On 5xx errors
  • Exponential backoff: Up to 23 hours
  • Manual redelivery: Via API
  • Delivery tracking: Full history available

Common Use Cases

CI/CD Integration

Trigger automated builds and deployments when code or assets change.

  • GitHub Actions
  • Jenkins
  • GitLab CI
  • Custom pipelines
Team Notifications

Keep teams informed about project activity and collaboration events.

  • Slack notifications
  • Discord webhooks
  • Microsoft Teams
  • Email digests
Asset Processing

Automatically process, transcode, or analyze uploaded media assets.

  • Video transcoding
  • Image optimization
  • Metadata extraction
  • Quality validation

Implementation Examples

Node.js Webhook Handler

const express = require('express');
const crypto = require('crypto');

const app = express();
app.use(express.json());

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

  // Verify signature
  const expected = crypto
    .createHmac('sha256', process.env.WEBHOOK_SECRET)
    .update(payload)
    .digest('hex');

  if (!crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(`sha256=${expected}`)
  )) {
    return res.status(401).send('Invalid signature');
  }

  // Handle event
  const { event, repository, commits } = req.body;

  switch (event) {
    case 'push':
      console.log(`New push to ${repository.full_name}`);
      // Trigger CI/CD pipeline
      break;
    case 'repo.created':
      console.log(`New repository: ${repository.name}`);
      // Set up monitoring
      break;
  }

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

app.listen(3000);

Python Webhook Handler

from flask import Flask, request, jsonify
import hmac
import hashlib
import os

app = Flask(__name__)

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

@app.route('/webhook', methods=['POST'])
def handle_webhook():
    signature = request.headers.get('X-Hub-Signature-256')
    payload = request.get_data()

    if not verify_signature(payload, signature, os.environ['WEBHOOK_SECRET']):
        return jsonify({'error': 'Invalid signature'}), 401

    data = request.get_json()
    event = data['event']

    if event == 'push':
        repo = data['repository']
        commits = data['commits']
        print(f"Push to {repo['full_name']}: {len(commits)} commits")
        # Trigger deployment

    elif event == 'lock.acquired':
        file_path = data['lock']['path']
        user = data['sender']['login']
        print(f"File locked: {file_path} by {user}")
        # Notify team

    return jsonify({'status': 'ok'})

if __name__ == '__main__':
    app.run(port=3000)

Webhook Delivery Tracking

StatusDescriptionAction
Delivered
HTTP 200-299 response within 10 secondsNo action needed
Retrying
5xx error or timeout; automatic retry scheduledCheck endpoint availability
Failed
4xx error or permanent failure after retriesCheck webhook configuration