Automate workflows with hooks that fire on task state transitions.
Lifecycle hooks trigger actions when tasks change state:
| Hook | Fires When |
|---|---|
onCreated |
Task is created |
onStarted |
Task moves to in-progress |
onBlocked |
Task moves to blocked |
onCompleted |
Task moves to done |
onArchived |
Task is archived |
Each hook can:
Enable hooks via the settings API:
curl -X PATCH http://localhost:3001/api/config/settings \
-H "Content-Type: application/json" \
-d '{
"hooks": {
"enabled": true,
"onCreated": {
"enabled": true,
"webhook": "https://your-server.com/webhooks/vk",
"notify": false,
"logActivity": true
},
"onStarted": {
"enabled": true,
"notify": true
},
"onBlocked": {
"enabled": true,
"webhook": "https://your-server.com/webhooks/vk",
"notify": true
},
"onCompleted": {
"enabled": true,
"notify": true
},
"onArchived": {
"enabled": false
}
}
}'
| Field | Type | Default | Description |
|---|---|---|---|
hooks.enabled |
boolean | false | Global enable/disable |
hooks.on*.enabled |
boolean | false | Enable specific hook |
hooks.on*.webhook |
string | — | URL to POST payload |
hooks.on*.notify |
boolean | false | Send notification |
hooks.on*.logActivity |
boolean | true | Record in activity log |
When a webhook is configured, VK sends a POST request:
{
"event": "onBlocked",
"taskId": "task_20260204_abc123",
"taskTitle": "Implement OAuth login",
"previousStatus": "in-progress",
"newStatus": "blocked",
"project": "my-project",
"sprint": "US-1700",
"timestamp": "2026-02-04T15:30:00.000Z"
}
| Header | Value |
|---|---|
Content-Type |
application/json |
X-VK-Event |
Hook event name (e.g., onBlocked) |
Configure onBlocked to POST to a Slack incoming webhook:
{
"hooks": {
"enabled": true,
"onBlocked": {
"enabled": true,
"webhook": "https://hooks.slack.com/services/XXX/YYY/ZZZ"
}
}
}
Your Slack webhook receives the payload and can format a message.
Use onCreated to wake an AI agent via OpenClaw:
{
"hooks": {
"enabled": true,
"onCreated": {
"enabled": true,
"webhook": "http://localhost:8080/api/wake"
}
}
}
The agent receives the new task and can begin work automatically.
Use onCompleted to update external dashboards:
{
"hooks": {
"enabled": true,
"onCompleted": {
"enabled": true,
"webhook": "https://metrics.example.com/vk/task-complete"
}
}
}
Simple Express handler for VK hooks:
import express from 'express';
const app = express();
app.use(express.json());
app.post('/webhooks/vk', (req, res) => {
const { event, taskId, taskTitle, newStatus } = req.body;
console.log(`[VK Hook] ${event}: ${taskTitle} (${taskId}) → ${newStatus}`);
switch (event) {
case 'onBlocked':
// Alert the team
notifySlack(`⚠️ Task blocked: ${taskTitle}`);
break;
case 'onCompleted':
// Update metrics
recordCompletion(taskId);
break;
}
res.sendStatus(200);
});
app.listen(3002);
Check current hooks configuration:
curl http://localhost:3001/api/config/settings | jq '.data.hooks'
Enable/disable hooks quickly:
# Enable all hooks
curl -X PATCH http://localhost:3001/api/config/settings \
-H "Content-Type: application/json" \
-d '{"hooks": {"enabled": true}}'
# Disable all hooks
curl -X PATCH http://localhost:3001/api/config/settings \
-H "Content-Type: application/json" \
-d '{"hooks": {"enabled": false}}'
hooks.enabled is truehooks.onBlocked.enabled) is truetail -f server/logs/server.log | grep hookslogActivity defaults to trueLifecycle hooks pattern inspired by BoardKit Orchestrator by Monika Voutov.