Webhooks
Webhooks send HTTP POST requests to your URL when task events occur. Use them to integrate with n8n, Home Assistant, Node-RED, or any service that accepts webhooks.
Creating a Webhook
bash
curl -X POST https://tasks.example.com/api/webhooks \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-service.com/webhook",
"events": ["task.created", "task.completed"]
}'The response includes a secret field — save it immediately. The secret is shown once and cannot be retrieved later.
Events
| Event | Fires when | Payload |
|---|---|---|
task.created | Task is created | { task: { ... } } |
task.updated | Task fields change | { task: { ... }, fields_changed: [...] } |
task.completed | Task is marked done | { task: { ... } } |
task.deleted | Task is trashed | { task_id, title } |
task.snoozed | Task is snoozed | { task: { ... }, previous_due_at } |
Payload Format
json
{
"event": "task.completed",
"timestamp": "2026-02-27T15:00:00.000Z",
"data": {
"task": {
"id": 42,
"title": "Call dentist",
"done": true,
"priority": 2,
"due_at": "2026-02-27T14:00:00Z",
"labels": ["medical"],
"project_id": 1,
"is_recurring": false,
"is_snoozed": false
}
}
}Headers
| Header | Value |
|---|---|
Content-Type | application/json |
X-OpenTask-Event | Event name (e.g., task.completed) |
X-OpenTask-Signature | sha256=<hex> HMAC-SHA256 of body |
Verifying Signatures
Every delivery is signed with your webhook's secret using HMAC-SHA256:
javascript
// Node.js
const crypto = require('crypto')
function verifySignature(body, signature, secret) {
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(body).digest('hex')
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))
}
const signature = req.headers['x-opentask-signature']
const isValid = verifySignature(rawBody, signature, YOUR_WEBHOOK_SECRET)python
# Python
import hmac, hashlib
def verify_signature(body: bytes, signature: str, secret: str) -> bool:
expected = 'sha256=' + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(signature, expected)Managing Webhooks
bash
# List webhooks
curl https://tasks.example.com/api/webhooks \
-H "Authorization: Bearer $TOKEN"
# Disable (without deleting)
curl -X PATCH https://tasks.example.com/api/webhooks/1 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"active": false}'
# Check recent deliveries
curl https://tasks.example.com/api/webhooks/1/deliveries \
-H "Authorization: Bearer $TOKEN"
# Delete
curl -X DELETE https://tasks.example.com/api/webhooks/1 \
-H "Authorization: Bearer $TOKEN"Delivery Behavior
- Timeout: 10 seconds per request
- Retries: Up to 3 attempts on failure (1s and 5s delays)
- Success: Any 2xx status code
- Logging: All deliveries logged, visible via the deliveries endpoint
- Retention: Delivery logs purged after 7 days
- Non-blocking: Webhook delivery never blocks task operations
