Skip to main content

Webhooks

Webhooks let external systems react when work changes in Kanera.

Use webhooks when another system should know about changes without polling the API constantly. Common examples include:

  • Update an external dashboard.
  • Sync changed cards to another system.
  • Trigger deployment or review workflows.
  • Record Kanera activity in an audit system.

To post card activity into a team chat channel, you do not need a webhook of your own. Kanera has built-in Chat Destinations for Slack, Discord, Telegram, and Zulip that format each message for the platform. Use a webhook when you need the full event catalog, exact payloads, and signature verification.

Create webhook endpoints from Workspace settings -> API, in the Custom webhooks section. Standalone boards have the same API tab in their own board settings.

Workspace API settings showing webhook configuration.

Each webhook destination can receive all events or only selected event types. Leave eventTypes empty to receive every event, or provide one or more of the event type strings below.

Plan and permissions

  • Creating and managing webhooks needs workspace admin permission.
  • Webhooks need Pro or the 30-day Pro trial. They are not available on hosted Free.
  • On hosted Free the create form is replaced by Webhooks aren't available on your plan.

What happens on a downgrade

When a hosted organisation moves from Pro or a trial to Free, Kanera pauses every enabled webhook endpoint rather than deleting anything. It also revokes active API keys, and disables automations beyond the Free limit.

On hosted FreeBehaviour
Existing endpointsAutomatically paused, and they cannot be re-enabled while the organisation is on Free.
New activityDoes not reach your endpoint.
Anything still waiting to sendRecorded as failed with webhooks are unavailable on the current plan rather than sent late.
A failed deliveryCannot be retried manually.
Configuration and historyKept. Endpoints, event selections, secrets, and delivery history are all still there.

Upgrading back to Pro re-enables the endpoints that were paused by the downgrade and restores the API keys it revoked, so a resumed integration does not need to be rebuilt.

Webhook event types

The public API exposes the current list at:

https://api.kanera.app/webhook-event-types
AreaEvent types
Listslist:created, list:updated, list:moved, list:rebalanced, list:deleted
Custom fieldscustomField:created, customField:updated, customField:moved, customField:rebalanced, customField:deleted
Custom field optionscustomFieldOption:created, customFieldOption:updated, customFieldOption:moved, customFieldOption:rebalanced, customFieldOption:deleted
Cardscard:created, card:updated, card:moved, card:rebalanced, card:deleted
Card custom fieldscard:customFieldValue:set, card:customFieldValue:cleared
Card labels and assigneescard:labels:set, card:assignees:set
Card attachmentscard:attachment:created, card:attachment:deleted
Card checklistscard:checklist:created, card:checklist:updated, card:checklist:moved, card:checklist:rebalanced, card:checklist:deleted
Card checklist itemscard:checklistItem:created, card:checklistItem:updated, card:checklistItem:moved, card:checklistItem:rebalanced, card:checklistItem:deleted
Workspace card labelscardLabel:created, cardLabel:updated, cardLabel:moved, cardLabel:rebalanced, cardLabel:deleted
Commentscomment:created, comment:updated, comment:deleted
Comment reactionscomment:reaction:added, comment:reaction:removed
Card feedcard:feedItem:created, card:feedItem:updated, card:feedItem:deleted
Boardsboard:created, board:updated, board:moved, board:rebalanced, board:deleted
Board membersboard:member:added, board:member:removed
Workspacesworkspace:updated, workspace:deleted
Workspace membersworkspace:member:added, workspace:member:updated, workspace:member:removed
Usersuser:profile:updated
Notesnote:created, note:updated, note:moved, note:rebalanced, note:deleted, note:locked, note:unlocked

Payload format

Kanera sends each webhook as a JSON object with a stable envelope and event-specific data.

FieldMeaning
idUnique webhook event id. This matches X-Kanera-Event-Id.
typeEvent type, such as card:created.
workspaceIdWorkspace where the event occurred.
boardIdBoard where the event occurred, when the event is board-scoped.
cardIdCard involved in the event, when the event payload identifies a card.
occurredAtISO 8601 timestamp for when the event occurred.
dataFull event payload. The shape depends on type and matches the corresponding realtime event payload.

