Skip to main content
The products webhook is called by VIZOCHOK when the AI needs current prices and availability for a set of products. Your endpoint receives a list of SKUs and returns pricing data for each.

Request Format

Method: POST Headers:
HeaderValue
Content-Typeapplication/json
X-VIZOCHOK-Signaturesha256=<hex_digest>
X-VIZOCHOK-TimestampUnix timestamp (seconds)
Body:
{
  "skus": ["milk-001", "milk-002", "milk-003"],
  "store_id": "store-1"
}
skus
string[]
required
List of product SKUs to look up. Typically 1-10 SKUs per request, matching what the AI found in the catalog search.
store_id
string
required
Store identifier. Use this to return location-specific pricing if your stores have different prices.

Response Format

Return a JSON object with a products array. Each product must include at minimum sku, price, and in_stock:
{
  "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
    }
  ]
}

Response Fields

products
array
required
Array of product pricing objects.
sku
string
required
Product SKU (must match a requested SKU).
price
number
required
Current retail price.
in_stock
boolean
required
Whether the product is currently available. Products with in_stock: false are filtered out and not shown to the customer.
promo_price
number
Promotional/discounted price. When present, the AI highlights the discount to the customer.
promo_label
string
Promotional label displayed alongside the price (e.g., "-19%", "SALE", "2 for 1").

Important Behavior

  • Missing SKUs: If a requested SKU is not included in your response, VIZOCHOK treats it as unavailable and excludes it from results.
  • Out of stock: Products with in_stock: false are filtered out — the customer will not see them.
  • Promotions: When promo_price is present, the AI automatically mentions the discount (e.g., “This milk is on sale: 42.00 instead of 52.00”).

Handler Examples

from fastapi import FastAPI, Request, HTTPException
from pydantic import BaseModel
import hmac
import hashlib
import time

app = FastAPI()

WEBHOOK_SECRET = "your_webhook_secret"

def verify_signature(request: Request, body: bytes):
    sig_header = request.headers.get("x-vizochok-signature", "")
    timestamp = request.headers.get("x-vizochok-timestamp", "")

    if not sig_header.startswith("sha256="):
        raise HTTPException(401, "Missing signature")

    # Check timestamp (5-minute tolerance)
    if timestamp:
        if abs(time.time() - int(timestamp)) > 300:
            raise HTTPException(401, "Timestamp expired")
        signed_payload = f"{timestamp}.".encode() + body
    else:
        signed_payload = body

    expected = hmac.new(
        WEBHOOK_SECRET.encode(), signed_payload, hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(sig_header[7:], expected):
        raise HTTPException(401, "Invalid signature")


class CheckProductsRequest(BaseModel):
    skus: list[str]
    store_id: str


@app.post("/api/vizochok/check-products")
async def check_products(req: CheckProductsRequest, request: Request):
    body = await request.body()
    verify_signature(request, body)

    # Look up products in your database
    products = []
    for sku in req.skus:
        product = await db.get_product(sku, store_id=req.store_id)
        if product:
            item = {
                "sku": sku,
                "price": product.price,
                "in_stock": product.stock > 0,
            }
            if product.promo_price:
                item["promo_price"] = product.promo_price
                item["promo_label"] = product.promo_label
            products.append(item)

    return {"products": products}

Testing

You can test your products webhook from the VIZOCHOK admin panel or via the API:
curl -X POST https://api.vizochok.com/api/v1/admin/webhooks/test \
  -H "Authorization: Bearer sk_your_secret_key"
This sends a test request with sample SKUs to your configured products_url and reports the result. You can also test locally using curl:
curl -X POST http://localhost:8081/api/vizochok/check-products \
  -H "Content-Type: application/json" \
  -d '{
    "skus": ["milk-001", "bread-042"],
    "store_id": "store-1"
  }'

Performance Tips

Keep your products webhook fast (under 2 seconds). The customer is waiting for search results while this call happens. The default timeout is 5 seconds, but faster responses mean a better experience.
  • Batch efficiently: You will receive 1-10 SKUs per request. Use a single database query with IN clause rather than individual lookups.
  • Cache prices: If your pricing system is slow, consider a short-lived cache (30-60 seconds) for price lookups.
  • Return early: Only include promo_price and promo_label when there is actually a promotion. Omitting optional fields is fine.