Webhooks
Receive HTTP callbacks for repository events. HMAC-SHA256 signed payloads with delivery tracking.
Webhooks notify your services when events occur on Drok. When a configured event happens — a push, a merge request, a pipeline completion — Drok sends an HTTP POST request to your endpoint with a JSON payload describing the event.
Creating Webhooks
drok webhook create my-org/my-repo \
--url https://your-service.com/webhook \
--events push,merge_request,pipeline \
--secret your-webhook-secret \
--content-type jsonOr through the web interface: Repository Settings > Webhooks > Add Webhook.
Events
| Event | Trigger |
|---|---|
push | Push to any branch |
merge_request | Merge request opened, updated, merged, or closed |
merge_request_comment | Comment on a merge request |
issue | Issue opened, updated, or closed |
issue_comment | Comment on an issue |
pipeline | Pipeline started, completed, or failed |
release | Release published or edited |
tag | Tag created or deleted |
branch | Branch created or deleted |
member | Collaborator added or removed |
package | Package published, yanked, or deleted |
repository | Repository created, deleted, or settings changed |
Wildcard
Subscribe to all events:
drok webhook create my-org/my-repo \
--url https://your-service.com/webhook \
--events "*"Payload Format
Headers
| Header | Description |
|---|---|
X-Drok-Event | The event type (e.g., push, merge_request) |
X-Drok-Delivery | Unique ID for this delivery |
X-Drok-Signature-256 | HMAC-SHA256 signature of the payload |
Content-Type | application/json |
User-Agent | Drok-Webhook/1.0 |
Push Event Payload
{
"event": "push",
"delivery_id": "dlv_01H8XYZ",
"timestamp": "2024-03-15T14:30:22Z",
"repository": {
"id": "repo_01H8XYZ",
"full_name": "my-org/my-repo",
"url": "https://drok.us/my-org/my-repo"
},
"sender": {
"id": "usr_01H8ABC",
"username": "alice"
},
"ref": "refs/heads/main",
"before": "abc1234567890",
"after": "def0987654321",
"commits": [
{
"id": "def0987654321",
"message": "Add new feature",
"author": {
"name": "Alice",
"email": "alice@example.com"
},
"timestamp": "2024-03-15T14:30:00Z",
"added": ["src/feature.rs"],
"modified": ["src/lib.rs"],
"removed": []
}
]
}Merge Request Event Payload
{
"event": "merge_request",
"action": "opened",
"delivery_id": "dlv_01H8XYZ",
"timestamp": "2024-03-15T14:30:22Z",
"merge_request": {
"id": "mr_01H8XYZ",
"number": 42,
"title": "Add new feature",
"state": "open",
"source_branch": "feature/new-feature",
"target_branch": "main",
"author": {
"id": "usr_01H8ABC",
"username": "alice"
},
"url": "https://drok.us/my-org/my-repo/merge-requests/42"
},
"repository": {
"id": "repo_01H8XYZ",
"full_name": "my-org/my-repo"
},
"sender": {
"id": "usr_01H8ABC",
"username": "alice"
}
}Signature Verification
Webhook payloads are signed with HMAC-SHA256 using the secret you provide when creating the webhook. Always verify the signature before processing payloads.
Verification Example (Node.js)
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler:
app.post('/webhook', (req, res) => {
const signature = req.headers['x-drok-signature-256'];
const isValid = verifySignature(
JSON.stringify(req.body),
signature,
process.env.WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
// Process the webhook...
res.status(200).send('OK');
});Verification Example (Python)
import hmac
import hashlib
def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)Delivery Tracking
Every webhook delivery is logged. View delivery history:
drok webhook deliveries my-org/my-repo --webhook-id whk_01H8XYZEach delivery record includes:
- Delivery ID — Unique identifier
- Event — The event type
- Response status — HTTP status code from your endpoint
- Response time — Time to receive a response
- Payload — The sent payload (viewable in web interface)
- Response body — Your endpoint's response
Redelivery
Redeliver a failed webhook:
drok webhook redeliver my-org/my-repo --delivery-id dlv_01H8XYZAutomatic Retries
Failed deliveries (non-2xx response or timeout) are retried automatically:
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry | 12 hours |
After 5 failed retries, the delivery is marked as failed. The webhook is not disabled — subsequent events still trigger new deliveries.
Webhook Disabling
If a webhook consistently fails (90% failure rate over 7 days), Drok sends a notification to the repository admin and marks the webhook as unhealthy. Unhealthy webhooks continue to receive deliveries but are flagged in the web interface.
Organization Webhooks
Create webhooks at the organization level to receive events from all repositories:
drok webhook create my-org \
--url https://your-service.com/webhook \
--events push,merge_request,pipeline \
--secret your-secret