Skip to main content
A webhook is an HTTP POST from klikit to a URL you host. Whenever something happens on klikit that you care about — a new order, a status change, a cart edit — klikit sends you the details. You don’t poll. You just answer the phone when it rings.

The mental model

1

You host an endpoint

e.g. https://api.yourcompany.com/integrations/klikit/webhooks. It needs to be HTTPS, publicly reachable from klikit’s egress IPs, and capable of handling a few requests per second per branch you operate.
2

Your klikit operator registers the URL

They map your URL to a (brand, branch, event) tuple. One URL per tuple today — there’s no self-service registration. Send your URL + environment to [email protected].
3

An event happens on klikit

A customer places an order. An operator marks one as READY. A cart is edited mid-checkout. Klikit’s outbound webhook delivery service picks up the event.
4

Klikit POSTs to your URL

JSON body, signed with your webhook secret in the x-klikit-signature header. See Verify signatures for the exact recipe.
5

You reply 2xx within 10 seconds

Any other reply (or a timeout) is treated as a failed delivery and retried with exponential backoff. Failed deliveries are persisted — your operator can replay them after you recover from downtime.

What you’ll receive

All three event types share the same JSON envelope:
{
  "brand_id":  123,
  "branch_id": 456,
  "orders":    [ /* one or more orders, same shape as GET /v1/partner/orders */ ]
}
Every delivery carries these headers:
HeaderPurpose
x-klikit-signaturehex(HMAC-SHA256(your webhook_secret, raw request body))
x-klikit-event-idUnique per delivery attempt. Use for idempotency.
x-klikit-event-typeOne of the three event names. See Event catalogue.
Content-TypeAlways application/json.

The three event types

klikit.order.created.v2

A new order just landed. Ring the kitchen.

klikit.order.status.updated

An order moved to a new state.

klikit.order.cart.updated

A cart was edited before checkout.

Five things you must get right

The HMAC is computed over the exact bytes klikit sent. If you parse the JSON and re-serialise before verifying, key reordering or whitespace differences will break the signature. Most frameworks have a “capture the raw body” hook — see the reference receivers for how.
Use crypto.timingSafeEqual (Node), hmac.compare_digest (Python), or your language’s equivalent. A naïve == is vulnerable to timing side-channels.
Klikit retries on any non-2xx, so the same x-klikit-event-id will arrive twice in some failure modes. Store the IDs you’ve already processed (Redis SETNX, Postgres unique index, etc.) and silently return 2xx for repeats.
Klikit’s delivery timeout is 10 seconds. If your endpoint takes 11 seconds to push to a slow POS and then returns 200, klikit has already counted it as a timeout and queued a retry — you’ll process every order twice. Reply 200 immediately, then queue the work.
Klikit ignores the body of your response, but if you do return a body, make it valid JSON to avoid logging noise on both sides.

Where to go from here

Verify signatures

Copy-pasteable HMAC verification in Node, Python, Go, PHP, and shell.

Event catalogue

What each event means, when it fires, what the payload looks like.

Troubleshooting

Symptom → cause table for the common integration failures.

Reference Node receiver

~80 lines, runs as-is, demonstrates all five musts.