Who reads which path
| You are | Read | Skip |
|---|---|---|
| A POS / kitchen system receiving klikit orders | Phases 1, 2, 3-POS, 4, 5 | 3-Aggregator |
| An aggregator / marketplace consuming klikit menus and pushing visibility | Phases 1, 2, 3-Aggregator, 4, 5 | 3-POS |
Phase 1 — Foundation
The flat work: get credentials, understand the contract, point at the right environment.- Get credentials from your klikit integration contact. You’ll receive
a
partner_key, asecret_key, and (if you’ll receive webhooks) awebhook_secret. Treat them like passwords; rotate via support if you suspect a leak. See Authentication. - Pick your environment. The development environment is your
sandbox — there is no separate staging tier. See
Environments.
- Dev:
https://api.dev.shadowchef.co/v1/partner - Prod:
https://gateway-enterprise.klikit.io/v1/partner
- Dev:
- Confirm scopes. Your credential is granted a fixed subset of
scopes —
orders:read,menus:read,menus:oos, etc. Hit one endpoint per scope you need and confirm 200 before designing around it. - Read the response envelope and error codes. Both are short. Doing this now saves a week of “but the response shape is weird” tickets.
curl -u "$KEY:$SECRET" $BASE/brands returns 200 with a
real data block.
Phase 2 — Map your business
Before any integration logic, build a local picture of what you’re working with. Klikit’s hierarchy is business → brands → branches, and every other id you’ll see references one of those three.GET /v1/partner/brands
Returns the brand catalogue for your business. Each entry has id,
business_id, title, logo, banner. Cache this; it changes weekly,
not hourly.
GET /v1/partner/branches
Returns the physical/virtual stores under your business — addresses,
opening hours, currency, supported order types, payment methods,
geo coordinates. Paginated with page/size. Critical fields:
id, brand_id, currency_code, lat, long, status,
payment_methods, available_times.
{brand_id, branch_id} → your internal store id. This mapping is the joinkey for everything in
phase 3.
Phase 3 — Pick your starting module
This is the branch in the road.Path A — POS / kitchen system
You want orders to flow from klikit into your POS, and status updates to flow back. Two modules to wire, in this order. A1. Read ordersGET /v1/partner/orders?page=1&size=20returns the order list, reverse-chronological. Usefrom/to(max 90-day window) to bound bycreated_at.GET /v1/partner/orders/{id}returns the full order — cart, customer, payment, fulfillment details. Use this on every order you intend to process; the list response is rich but the detail call is canonical.- Decode
statusviaGET /orders/statuses— IDs are stable across releases.
PATCH /v1/partner/orders/{id}/statustransitions an order throughaccepted → ready → picked_up(or terminalrejected/cancelled). Cancellations need areason_code. Always sendIdempotency-Key— see Idempotency.
accepted,
then ready, then picked_up, with the changes reflecting in klikit’s
admin UI.
Path B — Aggregator / marketplace
You want klikit menus on your surface, and you want to be able to toggle items in/out of stock and hide branches. Three modules, in this order. B1. Read menusGET /v1/partner/menus?brand_id=&branch_id=returns the store-level menu — sections → categories → items → modifier groups → modifier options — with all store-specific overrides applied. This is what to display to your customers.GET /v1/partner/menus(no params) returns the business-level menu — no store overrides. Useful for cataloguing across stores.
PATCH /v1/partner/items/{partner_item_id}/availabilityflips a single item in or out of stock. Bulk variant available. SendIdempotency-Keyon every call.
- Branch and brand visibility toggles let you hide a store or an entire
brand from your surface without affecting other partners. See the
API reference under
visibility.
Phase 4 — Add real-time (webhooks)
Polling works for development. Production wants pushes. Klikit emits three webhook event types and you subscribe by giving your klikit operator a receiver URL per(brand, branch, event) tuple.
| Event | When it fires | Subscribe if |
|---|---|---|
klikit.order.created.v2 | A new order lands | You’re a POS (mandatory) |
klikit.order.status.updated | An order moves to a new state | You’re a POS (recommended) |
klikit.order.cart.updated | The cart changes pre-checkout | You preview baskets pre-checkout (optional) |
- Webhooks overview — concepts and five-things-you-must-get-right.
- Verify signatures — HMAC recipe in 5 languages.
- Event catalogue — payload shapes per event.
- Node and Python reference receivers.
x-klikit-event-id, and acknowledges with 2xx in <1s. Test by asking
your operator to replay a failed delivery from hookit.webhook_logs.
Phase 5 — Production readiness checklist
Before you flip the base URL fromapi.dev.shadowchef.co to
gateway-enterprise.klikit.io:
Credentials & secrets
Credentials & secrets
- Production credentials issued by your klikit contact (separate from dev).
webhook_secretstored in your secrets manager, not in source.- Rotation runbook on file. Old secret stays valid for 15 minutes after rotation — schedule rotations during low-traffic windows.
Retries & idempotency
Retries & idempotency
- Every write call sends a fresh
Idempotency-Key(UUID) per logical action. - Retries reuse the same key on the same action; never regenerate mid-retry.
- Exponential backoff with jitter: 500ms → 30s, max 5 attempts.
- You only retry on
RATE_LIMITED,DOWNSTREAM_UNAVAILABLE,INTERNAL, and network timeouts. You do not retry onREQUEST_INVALIDorFORBIDDEN_SCOPE.
Webhook receiver
Webhook receiver
- Endpoint is HTTPS, publicly reachable from klikit’s egress, returns 2xx within 1 second (process async).
- HMAC-SHA256 verification of
x-klikit-signatureagainst the raw request body (not the parsed-and-reserialised JSON). - Idempotency keyed on
x-klikit-event-idin a persistent store (Redis SETNX, Postgres unique index — not an in-memorySet). - 10-second timeout budget understood; processing pushed to a durable queue if downstream is slow.
Logging & support
Logging & support
- Every klikit response’s top-level
request_idis captured in your logs alongside the operation it represented. - You can quote any
request_idto [email protected] and have us find the request end-to-end. - On webhook deliveries, you log
x-klikit-event-idfor the same reason.
Data freshness
Data freshness
- Brands and branches cached locally with a re-fetch interval that matches your business reality (daily is usually fine).
- Menus refreshed on webhook signal or, if not subscribed, polled at a cadence your klikit operator agrees with (typically every 5 minutes for active stores).
- Order list polled with
from/tono wider than 90 days per call.
Observability
Observability
- You alert on a sustained
5xxrate from klikit (DOWNSTREAM_UNAVAILABLE,INTERNAL). - You alert on rising
4XX(especiallyFORBIDDEN_SCOPE— usually means a scope was revoked). - Webhook delivery success rate visible on a dashboard; failures paged.
Sign-off
Sign-off
- At least one end-to-end test in production with your klikit contact observing, against a real (or staging) branch.
- Cancellation path tested with a real
reason_code. - Rotation, replay, and dispute runbooks reviewed with your klikit contact.
Where to next
Quickstart
5-minute hands-on, if you haven’t already.
Webhooks integration guide
Full receiver-side recipe.
API reference
Endpoint-by-endpoint, with real prod responses embedded.
Reference receivers
Copy-paste Node and Python webhook servers.