ÚvodPlatformaCeníkOtázkyNápovědaKontakt Kivea FlexiKivea PohodaKivea účetnictvíKivea fakturace Vyzkoušet zdarma

What is this?

Admin note: This is an “alert system” that proactively pushes updates from your {productName} to your other apps the moment they happen. Instead of your other systems asking “Is there anything new?”, our system calls them and says “Hey, here’s what just changed!”

Who is this for? Administrators should read this to understand how to enable real-time automation in their business. While you can see the active webhooks in your settings, the technical setup (URL and payload handling) must be done by a developer who can build a “listener” for these notifications.

Key benefits for the e-shop:

  • Instant Updates: Keep your warehouse, shipping, or CRM tools updated within seconds of a new order or a stock change.
  • Smart Filtering: Only send alerts for the things that matter (e.g., “only tell me about new orders,” or “only tell me when a product price changes”).
  • Reliable Delivery: If your other system is temporarily down, our system will keep retrying to send the notification until it gets through.
  • Efficient Automation: By pushing data only when it changes, you save on server costs and ensure your integrations are as fast as possible.

Overview

Webhooks allow your application to receive real-time notifications when data changes occur in the system. They are ideal for keeping external systems synchronized with your data.

**Key Features**
- Batched delivery: Changes are collected for 5 seconds and sent in batches (up to 100 changes)
- Advanced filtering: Entity-based, field-based, and column-based filtering
- Reliable delivery: Automatic retries with exponential backoff (1min → 3min → 9min → 27min → 81min)
- ChangeSet grouping: Changes are grouped by changeSet for transactional consistency

How It Works

1. Data Changes

When data changes occur (create, update, delete operations), the system captures these changes.

2. 5-Second Batching Window

Changes are collected for 5 seconds after the first change to create efficient batches.

3. Filtering & Grouping

Changes are filtered based on your webhook configuration (entity, where, columns) and grouped by changeSet for consistency.

4. HTTP POST Delivery

Webhook payload is sent as HTTP POST to your endpoint with up to 100 changes per request.


Webhook Registration Examples

Learn how to register webhooks with different configurations

Register Basic Webhook

Create a webhook for entity changes [badge:Registration|info|right]

POST /c/{companyId}/hooks
Content-Type: application/json

{
    "entity": "products",
    "url": "https://your-api.com/webhooks/products",
    "action": "webhook"
}

Webhook with Entity Filter

Only receive webhooks for specific entities [badge:Filtering|info|right]

POST /c/{companyId}/hooks
Content-Type: application/json

{
    "entity": "units",
    "url": "https://your-api.com/webhooks/units",
    "action": "webhook"
}

Webhook with Where Filter

Filter changes based on field values [badge:Filtering|info|right]

POST /c/{companyId}/hooks
Content-Type: application/json

{
    "entity": "products",
    "url": "https://your-api.com/webhooks/products",
    "action": "webhook",
    "filter": "price > 100 AND status = 'active'"
}

Webhook with Column Filter

Only trigger webhook when specific columns change [badge:Filtering|info|right]

POST /c/{companyId}/hooks
Content-Type: application/json

{
    "entity": "products",
    "url": "https://your-api.com/webhooks/products",
    "action": "webhook",
    "columns": ["price", "status", "inventory_count"]
}

Webhook for All Entities

Receive notifications for all entity changes [badge:Registration|info|right]

POST /c/{companyId}/hooks
Content-Type: application/json

{
    "entity": null,
    "url": "https://your-api.com/webhooks/all-changes",
    "action": "webhook"
}

Webhook with ChangeSet Control

Control whether to include changes within changeSets [badge:Advanced|info|right]

POST /c/{companyId}/hooks
Content-Type: application/json

{
    "entity": "products",
    "url": "https://your-api.com/webhooks/products",
    "action": "webhook",
    "allowInChangeSet": true,
    "disabled": false
}

Webhook with Payload Delivery

Embed the current state of each changed record directly in the payload [badge:Advanced|info|right]

POST /c/{companyId}/hooks
Content-Type: application/json

{
    "entity": "products",
    "url": "https://your-api.com/webhooks/products",
    "action": "webhook",
    "sendPayload": true
}

You can combine sendPayload with any other filter options:

POST /c/{companyId}/hooks
Content-Type: application/json

