This page explains how to receive real-time notifications from the Kanbert API via webhooks. You can register one or more webhook endpoints that will be called when specific events happen in your workspace.
- You register webhooks via the public API.
- Each webhook belongs to your integration user and is scoped to your domain/workspace.
- For every delivery we sign the JSON payload with an HMAC SHA-256 signature, using a per-subscription secret.
- Your endpoint must respond with a 2xx HTTP status within a few seconds to be considered successful.
All webhook management endpoints require the integration scope. You'll find a detailed description of the endpoints in the API Reference.
Create a webhook via the endpoint to get started.
Webhooks can be scoped by Project or Client. Specific webhooks for task:* and comment:* have to be scoped to a Project.
- HTTP method:
POST - Headers include
Content-Type: application/jsonand a signature header (see below). - Timeout: if your endpoint doesn’t respond within ~3 seconds, the attempt is considered failed.
- Retries: failed deliveries are retried automatically (default total tries: 3) with exponential backoff.
- Success criteria: any
2xxresponse code.
- To avoid noisy bursts when a resource is created/updated multiple times within a very short time window, webhook deliveries are debounced.
- The payload's
datacontains the latest model state at the time of delivery.
Special rules within the debounce window:
- Create absorbs updates: if a resource is created and then updated quickly, a single webhook is sent with
event = …:createanddatareflecting the latest state after those updates. - Delete suppression for pending create: if a delete/force-delete occurs before the debounced delivery of a create, the pending delivery is cancelled and no webhook is sent at all.
- Update → delete sequence: if the window starts with an update and a delete/force-delete happens before send, two webhooks are delivered in order: first
…:update(latest data), then…:delete.
Every webhook request contains an HMAC SHA-256 signature of the JSON payload, computed with your webhook’s secret.
- Header name:
Signature - Algorithm: HMAC-SHA256 over the exact request body (raw JSON string)
- Key: your
signature_secret_keyfrom creation
Example verification (pseudo code):
expected = hex_hmac_sha256(raw_body, signature_secret_key)
received = request.headers['Signature']
if !timingSafeEqual(expected, received): reject(401)Notes:
- Always validate the
Signaturebefore processing. - Use a timing-safe comparison to avoid timing attacks.
- Only accept
application/jsonand the expected fields.
Each delivery has this base shape. "data" always contains the full model data. "changes" and "previous" only contain changed attributes and are not always present.
{
"event": "EVENT",
"resource": {
"type": "TYPE",
"id": "ID"
},
"triggered_by": "UserData",
"data": "ModelData"
}Fields:
event: the event name.resource.type: the resource type involved (e.g.,contact,company).resource.id: the obfuscated identifier of the resource in our system.triggered_by: the user data that triggered the event.data: Current model data.
Example: contact created
{
"event": "contact:create",
"resource": {
"type": "contact",
"id": "X9abC3"
},
"triggered_by": {
"id": "yxZ21d",
"email": "user@emai",
"first_name": "Ada",
"last_name": "Lovelace",
"type": "user"
},
"data": {
"first_name": "Ada",
"last_name": "Lovelace",
"email": "ada@example.com"
}
}You can subscribe to one event per webhook
contact:createcontact:updatecontact:deletecompany:createcompany:updatecompany:deletetask:createtask:updatetask:deletecomment:createcomment:updatecomment:delete
This list reflects the current WebhookEvent enum used by the API.
- Use a unique, secret URL for your webhook endpoint.
- Restrict accepted methods to
POSTand validateContent-Type: application/json. - Verify the
Signatureheader using your storedsignature_secret_key. - Respond quickly (within a couple of seconds); you can enqueue heavy work and return
204 No Contentimmediately. - Implement idempotency by de-duplicating events on your side if needed.
- Log failed verifications and non-2xx responses for troubleshooting.
- 409 on create: a webhook with the same
urlandeventalready exists for your user. - Signature mismatches: compare against the exact raw body you received and the correct secret; watch out for whitespace transformations.
- Long processing times: return early with a
2xxand handle work asynchronously to avoid timeouts and retries.