Skip to content

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

EventFires whenPayload
task.createdTask is created{ task: { ... } }
task.updatedTask fields change{ task: { ... }, fields_changed: [...] }
task.completedTask is marked done{ task: { ... } }
task.deletedTask is trashed{ task_id, title }
task.snoozedTask 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

HeaderValue
Content-Typeapplication/json
X-OpenTask-EventEvent name (e.g., task.completed)
X-OpenTask-Signaturesha256=<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