Webhooks
Receive notifications when deployment events occur. All webhook payloads are signed with HMAC-SHA256.
Register a Webhook
POST /v1/projects/:id/webhooks
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", "events": ["deploy.started", "deploy.succeeded", "deploy.failed"]}'
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Webhook endpoint URL |
events | string[] | Yes | Events to subscribe to |
Response (201 Created):
{
"data": {
"id": "c47d8e9f-1234-5678-9abc-def012345678",
"project_id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://example.com/webhook",
"secret": "whsec_...",
"events": ["deploy.started", "deploy.succeeded", "deploy.failed"],
"created_at": "2026-02-25T10:00:00Z"
}
}
Important: Store the
secret-- it is used to verify webhook signatures and is only shown once.
Events
| Event | Trigger |
|---|---|
deploy.started | A new deployment build has started |
deploy.succeeded | Deployment is live and healthy |
deploy.failed | Build or health check failed |
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"
}
}
Signature Verification
Every webhook request includes an X-Sota-Signature header with an HMAC-SHA256 signature:
X-Sota-Signature: sha256=abc123...
Verify the signature in your webhook handler:
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
List Webhooks
GET /v1/projects/:id/webhooks
Returns all webhooks for the project. Secrets are omitted in list responses.
Delete Webhook
DELETE /v1/projects/:id/webhooks/:webhook_id
Returns 204 No Content.