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¶
- Under Settings → API and webhooks, set up the webhook
and tick
order.created,order.updatedor both. - Under Order details to include, tick the optional fields you want.
- Verify the signature on every request.
- 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.
Read an order¶
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.
Payment links¶
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 |