Developers

Two endpoints. That's the whole integration.

One feed we pull from you, one webhook we push to you. Keep your Laravel, your WooCommerce, your own database — we don't need to own your catalog to sell from it.

Contract v2HMAC-SHA256 signedCursor paginated
01

The catalog feed

You expose one authenticated JSON endpoint. We pull it every six hours, download and re-host your images, and rebuild the photo-match index so a customer's screenshot resolves to a real variation.

external_id is the dedup key — keep it stable and never reuse it. variation_id must match the id your own checkout uses, or orders we push back won't resolve.

GET /np/products
1GET https://yourshop.com.bd/np/products?cursor=&limit=250
2Authorization: Bearer <feed key>
3
4{
5 "version": "2",
6 "currency": "BDT",
7 "next_cursor": "eyJpZCI6NDI1MH0",
8 "products": [
9 {
10 "external_id": "NK-4001", // stable, never reused
11 "title": "Jamdani Handloom Saree",
12 "description": "Half-silk Jamdani woven in Rupganj.",
13 "category": "Apparel",
14 "price": 6850.00,
15 "compare_at": 7900.00,
16 "stock": 19, // absolute count wins over in_stock
17 "images": [
18 "https://yourshop.com.bd/media/jd-main.jpg",
19 "https://yourshop.com.bd/media/jd-warehouse-raw.jpg"
20 ],
21 "variations": [
22 { "variation_id": "JD-IND", "color": "Indigo", "price": 6850.00, "stock": 12 },
23 { "variation_id": "JD-TER", "color": "Terracotta", "price": 6850.00, "stock": 7 },
24 { "variation_id": "JD-IVY", "color": "Ivory", "price": 7250.00, "stock": 0 }
25 ],
26 "tags": ["saree", "jamdani", "handloom"]
27 }
28 ]
29}
02

The order webhook

When the agent closes an order, we POST it to you. Return a payment_url and the agent sends a bKash or Nagad link straight into the chat; return nothing and it stays cash on delivery.

Orders are always itemised. There is no single-product shortcut shape to branch on — one line item or nine, the payload is identical.

POST /np/orders
1POST https://yourshop.com.bd/np/orders
2Idempotency-Key: np_ord_8f94e19b73424912
3X-NP-Signature: t=1756654800,v1=6f3c9a...
4Content-Type: application/json
5
6{
7 "event": "order.closed",
8 "placed_at": "2026-08-31T15:12:04Z",
9 "channel": "whatsapp",
10 "customer": {
11 "name": "Nabila Hoque",
12 "phone": "01712045590",
13 "address": {
14 "line": "House 42, Road 7, Sector 7, Uttara",
15 "district": "Dhaka",
16 "thana": "Uttara",
17 "delivery_type": "home"
18 }
19 },
20 "lines": [
21 {
22 "external_id": "NK-4201",
23 "variation_id": "JT-NAT",
24 "title": "Jute & Leather Tote · Natural",
25 "quantity": 1,
26 "unit_price": 2980.00
27 }
28 ],
29 "subtotal": 2980.00,
30 "delivery_charge": 80.00,
31 "discount": 0.00,
32 "total": 3060.00,
33 "payment": { "method": "cod", "collected": 0.00 }
34}
Safety

Webhooks retry. Networks lie. Plan for both.

verify.ts
1// Verify X-NP-Signature before you trust the body.
2import { createHmac, timingSafeEqual } from "node:crypto";
3
4export function verify(raw: string, header: string, secret: string) {
5 const parts = Object.fromEntries(
6 header.split(",").map((kv) => kv.split("=") as [string, string])
7 );
8 const age = Math.abs(Date.now() / 1000 - Number(parts.t));
9 if (age > 300) return false; // reject replays older than 5 min
10
11 const expected = createHmac("sha256", secret)
12 .update(parts.t + "." + raw)
13 .digest("hex");
14
15 const a = Buffer.from(expected);
16 const b = Buffer.from(parts.v1 ?? "");
17 return a.length === b.length && timingSafeEqual(a, b);
18}

Signed, not just keyed

Every push carries X-NP-Signature — HMAC-SHA256 over a timestamp and the raw body. A leaked key alone can't forge an order, and a captured request can't be replayed after five minutes.

Stock fails closed

If a product arrives with neither stock nor in_stock, we import it as out of stock. An ambiguous feed makes the agent silent about a product — never confidently wrong about it.

An empty page is an error

A feed that previously returned 214 products and suddenly returns [] is treated as a failure, not a catalog wipe. We keep the last good snapshot and tell you in the sync log.

Fetcher limits

What our crawler will and won't do.

Transport

HTTPS only · no private, loopback or link-local hosts

Redirects

3 maximum, re-validated at each hop

Timeouts

10s connect · 30s per page

Page size

250 items · 25 MB maximum

Pagination

Cursor-based, stable ordering required

Schedule

Every 6 hours, plus manual sync

Egress

Static IP available for your allowlist

Key compare

Constant-time on your side, please

Get started today

Your next customer is typing right now.

Connect your page, upload your products, and start with 50 free AI messages. If it doesn't earn its keep, walk away — nothing to cancel, nothing owed.

  • No card needed
  • Live in 10 minutes
  • Cancel whenever you like

What happens in the first week

  1. Day 1Your page is connected and answering in Bangla.
  2. Day 2Your catalog is synced; photo matching switches on.
  3. Day 4First orders confirmed and booked with the courier.
  4. Day 7You see your automated chats, closed sales, and ROI.