{
    "entity": "products",
    "url": "https://your-api.com/webhooks/products",
    "action": "webhook",
    "sendPayload": true,
    "columns": ["price", "status"],
    "filter": "status = 'active'"
}

Webhook with columnsToSend

Control exactly which fields (and related data) are included in the data payload [badge:Advanced|info|right]

When columnsToSend is set, the system uses it as a column selector query — it can include relation expansions. If columnsToSend is empty (or omitted), the full record is returned.

POST /c/{companyId}/hooks
Content-Type: application/json

{
    "entity": "products",
    "url": "https://your-api.com/webhooks/products",
    "action": "webhook",
    "sendPayload": true,
    "columnsToSend": ["id", "name", "price", "status", "category.name"]
}

Filtering Features

Control which changes trigger your webhooks

card: Entity Filter
icon: filter
Filter by specific entity type. Set the "entity" field to receive webhooks only for specific entities like "products", "units", etc. Use null to receive all entity changes.
card: Where Filter
icon: code
Advanced field-based filtering. Use SQL-like where clauses to filter changes based on field values. Example: "price > 100 AND status = 'active'"
card: Column Filter
icon: filter
Filter by specific column changes. Use the "columns" array to only trigger webhooks when specific columns have actually changed. Example: ["price", "status", "inventory_count"]
card: ChangeSet Control
icon: play
Include or exclude changeSet data. Control whether changes within changeSets are included using the "allowInChangeSet" field (true/false).
card: Payload Delivery
icon: database
Embed the current record state in every change entry. When "sendPayload" is true, each change in the payload includes a "data" field with the current state of the row. Use "columnsToSend" to select specific fields and relations. Eliminates the need for a follow-up GET request.

Webhook Payload Examples

Examples of webhook payloads your endpoint will receive

Single Change Webhook Payload [badge:Payload|info|right]

Example payload for a single change

{
    "hookId": "hook-123-456",
    "tenantId": "tenant-789",
    "organisationId": "org-101",
    "changeSetId": null,
    "changes": [
        {
            "id": "change-001",
            "entity": "products",
            "operation": "update",
            "rowId": "product-456",
            "changeSetId": null
        }
    ],
    "timestamp": "2025-09-08T10:30:00.000Z"
}

Batch Changes Webhook Payload [badge:Payload|info|right]

Example payload with multiple changes (up to 100)

{
    "hookId": "hook-123-456",
    "tenantId": "tenant-789",
    "organisationId": "org-101",
    "changeSetId": "changeset-abc",
    "changes": [
        {
            "id": "change-001",
            "entity": "products",
            "operation": "create",
            "rowId": "product-456",
            "changeSetId": "changeset-abc"
        },
        {
            "id": "change-002",
            "entity": "products",
            "operation": "update",
            "rowId": "product-457",
            "changeSetId": "changeset-abc"
        },
        {
            "id": "change-003",
            "entity": "categories",
            "operation": "update",
            "rowId": "category-123",
            "changeSetId": "changeset-abc"
        }
    ],
    "timestamp": "2025-09-08T10:30:00.000Z"
}

Payload Webhook Example [badge:Payload|info|right]

When sendPayload: true is set on the hook, each change entry contains a data field with the current state of the row at the time of delivery. This removes the need for your receiver to make a follow-up GET request.

Simple payload (no columnsToSend — full record):

{
    "hookId": "hook-123-456",
    "tenantId": "tenant-789",
    "organisationId": "org-101",
    "changeSetId": null,
    "changes": [
        {
            "id": 10042,
            "entity": "products",
            "operation": "update",
            "rowId": "product-456",
            "changeSetId": null,
            "data": {
                "id": "product-456",
                "name": "Wireless Headphones",
                "code": "WH-1000",
                "price": 149.99,
                "status": "active",
                "inventory_count": 42,
                "category_id": "cat-electronics",
                "updatedAt": "2025-09-08T10:29:58.000Z"
            }
        }
    ],
    "timestamp": "2025-09-08T10:30:00.000Z"
}

With columnsToSend — only selected fields are included; relations are expanded inline:

