Webhooks
Webhooks lar eksterne systemer reagere når arbeidet endres i Kanera.
Bruk webhooks når et annet system skal vite om endringer uten å avspørre API hele tiden. Vanlige eksempler inkluderer:
- Oppdater et eksternt dashbord.
- Synkroniser byttede kort til et annet system.
- Utløs distribusjon eller gjennomgå arbeidsflyter.
- Registrer Kanera-aktivitet i et revisjonssystem.
For å legge inn kortaktivitet i en gruppechatkanal, trenger du ikke en egen webhook. Kanera har innebygd Chat Destinasjoner for Slack, Discord, Telegram og Zulip som formaterer hver melding for plattformen. Bruk en webhook når du trenger hele hendelseskatalogen, nøyaktige nyttelaster og signaturbekreftelse.
Arbeidsområdeadministratorer kan opprette webhook-endepunkter fra Arbeidsområdeinnstillinger -> API, i Egendefinerte webhooks seksjon. Frittstående boards har samme API fane i egne brettinnstillinger. Integrasjoner kan også registrere endepunkter gjennom det offentlige API eller TypeScript SDK.
Hver webhook-destinasjon kan motta alle hendelser eller bare utvalgte hendelsestyper. eventTypes tom for å motta hver hendelse, eller angi en eller flere av strengene for hendelsestypen nedenfor.
Plan og tillatelser
- Arbeidsområdeadministratorer kan se og administrere alle generiske webhook-endepunkter i det arbeidsområdet.
- En API-legitimasjonsagent som kan skrive eller en interaktiv OAuth-agent kan registrere et endepunkt uten administratorautoritet når brukeren er et arbeidsområdemedlem. Dette endepunktet er begrenset til opprettelsestilkoblingen: bare de samme tilkoblings- og arbeidsområdeadministratorene kan se eller administrere den. Lest-omfattet legitimasjon kan ikke administrere webhooks.
- Webhooks trenger Pro eller 30-dagers Pro-rettssaken. De er ikke tilgjengelige på verts Free.
- På vert Free opprette skjemaet er erstattet av Webhooks er ikke tilgjengelig på planen din.
Tilbakekalling av legitimasjons- eller agenttilkoblingen fjerner også endepunktene for tilkoblingen. Admin-opprettede endepunkter for arbeidsområdet forblir til en administrator sletter dem.
Hva skjer i en nedgradering
Når en vertsorganisasjon flytter fra Pro eller en prøveversjon til Free, setter Kanera alle aktiverte webhook-endepunkter på pause i stedet for å slette noe. Det opphever også API-nøkler for arbeidsområde (personlige nøkler fortsetter å fungere), og deaktiverer automatiseringer utover Free-grensen.
| På vert Free | Adferd |
|---|---|
| Eksisterende endepunkter | Automatisk pauset, og de kan ikke aktiveres på nytt mens organisasjonen er på Free. |
| Ny aktivitet | Når ikke endepunktet ditt. |
| Alt som venter på å bli sendt | Registrert som mislykket med webhooks are unavailable on the current plan I stedet for å bli sent. |
| En mislykket levering | Kan ikke prøves manuelt. |
| Konfigurasjon og historikk | Holdt. Endpoints, arrangement valg, hemmeligheter, og levering historie er alle fortsatt der. |
Oppgradering tilbake til Pro aktiverer endepunktene som ble pauset av nedgraderingen, og gjenoppretter API-tastene for arbeidsområdet som ble tilbakekalt, slik at en gjenopptatt integrasjon ikke trenger å bli gjenoppbygd.
Registrer et endepunkt programmatisk
Det offentlige API-et viser den samme generiske endepunktlivssyklusen som brukes av arbeidsområdeinnstillinger. Hver bane nedenfor er relativt til:
/api/v1/workspaces/{workspaceId}/webhooks
| Metode | Sti | Bruk |
|---|---|---|
GET | (grunnbane) | Vis endepunkter som er synlige for den som ringer. |
POST | (grunnbane) | Opprett et endepunkt og gi tilbake signeringshemmeligheten en gang. |
PATCH | /{endpointId} | Endre navn, URL, hendelsesfilter eller aktivert tilstand. |
POST | /{endpointId}/secret | Roter signeringshemmeligheten. |
DELETE | /{endpointId} | Slett endepunktet. |
GET | /{endpointId}/deliveries | Les nylige leveringsforsøk. |
POST | /{endpointId}/deliveries/{deliveryId}/retry | Prøv en mislykket levering. |
Med TypeScript SDK, bruk kanera.webhookEndpoints.create(), .list(), .update(), .rotateSecret(), .deliveries(), .retryDelivery(), og .delete(). Det returnerte endepunktet har scope: "workspace" for et admin-administrert endepunkt eller scope: "connection" når en ikke-admin legitimasjon registrerte den. Lagre secret returneres ved opprettelse eller rotasjon umiddelbart; senere leser aldri avsløre den.
Webhook-hendelsestyper
Det offentlige API-et viser gjeldende liste på:
https://api.kanera.app/webhook-event-types
| Område | Hendelsestyper |
|---|---|
| Lister | list:created, list:updated, list:moved, list:rebalanced, list:deleted |
| tavlen separatorer | separator:created, separator:updated, separator:moved, separator:rebalanced, separator:deleted |
| Egendefinerte felt | customField:created, customField:updated, customField:moved, customField:rebalanced, customField:deleted |
| Egendefinerte feltvalg | customFieldOption:created, customFieldOption:updated, customFieldOption:moved, customFieldOption:rebalanced, customFieldOption:deleted |
| Kort | card:created, card:updated, card:moved, card:rebalanced, card:deleted |
| Egendefinerte kortfelt | card:customFieldValue:set, card:customFieldValue:cleared |
| Kortetiketter og kortinnehavere | card:labels:set, card:assignees:set |
| Kortvedlegg | card:attachment:created, card:attachment:deleted |
| Kort sjekklister | card:checklist:created, card:checklist:updated, card:checklist:moved, card:checklist:rebalanced, card:checklist:deleted |
| Kort sjekkliste elementer | card:checklistItem:created, card:checklistItem:updated, card:checklistItem:moved, card:checklistItem:rebalanced, card:checklistItem:deleted |
| Arbeidsområdekortetiketter | cardLabel:created, cardLabel:updated, cardLabel:moved, cardLabel:rebalanced, cardLabel:deleted |
| Kommentarer | comment:created, comment:updated, comment:deleted |
| Kommentar reaksjoner | comment:reaction:added, comment:reaction:removed |
| Kortstrøm | card:feedItem:created, card:feedItem:updated, card:feedItem:deleted |
| Tavler | board:created, board:updated, board:moved, board:rebalanced, board:deleted |
| Styremedlemmer | board:member:added, board:member:removed |
| Arbeidsområder | workspace:updated, workspace:deleted |
| Arbeidsområde medlemmer | workspace:member:added, workspace:member:updated, workspace:member:removed |
| Brukere | user:profile:updated |
| Notater | note:created, note:updated, note:moved, note:rebalanced, note:deleted, note:locked, note:unlocked |
| Agent kjører | agentRun:started, agentRun:updated |
Nyttelastformat
Kanera sender hver webhook som et JSON-objekt med en stabil konvolutt og hendelsesspesifikk data.
| Felt | Betydning |
|---|---|
id | Unik webhook-hendelses-id. Dette samsvarer X-Kanera-Event-Id. |
type | Hendelsestype, som card:created. |
workspaceId | Arbeidsområde der hendelsen skjedde. |
boardId | tavlen der hendelsen skjedde, når arrangementet er tavle-scoped. |
cardId | Kort som er involvert i arrangementet, når nyttelasten for arrangementet identifiserer et kort. |
occurredAt | ISO 8601 tidsstempel for når hendelsen skjedde. |
data | Full hendelse nyttelast. Formen avhenger av type og samsvarer med den tilsvarende sanntidshendelsen nyttelast. |
Agent-run hendelser bære { boardId, cardId, run } i data, hvor run er den fulle agenten løp: dens agentName, den userId Det virker for, status, title, summary, externalUrlog dens startedAt, heartbeatAt, og endedAt tidsstempler. agentRun:updated branner på hver hjerterytme samt på en statusendring, så tast handleren på run.status I stedet for å behandle hver levering som nytt arbeid. En løp som slutter å pulsere kommer som en endelig agentRun:updated med status: "stalled".
Eksempel card:created nyttelast:
{
"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 levering
Kanera sender webhook-leveranser som JSON og inkluderer overskrifter du kan bruke til å bekrefte forespørselen:
| Overskrift | Betydning |
|---|---|
X-Kanera-Event-Id | Unik hendelses-id. |
X-Kanera-Timestamp | Unix tidsstempel i sekunder. |
X-Kanera-Signature | sha256= pluss en HMAC-SHA256-signatur. |
Signaturen beregnes over:
${timestamp}.${rawBody}
Bruke Webhook endpoint secret
Webhook-leveranser blir prøvd på nytt når endepunktet returnerer en ikke-2xx-status eller ikke kan nås. Kanera registrerer leveringshistorikk slik at du kan se gjennom feil, prøve leveranser på nytt, pause destinasjoner og rotere hemmeligheter fra API-innstillingene for arbeidsområdet.
Bekreft webhook-signaturer
Kontroller signaturen før du stoler på nyttelasten.
Den TypeScript SDK gjør dette for deg, og kaster i stedet for å returnere en boolsk så en handler ikke kan glemme å sjekke:
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);
});
For å verifisere det selv, sammenlign HMAC over {timestamp}.{body} i konstant tid. Legg merke til lengdekontrollen: crypto.timingSafeEqual kaster når de to bufferne varierer i lengde, som en angriper styrer.
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);
});
Kontroller alltid mot råforespørselskroppen. Hvis rammeverket analyserer JSON før verifisering, kan signaturkontrollen mislykkes eller bli upålitelig.
Kanera Sender også X-Kanera-Timestamp og X-Kanera-Event-Id. Avvise leveranser hvis tidsstempel er utenfor noen minutter av nå å bundet replay, og bruke hendelsen id å gjøre handleren idempotent, siden leveranser kan prøves på nytt.
Relaterte utgående alternativer
Webhooks er den generelle banen. To smalere alternativer finnes for bestemte målgrupper:
| Sti | Publikum | Nyttelast | Hvor å sette opp | Abonnement |
|---|---|---|---|---|
| Webhooks | Et annet system | Signert JSON i hele arrangementskatalogen | Arbeidsområdeinnstillinger -> API | Pro eller prøveversjon |
| Chat destinasjoner | En lagkanal | Formaterte meldinger for Slack, Discord, Telegram eller Zulip | Arbeidsområdeinnstillinger -> Integrasjoner | Pro eller prøveversjon |
| Personlige leveringskanaler | En person | ntfy, Gotify, eller signert JSON for dine egne varsler | Profilinnstillinger -> Varsler | Pro eller prøveversjon |
| MCP-hendelsesabonnementer | En AI-agents vert | Signert kort og kommentar forekomster til en tilbakeringing agenten bekreftet | Agenten abonnerer over MCP; ingenting å sette opp i Kanera | Hver plan |
Chat-mål administreres separat fra webhook-endepunkter og vises ikke i webhook-listen, så å rotere en webhook-hemmelighet påvirker aldri et chat-mål.
En automatiserings Ring en webhook handlingen er målrettet i stedet for abonnementsbasert. Det sender automation:webhook:called bare til endepunktet som er valgt på regelen, uavhengig av det endepunktets vanlige eventTypes filter, samtidig som du beholder samme signatur, prøv på nytt og leveringshistorikk. Automatiseringer.
