Skip to content

Webhooks

PanSalut edited this page Aug 1, 2026 · 1 revision

Outbound Webhooks

Koffan can send HTTP POST notifications when shopping list items change. This makes it possible to connect Koffan to n8n, Node-RED, Zapier, Discord, Telegram, or another automation service.

Webhook support is available in Koffan 2.13.0 and later.

Configuration

Set these environment variables and restart Koffan:

Variable Required Description
WEBHOOK_URL Yes HTTP or HTTPS endpoint that receives events. Leaving it empty disables webhooks.
WEBHOOK_SECRET No Secret used to sign the raw request body with HMAC-SHA256.
WEBHOOK_EVENTS No Comma-separated event filter. When omitted, all supported events are enabled.

Example:

WEBHOOK_URL=https://automation.example.com/webhook/koffan \
WEBHOOK_SECRET=replace-with-a-random-secret \
WEBHOOK_EVENTS=item.created,item.completed,item.deleted \
go run .

Docker Compose example:

services:
  koffan:
    environment:
      WEBHOOK_URL: https://automation.example.com/webhook/koffan
      WEBHOOK_SECRET: replace-with-a-random-secret
      WEBHOOK_EVENTS: item.created,item.updated,item.completed,item.deleted

WEBHOOK_URL must use the http or https scheme. An unsupported event name makes the webhook configuration invalid and disables outbound delivery until the configuration is corrected.

Events

Event Trigger
item.created An item is created directly, through the REST batch API, from a template, or during import.
item.updated An item is edited, moved, reactivated, marked uncertain, unchecked, or has its quantity changed.
item.completed An item is marked completed, including check-all operations.
item.deleted An item is deleted directly or through a cascading list/section deletion, delete-completed, import replace, or database clear.

Bulk operations send one webhook request for each affected item. Operations that do not change an item do not create an event.

HTTP Request

Every delivery uses POST and includes these headers:

Content-Type: application/json
User-Agent: Koffan-Webhook/1.0
X-Koffan-Event: item.created
X-Koffan-Signature-256: sha256=<hex digest>

X-Koffan-Signature-256 is included only when WEBHOOK_SECRET is configured.

Example payload:

{
  "id": "32f46c85bf51499cac2131cdbf18d78c",
  "event": "item.created",
  "timestamp": "2026-08-01T10:30:00Z",
  "data": {
    "item": {
      "id": 42,
      "section_id": 3,
      "name": "Milk",
      "description": "",
      "completed": false,
      "uncertain": false,
      "quantity": 1,
      "sort_order": 0,
      "created_at": "2026-08-01T10:30:00Z",
      "updated_at": 1785580200
    },
    "section": {
      "id": 3,
      "name": "Dairy"
    },
    "list": {
      "id": 1,
      "name": "Weekly groceries"
    }
  }
}

The event id remains unchanged across retries and can be used for deduplication. Delete events retain the item, section, and list context even when the parent records were removed by a cascading operation.

Signature Verification

When WEBHOOK_SECRET is set, Koffan calculates HMAC-SHA256 over the exact raw HTTP request body and sends the result as:

X-Koffan-Signature-256: sha256=<lowercase hexadecimal digest>

Verification steps:

  1. Read the raw request body without reformatting the JSON.
  2. Calculate HMAC-SHA256 using WEBHOOK_SECRET as the key.
  3. Prefix the lowercase hexadecimal result with sha256=.
  4. Compare it with the header using a constant-time comparison.

Use HTTPS and a strong random secret when the endpoint is reachable over a network.

Delivery and Retries

Koffan stores accepted events in a SQLite outbox before attempting HTTP delivery. Sending the HTTP request is asynchronous and does not wait for the receiving automation to finish.

  • Any HTTP status from 200 through 299 confirms delivery.
  • Network errors and non-2xx responses are retried indefinitely.
  • Retry delays grow exponentially from 1 second up to 5 minutes.
  • Pending events survive application restarts.
  • Events are delivered in creation order. A failing event delays later events until it succeeds.
  • Delivery is at least once. A receiver may see the same event more than once if Koffan stops after the receiver responds but before the outbox entry is removed.

Receivers should therefore store processed event IDs and ignore duplicates.

Troubleshooting

  • Check Koffan logs for invalid configuration, persistence errors, response status codes, and retry delays.
  • Confirm the endpoint is reachable from the Koffan container or host, not only from your browser.
  • Return a 2xx response after the event is accepted.
  • If no events arrive, verify WEBHOOK_EVENTS and restart Koffan after changing environment variables.

Clone this wiki locally