> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vizochok.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook Architecture

> How VIZOCHOK communicates with your backend via server-to-server webhooks for real-time prices, stock, and cart operations.

VIZOCHOK uses server-to-server HTTP webhooks to communicate with your backend. This is the same architecture used by Stripe, Shopify, and other modern SaaS platforms -- your backend stays in control of prices, stock, and cart state at all times.

***

## Why Webhooks?

VIZOCHOK stores your product **catalog** (names, descriptions, categories) for AI-powered semantic search. However, **prices and stock availability** change frequently and must come from your system of record.

Instead of syncing prices to VIZOCHOK, your backend provides them on-demand when the AI needs them:

<Steps>
  <Step title="AI finds matching SKUs">
    The Catalog DB stores product names, descriptions, and embeddings. When a customer asks for a product, the AI searches and finds matching SKUs.
  </Step>

  <Step title="VIZOCHOK calls your products_url webhook">
    An HTTP POST request with the matching SKUs is sent to your backend to get current prices and stock.
  </Step>

  <Step title="Filter unavailable products">
    Products not returned by your webhook or marked as out of stock are filtered out.
  </Step>

  <Step title="Show results to customer">
    Only available products with live prices are displayed to the customer.
  </Step>
</Steps>

***

## Webhook Types

### Products Webhook (Required)

Called when the AI needs current prices and availability for specific products.

**When it fires**: After the AI searches the catalog and finds matching products, before showing them to the customer.

<Steps>
  <Step title="AI searches catalog">
    AI searches "milk" and finds SKUs: `milk-001`, `milk-002`, `milk-003`.
  </Step>

  <Step title="VIZOCHOK calls your webhook">
    ```json theme={null}
    POST https://your-api.com/api/vizochok/check-products
    {
      "skus": ["milk-001", "milk-002", "milk-003"],
      "store_id": "store-1"
    }
    ```
  </Step>

  <Step title="Your backend responds with prices">
    ```json theme={null}
    {
      "products": [
        {"sku": "milk-001", "price": 45.90, "in_stock": true},
        {"sku": "milk-002", "price": 52.00, "in_stock": true, "promo_price": 42.00, "promo_label": "-19%"},
        {"sku": "milk-003", "price": 38.50, "in_stock": false}
      ]
    }
    ```
  </Step>

  <Step title="VIZOCHOK filters and displays">
    `milk-003` is filtered out (out of stock). `milk-001` and `milk-002` are shown to the customer with correct prices.
  </Step>
</Steps>

Products not returned in the response are treated as unavailable and excluded from results.

See [Products Webhook](/webhooks/products) for the complete specification.

***

### Cart Webhook (Recommended)

Called when the AI performs a cart operation (add, remove, update quantity, clear).

**When it fires**: After the AI decides to modify the cart, before confirming the change to the customer.

<Steps>
  <Step title="AI decides to add product">
    AI decides to add `milk-001` to cart.
  </Step>

  <Step title="VIZOCHOK calls your cart webhook">
    ```json theme={null}
    POST https://your-api.com/api/vizochok/cart
    {
      "action": "add",
      "store_id": "store-1",
      "session_id": "user-123",
      "sku": "milk-001",
      "name": "Молоко Lactel 2.5%",
      "quantity": 1,
      "price": 45.90
    }
    ```
  </Step>

  <Step title="Your backend responds">
    **Success:** `{"ok": true}` -- AI confirms: "Added!"

    **Failure:** `{"ok": false, "reason": "out_of_stock"}` -- AI: "Sorry, that's out of stock. Want to try another brand?"
  </Step>
</Steps>

See [Cart Webhook](/webhooks/cart) for all four operations.

***

### Cart GET Webhook (Optional)

Called once when a new conversation starts, to load the customer's existing cart.

**When it fires**: On the first message of a new conversation, if `cart_get_url` is configured.

<Steps>
  <Step title="New conversation starts">
    Customer sends first message. VIZOCHOK checks if `cart_get_url` is configured.
  </Step>

  <Step title="VIZOCHOK calls your cart GET webhook">
    ```
    GET https://your-api.com/api/vizochok/cart/items
      ?store_id=store-1&session_id=user-123
    ```
  </Step>

  <Step title="Your backend returns current cart">
    ```json theme={null}
    {
      "items": [
        {"sku": "bread-01", "name": "Хліб", "price": 32.00, "quantity": 1, "unit": "pcs"}
      ]
    }
    ```

    AI now knows the customer already has bread and can reference it in conversation.
  </Step>
</Steps>

***

## Setup

### Admin Panel

<Steps>
  <Step title="Open Webhook Settings">
    Log into the [Admin Panel](https://app.vizochok.com), navigate to **Settings > Webhooks**.
  </Step>

  <Step title="Configure Endpoints">
    Enter the URLs for your webhook endpoints:

    * **Products URL**: `https://your-api.com/api/vizochok/check-products`
    * **Cart URL**: `https://your-api.com/api/vizochok/cart`
    * **Cart GET URL**: `https://your-api.com/api/vizochok/cart/items`
    * **Timeout**: How long VIZOCHOK waits for your response (default: 5 seconds)

    <Warning>
      Webhook URLs must use HTTPS. Private IPs and localhost addresses are rejected for security.
    </Warning>
  </Step>

  <Step title="Save and Note Your Secret">
    When you save, VIZOCHOK auto-generates a webhook secret if one doesn't already exist. This secret is used to sign every webhook request with HMAC-SHA256.

    You can also provide your own secret or rotate it later.
  </Step>
</Steps>

Webhook settings are also available via the REST API -- see the API Reference tab.

### Testing Webhooks

The Admin Panel includes a built-in webhook test under **Settings > Webhooks**. Click "Test" to send a test request to your products URL and verify connectivity.

<Tip>
  If the test fails, check:

  * Is your endpoint publicly accessible (not behind a VPN or firewall)?
  * Does your server respond within the timeout (default 5 seconds)?
  * Is the URL using HTTPS?
  * If you verify signatures, does your secret match?
</Tip>

***

## Request Signing

Every webhook request includes HMAC-SHA256 signature headers:

| Header                 | Value                    |
| ---------------------- | ------------------------ |
| `X-VIZOCHOK-Signature` | `sha256=<hex_digest>`    |
| `X-VIZOCHOK-Timestamp` | Unix timestamp (seconds) |
| `Content-Type`         | `application/json`       |

The signature covers both the timestamp and the request body to prevent replay attacks. See [Signature Verification](/webhooks/signature) for implementation details.

***

## Error Handling

| Scenario                       | VIZOCHOK Behavior                                                                  |
| ------------------------------ | ---------------------------------------------------------------------------------- |
| Products webhook timeout/error | All products treated as unavailable                                                |
| Cart webhook timeout/error     | `{ok: false, reason: "webhook_timeout"}` -- AI tells customer the operation failed |
| 5xx response                   | Retries once with 1-second delay                                                   |
| Non-200 response               | Treats as failure, no retry                                                        |
| Products not in response       | Filtered out (treated as unavailable)                                              |

***

## Next Steps

<CardGroup cols={3}>
  <Card title="Products Webhook" icon="barcode" href="/webhooks/products">
    Full request/response specification with handler examples.
  </Card>

  <Card title="Cart Webhook" icon="cart-shopping" href="/webhooks/cart">
    Handle all four cart operations with validation.
  </Card>

  <Card title="Signature Verification" icon="shield-check" href="/webhooks/signature">
    HMAC-SHA256 verification in Python, Node.js, and Go.
  </Card>
</CardGroup>
