Back
other

TaskNotes Webhooks — TaskNotes

619 words
View original

TaskNotes webhooks send HTTP POST requests when selected events occur.

Prerequisites

  1. Enable HTTP API in Settings -> TaskNotes -> Integrations -> HTTP API.
  2. Create at least one webhook (settings UI or API).
  3. Subscribe it to one or more events.

Event Types

Task events:

Time events:

Pomodoro events:

Recurring events:

Reminder events:

Payload Shape

All webhook payloads use the same top-level envelope:

{
  "event": "task.created",
  "timestamp": "2026-02-21T10:30:00.000Z",
  "vault": {
    "name": "My Vault",
    "path": "/path/to/vault"
  },
  "data": {}
}

data is event-specific.

Create

POST /api/webhooks

Required fields:

Optional fields:

Example:

curl -X POST http://localhost:8080/api/webhooks \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/tasknotes",
    "events": ["task.completed", "task.created"],
    "transformFile": "TaskNotes/webhooks/slack.json"
  }'

List

GET /api/webhooks

Returns registered hooks. Secrets are not returned.

Delete

DELETE /api/webhooks/:id

Delivery History

GET /api/webhooks/deliveries

Returns last 100 in-memory deliveries.

Delivery Behavior

Current implementation behavior:

Because retries and duplicates are possible, handlers should be idempotent.

Signature Verification

When corsHeaders is enabled (default), delivery includes:

Signature is HMAC-SHA256 over JSON.stringify(payload) using webhook secret.

Node.js example:

const crypto = require("crypto");

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(JSON.stringify(payload))
    .digest("hex");
  return signature === expected;
}

Payload Transformations

A webhook can specify transformFile pointing to a file in your vault.

Supported file types:

If transform execution fails, TaskNotes falls back to original payload.

JavaScript Transform Files

Expected format:

function transform(payload) {
  return payload;
}

Execution model:

Important behavior:

Example:

function transform(payload) {
  if (payload.event === "task.completed") {
    return {
      text: \`Completed: ${payload.data.task.title}\`,
      event: payload.event,
      at: payload.timestamp,
    };
  }

  return payload;
}

JSON Transform Files

Structure:

{
  "task.completed": {
    "text": "Task completed: ${data.task.title}",
    "vault": "${vault.name}"
  },
  "default": {
    "text": "TaskNotes event: ${event}"
  }
}

Rules:

CORS and Headers

Webhook delivery requests are outbound server-side requests from TaskNotes.

corsHeaders behavior:

Disable custom headers for endpoints that reject non-standard headers.

Testing

Local Test Server

Use repository script:

node test-webhook.js

Optional custom port:

node test-webhook.js 8080

Default server values:

External Inspection

For quick inspection, use a request-bin tool such as webhook.site.

Troubleshooting

No deliveries

  1. Confirm HTTP API is enabled.
  2. Confirm webhook is active.
  3. Confirm event is subscribed.

Signature mismatch

  1. Confirm secret matches webhook config.
  2. Verify your verifier hashes the exact JSON body.
  3. Verify hex digest comparison.

Webhook disabled automatically

If failures continue and failureCount exceeds 10, webhook is disabled.

  1. Fix endpoint availability or response handling.
  2. Re-enable webhook in TaskNotes settings, or recreate it via POST /api/webhooks.
  3. Confirm transformFile exists in vault.
  4. For JS, ensure transform function is defined.
  5. Check Obsidian console logs for transform exceptions.