Example card:created payload:

{
"id": "7e5c982a-e6c9-4ea7-9647-b14fe73ed50a",
"type": "card:created",
"workspaceId": "a069fd45-3bb3-4928-bac9-cb574a050d20",
"boardId": "48a52a55-763e-4c64-8a76-51ac56247f5c",
"cardId": "70c39cef-1aec-44e6-a8f5-f36f765a818d",
"occurredAt": "2026-05-28T12:34:56.000Z",
"data": {
"boardId": "48a52a55-763e-4c64-8a76-51ac56247f5c",
"card": {
"id": "70c39cef-1aec-44e6-a8f5-f36f765a818d",
"boardId": "48a52a55-763e-4c64-8a76-51ac56247f5c",
"listId": "3bb3c1b3-8fc7-4807-854d-2d5ff62df147",
"title": "Prepare kickoff agenda",
"position": "1000.0000000000"
}
}
}

Webhook delivery

Kanera sends webhook deliveries as JSON and includes headers you can use to verify the request:

HeaderMeaning
X-Kanera-Event-IdUnique event id.
X-Kanera-TimestampUnix timestamp in seconds.
X-Kanera-Signaturesha256= plus an HMAC-SHA256 signature.

The signature is calculated over:

${timestamp}.${rawBody}

using the webhook endpoint secret.

Webhook deliveries are retried when the endpoint returns a non-2xx status or cannot be reached. Kanera records delivery history so you can review failures, retry deliveries, pause destinations, and rotate secrets from the workspace API settings.

Verify webhook signatures

Verify the signature before trusting the payload.

The TypeScript SDK does this for you, and throws rather than returning a boolean so a handler cannot forget to check:

import { parseWebhook } from "@kanera/sdk";

app.post("/kanera/webhook", express.raw({ type: "application/json" }), async (req, res) => {
const event = await parseWebhook({
secret: process.env.KANERA_WEBHOOK_SECRET!,
payload: req.body, // the raw bytes
headers: req.headers,
});
// Handle event.type, event.workspaceId, event.boardId, event.cardId, and event.data.
res.sendStatus(204);
});

To verify it yourself, compare the HMAC over {timestamp}.{body} in constant time. Note the length check: crypto.timingSafeEqual throws when the two buffers differ in length, which an attacker controls.

import crypto from "node:crypto";
import express from "express";

const app = express();

app.post("/kanera/webhook", express.raw({ type: "application/json" }), (req, res) => {
const timestamp = req.header("X-Kanera-Timestamp") ?? "";
const signature = req.header("X-Kanera-Signature") ?? "";
const expected = "sha256=" + crypto
.createHmac("sha256", process.env.KANERA_WEBHOOK_SECRET!)
.update(`${timestamp}.${req.body.toString("utf8")}`)
.digest("hex");

const received = Buffer.from(signature);
const digest = Buffer.from(expected);
if (received.length !== digest.length || !crypto.timingSafeEqual(received, digest)) {
return res.status(401).send("invalid signature");
}

const event = JSON.parse(req.body.toString("utf8"));
// Handle event.type, event.workspaceId, event.boardId, event.cardId, and event.data.
res.sendStatus(204);
});

Always verify against the raw request body. If your framework parses JSON before verification, the signature check may fail or become unreliable.

Kanera also sends X-Kanera-Timestamp and X-Kanera-Event-Id. Reject deliveries whose timestamp is outside a few minutes of now to bound replay, and use the event id to make your handler idempotent, since deliveries may be retried.

Webhooks are the general-purpose path. Two narrower options exist for specific audiences:

PathAudiencePayloadWhere to set upPlan
WebhooksAnother systemSigned JSON across the whole event catalogWorkspace settings -> APIPro or trial
Chat destinationsA team channelFormatted messages for Slack, Discord, Telegram, or ZulipWorkspace settings -> IntegrationsPro or trial
Personal delivery channelsOne personntfy, Gotify, or signed JSON for your own notificationsProfile settings -> NotificationsPro or trial

Chat destinations are managed separately from webhook endpoints and do not appear in the webhook list, so rotating a webhook secret never affects a chat destination.