Build
Booking sales
Book every Scanimart sale -- online and in-store -- into your POS exactly once.
Every sale a store makes through Scanimart has to end up in its books — in your POS. There are two kinds:
channel |
What happened |
|---|---|
SCANIMART_ONLINE |
A delivery order reached the customer |
SCANIMART_INSTORE |
A customer scanned and paid in the aisle with Scan & Go |
Both arrive the same way, as a sale with every line, the price paid, and the payment.
The sale.completed webhook
{
"id": "evt_6512bd43d9caa6e02c990b0a82652dca",
"object": "event",
"type": "sale.completed",
"store_id": 1042,
"data": {
"channel": "SCANIMART_ONLINE",
"sale": {
"object": "sale",
"id": "ORDER-1A2B3C4D5E",
"external_id": "BILL-20391",
"channel": "SCANIMART_ONLINE",
"sold_at": "2026-10-08T11:02:00+05:30",
"total_amount": "297.00",
"delivery_fee": "30.00",
"payment": { "status": "SUCCESS", "paid": true, "method": "UPI" },
"lines": [ "…" ]
}
}
}Book it into your POS, then answer 2xx. This is the webhook rule — make the event durable before you answer — where the durable record is the booked sale: answering is how Scanimart knows your stock count already includes that sale. Until you answer, it keeps subtracting those units from the counts you push (see Inventory sync). Answer before the sale is booked and a count you push in between puts sold units back on the shelf.
Booking has to fit in the 10 seconds a webhook allows. If it cannot — your POS books in batches, say — leave sale.completed off your endpoint's events and pull sales instead.
Book each sale once. The event id is unique — dedupe on it, since a retry can deliver the same sale again.
Taxes
Prices are tax-inclusive, as the customer paid them. Scanimart does not split out GST: your POS applies its own tax rules to the lines when it books them, the same as for a counter sale.
Pulling instead
If you cannot receive webhooks, or as a nightly safety net, list sales instead:
curl "https://api.scanimart.com/v1/stores/1042/sales?since=2026-10-08T00:00:00%2B05:30" \
-H "Authorization: Bearer $SCANIMART_KEY"Oldest first, the last 30 days, paginated. Each sale carries event_id. After booking, acknowledge them so they stop being subtracted from your counts:
curl -X POST https://api.scanimart.com/v1/stores/1042/sales/ack \
-H "Authorization: Bearer $SCANIMART_KEY" \
-H "Content-Type: application/json" \
-d '{"event_ids": ["evt_6512bd43d9caa6e02c990b0a82652dca"]}'Up to 500 per call. Acknowledging the same sale twice is harmless.
Exit checks
For in-store sales you may also see sale.exit_verified: the customer's basket was checked at the door. It is informational; the sale was already complete.
