Webhooks
Webhooks let you receive HTTP POST requests when events happen in your projects. Use them to integrate TaskView with external systems - CI/CD pipelines, Slack bots, custom dashboards, or any service that can accept HTTP requests.
Supported events
| Event | When it fires |
|---|---|
task.created | A new task is created in the project |
task.updated | A task is updated (description, status, priority, deadline, etc.) |
task.deleted | A task is deleted |
task.assigneesChanged | Task assignees are added or removed |
time-entry.started | A timer is started on a task |
time-entry.stopped | A running timer is stopped |
time-entry.created | A time entry is created manually |
time-entry.updated | A time entry is updated |
time-entry.deleted | A time entry is deleted |
sprint.created | A new sprint is created (draft or planned) |
sprint.updated | Sprint fields are edited (name, dates, capacity, goal) |
sprint.activated | A sprint transitions to the active state |
sprint.reviewStarted | An active sprint enters review |
sprint.completed | A sprint is closed and marked completed |
sprint.paused | An active sprint is paused |
sprint.resumed | A paused sprint is resumed |
sprint.deleted | A sprint is deleted (any status, including completed) |
task.assignedToSprint | A task is added to, moved between, or removed from a sprint |
Setup
- Open a project in TaskView
- Right-click the project in the sidebar → "Webhooks"
- Click "Add Webhook"
- Enter the URL where you want to receive events
- Select which events to subscribe to
- Click "Add"
- Copy the secret and store it securely - it will not be shown again
Payload format
Every webhook delivery is an HTTP POST with Content-Type: application/json:
{
"event": "task.updated",
"timestamp": "2026-03-22T12:00:00.000Z",
"task": {
"id": 123,
"goalId": 774,
"description": "Fix login bug",
"complete": false,
"statusId": 5,
"priorityId": 2,
"tags": [1, 3],
"assignedUsers": [10, 22],
"subtasks": []
},
"changes": {
"statusId": 5
},
"initiatorId": 1
}
The changes field is only present on task.updated and sprint.updated events and contains only the fields that changed.
Sprint events carry the sprint payload. Lifecycle events (sprint.activated, sprint.reviewStarted, sprint.completed, sprint.paused, sprint.resumed) include the full sprint object reflecting its state at the time the event fired, plus sprintId, goalId, and initiatorId:
{
"event": "sprint.completed",
"timestamp": "2026-03-22T12:00:00.000Z",
"sprintId": 42,
"goalId": 774,
"initiatorId": 1,
"sprint": {
"id": 42,
"goalId": 774,
"name": "Sprint 7",
"status": "completed",
"startDate": "2026-03-08",
"endDate": "2026-03-22",
"goalAchieved": true,
"completedAt": "2026-03-22T12:00:00.000Z"
}
}
task.assignedToSprint carries taskId, sprintId (the new sprint, or null when removed), prevSprintId, goalId, and initiatorId. sprint.deleted carries sprintId, goalId, and initiatorId only, since the sprint no longer exists. initiatorId may be null for sprints generated automatically by a cadence.
Signature verification
Every request includes an X-Webhook-Signature header with an HMAC-SHA256 signature of the request body:
X-Webhook-Signature: sha256=5d41402abc4b2a76b9719d911017c592...
Always verify the signature before processing the payload. Example in Node.js:
const crypto = require('crypto')
function verifySignature(body, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex')
return signature === expected
}
// In your HTTP handler:
const body = req.body // raw string, not parsed JSON
const signature = req.headers['x-webhook-signature']
const isValid = verifySignature(body, signature, YOUR_SECRET)
Retries
If your server responds with a non-2xx status code or doesn't respond within 10 seconds, TaskView retries the delivery:
| Attempt | Delay |
|---|---|
| 1st retry | ~10 seconds |
| 2nd retry | ~20 seconds |
After 3 total attempts (1 original + 2 retries), the delivery is marked as failed.
Auto-deactivation
If a webhook accumulates 10 consecutive failed deliveries (after all retries are exhausted), it is automatically deactivated. A single successful delivery resets the failure counter.
To reactivate a webhook, toggle it back on from the webhooks page. The failure counter is not reset automatically - the next successful delivery will reset it.
Delivery history
The webhooks page shows delivery history for each webhook:
- Event - which event was delivered
- Status - success, failed, or pending
- HTTP code - response status code from your server
- Attempts - how many attempts were made
- Payload - click to view the full JSON payload
Failed deliveries can be retried manually from the delivery history.
Managing webhooks
From the webhooks page you can:
- Toggle webhooks on/off
- Edit the URL and subscribed events
- Test - sends a test payload to verify connectivity
- Rotate secret - generates a new secret (the old one stops working immediately)
- Delete - removes the webhook and all delivery history
- View deliveries - see delivery history with status filter
Secret rotation
If your secret is compromised, rotate it:
- Click the key icon on the webhook
- Confirm that you want to rotate
- Copy the new secret
- Update the secret in your receiving application
The old secret stops working immediately. Any in-flight deliveries signed with the old secret will fail signature verification on your end.
Testing locally
You can use a simple Node.js script to test webhook deliveries:
const http = require('http')
const crypto = require('crypto')
const PORT = 4545
const SECRET = 'your-secret-here'
const server = http.createServer((req, res) => {
const chunks = []
req.on('data', (chunk) => chunks.push(chunk))
req.on('end', () => {
const body = Buffer.concat(chunks).toString()
const signature = req.headers['x-webhook-signature'] || ''
const expected = 'sha256=' + crypto
.createHmac('sha256', SECRET)
.update(body)
.digest('hex')
console.log(signature === expected ? 'Valid' : 'INVALID')
console.log(JSON.stringify(JSON.parse(body), null, 2))
res.writeHead(200)
res.end('OK')
})
})
server.listen(PORT, () => console.log(`Listening on :${PORT}`))
Run with node webhook-receiver.js and set the webhook URL to http://localhost:4545.
Notifications
Real-time and push notifications in TaskView - deadline alerts, assignment notifications, per-user preferences, and multi-channel delivery via WebSocket and Firebase Cloud Messaging.
API Tokens
Create API tokens for programmatic access to TaskView. Tokens support permission scoping, project-level restrictions, and optional expiration.
