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:
- Bearer Token (JWT):
Authorization: Bearer <token>(obtained via Supabase Auth or Clerk PIN login). - 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
ProductAliaslearning 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/oggoraudio/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 headerX-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 containingaudiofile andphoneNumber).
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"
}