Skip to content

Order API

Get chat orders as signed webhook events, and read or update them over HTTP. Kothok never takes payment; payment only records how the shopper paid.

What Where
Order events POST to your webhook address
Read an order GET https://backend.kothok.ai/order-api/orders/{order_ref}
Update an order POST https://backend.kothok.ai/order-api/orders/{order_ref}/status

Set it up

  1. Under Settings → API and webhooks, set up the webhook and tick order.created, order.updated or both.
  2. Under Order details to include, tick the optional fields you want.
  3. Verify the signature on every request.
  4. To read or update orders, create an API key on the same page (shops only).

Events

order.created fires once per order. order.updated fires when the status, payment, customer, courier or a return or exchange request changes. Each carries the whole order, not a diff, plus on order.updated:

Field Values
changes One or more of status, payment, customer, courier, return_request, exchange_request.
source dashboard, api, chat, store, courier or system. api is the echo of your own call.
request Only for return_request / exchange_request: {type, item, reason, exchange_for}.

Deduplicate on order_ref and ignore events older than the order.updated_at you stored. See Retries and resends.

Fields

Always sent:

Field Notes
order_ref Order number, e.g. KO-123456. Unique per shop.
status new, confirmed, delivered or cancelled.
created_at, updated_at ISO 8601, UTC.
customer.name, customer.phone, customer.address As given in the chat.
items title, quantity, unit_price, currency, size, color, option (null when the product has none).
total, currency Items, plus delivery, minus any discount. Numbers in the shop's currency, not minor units.
discount {code, amount} or null. amount is positive.

Sent only if ticked in the dashboard:

Tick box Adds
Customer email customer.email or null
Order note note
Delivery option and charge delivery: {label, amount} or null
Payment method and status payment (below)
Chat channel channel: widget, whatsapp, messenger or instagram
Product links url on each item

payment:

Field Values
method cod, online (Shopify or WooCommerce checkout) or manual (bKash, Nagad or a payment link)
status cod, unpaid, paid, failed or refunded
provider woocommerce, shopify, payment_link, manual_bkash, manual_nagad, or null for cash on delivery
amount_paid Amount recorded as paid, or null

Authentication

Create an API key under Settings → API and webhooks (shops only). It looks like kok_<id>.<secret> and is shown once. Replace key or Revoke key stops the old key at once.

Authorization: Bearer kok_12.Xq3...

Read an order

GET https://backend.kothok.ai/order-api/orders/KO-123456
Authorization: Bearer kok_12.Xq3...

Returns {"order": {...}} with every field, ticked or not.

Update an order

POST https://backend.kothok.ai/order-api/orders/KO-123456/status
Authorization: Bearer kok_12.Xq3...
Content-Type: application/json

{ "payment_status": "paid", "payment_ref": "TRX8N7A6BC5", "status": "confirmed" }
Field Notes
status confirmed, delivered or cancelled
payment_status paid
amount_paid Optional. More than 0, not above the total. Defaults to what was owed.
payment_ref Optional, up to 100 characters
reason Optional, up to 300 characters, for a cancellation
message Optional, up to 1,000 characters. Replaces the default message to the shopper.
notify_customer Default true. false sends the shopper nothing.

Send status, payment_status or both. Allowed moves: new → confirmed, new or confirmed → cancelled, confirmed → delivered. Repeating a call is safe. The shopper gets at most one message per call; delivered sends nothing unless you send message.

{ "order": {...}, "changed": ["payment_status", "status"], "customer_notified": true, "notify_error": null }

Errors

Errors return {"detail": "..."}.

Status When
401 Missing, malformed or replaced key
403 The business doesn't take orders
404 No order with that number in this shop
409 The move isn't allowed from the current status, not enough stock to confirm, the order is cancelled, or amount_paid is above the total
422 Invalid body, e.g. an unknown field or neither status nor payment_status
429 Over 600 calls a minute per key. Wait a minute; there is no Retry-After.

With payment_status and status: "confirmed" together, the payment is saved first, so a stock 409 leaves it recorded. Read the order before you retry.

Placeholders in a payment link saved in the dashboard are filled in and URL-encoded:

Placeholder Becomes
{order_ref} KO-123456
{amount} Amount due, e.g. 1410 or 1410.50
{currency} e.g. BDT
https://pay.example.com/checkout?ref={order_ref}&amount={amount}&currency={currency}

Still need help?

Tell us what you were trying to do and we will help you sort it out.

Contact support