KHOLO LogoDocs v1.0
Developer Guide

REST API Reference

Full REST API endpoint catalog, payloads, responses, and parameters.

The Kholo Fastify API exposes standard RESTful endpoints for managing orders, line items, product catalogs, customer records, and ERP synchronization.

Base URL (Local): http://localhost:XXXX
Base URL (Production): https://api.yourdomain.co.za


1. Authentication

Endpoints require either:

  1. Bearer Token (JWT): Authorization: Bearer <token> (obtained via Supabase Auth or Clerk PIN login).
  2. API Key: X-Api-Key: kholo_live_xxxx (for machine-to-machine integrations).

2. Orders Endpoints

List Orders

  • Route: GET /api/orders
  • Query Parameters:
    • status: Filter by status (RECEIVED, PENDING_REVIEW, APPROVED, COMPLETED, FAILED, CANCELLED).
    • search: Customer name, phone number, or raw text query.
    • limit: Number of records (default: 50).
    • offset: Pagination offset (default: 0).
  • Response 200 OK:
{
  "orders": [
    {
      "id": "997220b1-3d2e-4fad-a758-fb0fe872aeb0",
      "status": "PENDING_REVIEW",
      "rawText": "10 whites 12.5kg, 4 tastic 10kg",
      "isVoiceNote": false,
      "totalAmount": 2345.00,
      "createdAt": "2026-09-30T09:30:00.000Z",
      "customer": {
        "id": "cust-8832",
        "name": "Clerk (KwaMashu Spaza)",
        "phoneNumber": "+27 00 000 0000",
        "creditStatus": "ACTIVE"
      },
      "lines": [
        {
          "id": "line-1",
          "rawItemText": "whites 12.5kg",
          "quantity": 10,
          "matchConfidence": 0.95,
          "product": {
            "sku": "WSTAR-12.5KG",
            "name": "White Star Super Maize Meal 12.5kg",
            "basePrice": 148.50
          }
        }
      ]
    }
  ]
}

Get Order Details

  • Route: GET /api/orders/:id
  • Response 200 OK: Full order object including customer, line items, parent/child relationships, and ERP references.

Update / Resolve Order Line ("Resolve & Teach")

  • Route: PUT /api/orders/:id/lines/:lineId
  • Request Body:
{
  "productId": "prod-uuid-wstar",
  "teachAlias": true,
  "aliasScope": "CUSTOMER"
}
  • Effect: Updates the order line to the selected product, recalculates subtotals, and registers the phrase in the ProductAlias learning database.

Approve Order & Sync to ERP

  • Route: POST /api/orders/:id/approve
  • Request Body: {}
  • Response 200 OK:
{
  "success": true,
  "orderId": "997220b1-3d2e-4fad-a758-fb0fe872aeb0",
  "status": "COMPLETED",
  "erpSalesOrderId": "SO-2026-8454"
}

Reject / Cancel Order

  • Route: POST /api/orders/:id/reject
  • Request Body:
{
  "reason": "Customer cancelled via phone"
}

Retrieve Warehouse Pick Slip

  • Route: GET /api/orders/:id/pick-slip
  • Response 200 OK:
{
  "pickSlip": {
    "distributorName": "Kholo Distribution Centre",
    "orderId": "997220b1-3d2e-4fad-a758-fb0fe872aeb0",
    "erpSalesOrderId": "SO-2026-8454",
    "customerName": "Clerk (KwaMashu Spaza)",
    "customerPhone": "+27 00 000 0000",
    "lines": [
      {
        "binLocation": "Aisle 1 - Bay A04 (Heavy Staples)",
        "sku": "WSTAR-12.5KG",
        "description": "White Star Maize Meal 12.5kg",
        "quantity": 10,
        "packSize": 1,
        "isZeroRated": true
      }
    ]
  }
}

Stream Voice Note Audio

  • Route: GET /api/orders/:id/audio
  • Headers: Range: bytes=0- (supports HTTP partial content streaming for fast scrubbing).
  • Response 200 / 206: Binary audio stream (audio/ogg or audio/webm).

Split Order Lines

  • Route: POST /api/orders/:id/split
  • Request Body:
{
  "targetLocationId": "loc-uuid-depot-b",
  "lineIds": ["line-uuid-beverages-1", "line-uuid-beverages-2"]
}

3. Product Catalog Endpoints

List Products

  • Route: GET /api/products
  • Query Parameters: category, search, limit, offset.

Create Product

  • Route: POST /api/products
  • Request Body:
{
  "sku": "WSTAR-12.5KG",
  "name": "White Star Super Maize Meal 12.5kg",
  "unitOfMeasure": "bag",
  "packSize": 1,
  "basePrice": 148.50,
  "binLocation": "Aisle 1 - Bay A04",
  "reorderPoint": 50,
  "safetyStock": 20
}

Manage Aliases

  • List Aliases: GET /api/products/:id/aliases
  • Add Alias: POST /api/products/:id/aliases
    {
      "aliasText": "12.5 whites",
      "customerId": null
    }
  • Delete Alias: DELETE /api/aliases/:id

4. Customer Endpoints

List Customers

  • Route: GET /api/customers

Create Customer

  • Route: POST /api/customers
    {
      "phoneNumber": "+27 00 000 0000",
      "name": "Clerk (KwaMashu Spaza)",
      "erpCustomerId": "CUST-8832",
      "priceTier": "TIER_A",
      "creditStatus": "ACTIVE"
    }

Update Credit Status

  • Route: PUT /api/customers/:id/credit-status
    {
      "creditStatus": "HOLD"
    }

5. Webhooks & Simulator

Meta WhatsApp Ingestion Webhook

  • Verification: GET /api/webhooks/whatsapp?hub.mode=subscribe&hub.verify_token=...&hub.challenge=...
  • Event Receiver: POST /api/webhooks/whatsapp (Requires HMAC signature header X-Hub-Signature-256).

Simulator Chat Trigger

  • Route: POST /api/simulator/chat
    {
      "phoneNumber": "+27 00 000 0000",
      "text": "10 whites 12.5kg, 2 cases stoney"
    }

Simulator Voice Upload

  • Route: POST /api/simulator/voice (Multipart form-data containing audio file and phoneNumber).

6. Health & Diagnostics

  • Route: GET /api/health
  • Response 200 OK:
{
  "status": "ok",
  "timestamp": "2026-09-30T09:36:00.000Z",
  "uptime": 14205,
  "version": "1.0.0"
}

On this page