Skip to main content
Documentation
API & Integration

Webhooks & Events

A planned webhooks service for real-time repository event notifications, intended to power CI/CD pipelines, Slack notifications, and automated workflows.

Event-Driven Automation (Planned)

The planned webhooks service would deliver real-time notifications about repository activity, enabling integrations and automated workflows across your creative pipeline. This service does not exist yet.

Planned
Event Types
Real-time
Delivery
Secure
Signatures

Supported Events

Repository Events
repo.createdNew repository
repo.deletedRepository removed
repo.updatedSettings changed
repo.transferredOwnership changed
Push Events
pushCommits pushed
push.tagTag pushed
push.forceForce push
Branch & Tag Events
branch.createdNew branch
branch.deletedBranch removed
tag.createdNew tag
Collaboration Events
member.addedUser added
member.removedUser removed
lock.acquiredFile 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