sota.io

Webhooks

Set up webhooks to receive notifications when deployment events occur on sota.io.

Overview

Webhooks send HTTP POST requests to your URL when deployments start, succeed, or fail. All payloads are signed with HMAC-SHA256 for security.

Setting Up a Webhook

Via API

curl -X POST https://api.sota.io/v1/projects/550e8400-.../webhooks \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/webhook/sota", "events": ["deploy.started", "deploy.succeeded", "deploy.failed"]}'

Save the returned secret -- you will need it to verify signatures.

Events

EventWhen
deploy.startedA new deployment build has begun
deploy.succeededDeployment is live and passing health checks
deploy.failedBuild error or health check timeout

Payload Format

{
  "event": "deploy.succeeded",
  "project_id": "550e8400-e29b-41d4-a716-446655440000",
  "deployment_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "timestamp": "2026-02-25T14:30:00Z",
  "data": {
    "url": "https://my-app.sota.io",
    "status": "running"
  }
}

Verifying Signatures

Every webhook includes an X-Sota-Signature header. Verify it to ensure the request is authentic:

Node.js

const crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(body, 'utf8')
    .digest('hex');

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

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

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

  const event = req.body;
  console.log(`Received ${event.event} for ${event.project_id}`);

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

Python

import hmac
import hashlib

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

Use Cases

  • Slack notifications -- Post to a channel when deployments complete
  • CI/CD integration -- Trigger downstream pipelines after successful deploys
  • Monitoring -- Alert on failed deployments
  • Audit logging -- Record all deployment events