{
    "hookId": "hook-123-456",
    "tenantId": "tenant-789",
    "organisationId": "org-101",
    "changeSetId": null,
    "changes": [
        {
            "id": 10042,
            "entity": "products",
            "operation": "update",
            "rowId": "product-456",
            "changeSetId": null,
            "data": {
                "id": "product-456",
                "name": "Wireless Headphones",
                "price": 149.99,
                "status": "active",
                "category": {
                    "id": "cat-electronics",
                    "name": "Electronics"
                }
            }
        }
    ],
    "timestamp": "2025-09-08T10:30:00.000Z"
}

For a batch with multiple changes, each entry carries its own data:

{
    "hookId": "hook-123-456",
    "tenantId": "tenant-789",
    "organisationId": "org-101",
    "changeSetId": "changeset-abc",
    "changes": [
        {
            "id": 10050,
            "entity": "products",
            "operation": "create",
            "rowId": "product-500",
            "changeSetId": "changeset-abc",
            "data": {
                "id": "product-500",
                "name": "Smart Watch Pro",
                "code": "SW-PRO",
                "price": 299.00,
                "status": "active",
                "inventory_count": 10,
                "category_id": "cat-electronics",
                "updatedAt": "2025-09-08T10:29:59.000Z"
            }
        },
        {
            "id": 10051,
            "entity": "products",
            "operation": "update",
            "rowId": "product-456",
            "changeSetId": "changeset-abc",
            "data": {
                "id": "product-456",
                "name": "Wireless Headphones",
                "code": "WH-1000",
                "price": 129.99,
                "status": "active",
                "inventory_count": 41,
                "category_id": "cat-electronics",
                "updatedAt": "2025-09-08T10:29:59.000Z"
            }
        }
    ],
    "timestamp": "2025-09-08T10:30:00.000Z"
}
**When to use sendPayload**
- Your receiver needs the record data immediately without a follow-up GET request
- You are syncing data to an external warehouse or search index and need the complete document
- You want to avoid race conditions where a second change arrives before you can fetch the record

**Use columnsToSend to control the shape of `data`**
- Leave `columnsToSend` empty to receive the full flat record
- Set `columnsToSend` to specific field keys to receive only those fields
- Include dotted relation paths (e.g. `category.name`) to have relations expanded inline

**When NOT to use sendPayload**
- You only care about *which* records changed, not their current state (keeps payload smaller)
- The entity has very large records — use `columnsToSend` to limit the shape
- The record may be deleted by the time of delivery; for `delete` operations `data` will be `undefined` (the row no longer exists)

Retry & Backoff Mechanism

Reliable delivery with exponential backoff strategy

card: Initial Retry Delay
icon: clock
1 minute delay after first failure. When a webhook fails, the first retry happens after 1 minute.
card: Exponential Backoff
icon: refresh-cw
Progressive delay increases. Retry delays: 1 min → 3 min → 9 min → 27 min → 81 min → final failure.
card: Maximum Attempts
icon: alert-triangle
5 retry attempts per webhook. After 5 failed attempts, the webhook is removed from the queue and a 1-hour delay is applied.
card: Success Reset
icon: check-circle
Retry count resets on success. When a webhook succeeds, the retry delay and failure count are reset to zero.
**Retry Schedule**
- **1st failure:** Retry in 1 minute
- **2nd failure:** Retry in 3 minutes
- **3rd failure:** Retry in 9 minutes
- **4th failure:** Retry in 27 minutes
- **5th failure:** Retry in 81 minutes
- **Final failure:** Remove from queue, apply 1-hour penalty

Best Practices

Endpoint Requirements

  • Return HTTP 200-299 status codes for successful processing
  • Respond within 120 seconds (request timeout)
  • Use HTTPS endpoints for security
  • Implement idempotency to handle duplicate deliveries

Error Handling

  • Return 4xx status codes for permanent failures (no retry)
  • Return 5xx status codes for temporary failures (will retry)
  • Log webhook payloads for debugging failed deliveries
  • Implement graceful degradation for temporary outages

Filtering Best Practices

  • Use specific entity filters to reduce unnecessary webhook calls
  • Implement where filters to only receive relevant changes
  • Use column filters to trigger webhooks only when important fields change
  • Consider using allowInChangeSet: false for simpler processing

Performance Tips

  • Process webhook payloads asynchronously when possible
  • Combine multiple filtering options for precise webhook targeting
  • Monitor webhook failure rates and adjust filters accordingly
  • Use column filters to avoid webhooks on timestamp-only updates