Docs

Endpoints

All paths are relative to https://crm.api.kushicorp.com. API-key endpoints need authentication; storefront endpoints use your store slug.


Integrator API — Orders board (API key)

Create an order

POST /public/v1/orders

Creates an order on your Orders board. Each item either links a catalog product by productId (price and name come from the catalog) or is a free-text line with your own name and unitPrice.

Linking by productId is what lets the order affect inventory — but stock moves when the order reaches Delivered, not when it's created, because the goods are still yours until then. Set the status with PATCH /public/v1/orders/{id} and the deduction happens then, taking from the assigned agent if there is one, otherwise the office. Combos deduct their constituents; a quantity bundle deducts its free gifts.

Request

{
  "customerName": "Ada Obi",
  "phone": "08012345678",
  "address": "12 Marina, Lagos",
  "codAmount": 27500,
  "deliveryFee": 1500,
  "courier": "GIG",
  "source": "shopify",
  "items": [
    { "productId": "3f9c…", "qty": 2 },
    { "name": "Gift wrap", "qty": 1, "unitPrice": 500 }
  ]
}

Only customerName and a non-empty items array are required. New orders start in Pending.

Response201 Created

{ "id": "a1b2…", "reference": "A1B2C3D4", "status": "Pending", "total": 55500 }

Duplicate guard — the same phone + total within 6 hours returns the existing order instead of creating another:

{ "id": "a1b2…", "duplicate": true }

List orders

GET /public/v1/orders?status=Pending&limit=50

Recent orders, newest first. status (optional) filters to one status; limit defaults to 50 (max 200).

Response200 OK

{ "orders": [
  { "id": "a1b2…", "reference": "A1B2C3D4", "customerName": "Ada Obi", "phone": "08012345678",
    "status": "Pending", "paymentStatus": "unpaid", "total": 55500, "source": "shopify",
    "createdAt": "2026-07-21T10:00:00Z", "items": [ { "name": "…", "qty": 2, "unitPrice": 27500 } ] }
] }

Update an order

PATCH /public/v1/orders/{id}

Send status and/or paymentStatus. Statuses: Pending, In Transit, Delivered, Rescheduled, Call Back, Rejected, Follow Up.

{ "status": "In Transit", "paymentStatus": "paid" }

Response200 OK{ "ok": true }

List products

GET /public/v1/products
{ "products": [
  { "id": "3f9c…", "name": "Magic Brush", "sku": null, "unit": "pack", "type": "simple",
    "price": 27500, "cost": 4700, "stock": 98, "isActive": true }
] }

Live stock

GET /public/v1/stock
{ "stock": [
  { "productId": "3f9c…", "name": "Magic Brush", "office": 98, "withAgents": 31, "total": 129 }
] }

Storefront — customer checkout (no key)

Store details

GET /public/v1/store/{slug}

Returns the store name/branding and its active products (with offer tiers) — enough to render a store page.

Place an order

POST /public/v1/store/{slug}/orders

A pay-on-delivery order from a customer. Prices are computed server-side from the catalog. Body: customerName, phone, address, optional email/note, and items: [{ productId, qty }]. Returns { "id": "…" } (or { "id": "…", "duplicate": true }).

Track an order

GET /public/v1/orders/{id}

Public status timeline for one order — the full order id acts as the token. No key required.