Stock Management API
Record and manage inventory movements with VSCU integration.
Overview
The Stock API allows you to record stock movements (stock in, stock out, adjustments) and sync them with KRA eTIMS. All stock movements are submitted to VSCU for compliance tracking.
Automatic Stock Management: Stock levels are automatically updated when you create sales (decreases stock) or purchases (increases stock) through their respective APIs. The Stock API provides endpoints to view current stock levels and complete movement history.
Create Stock Movement
Record a stock movement (stock in, stock out, or adjustment).
/api/v1/stockCreate Stock Movement
Record a stock movement and sync to VSCU. Supports stock in (11), stock out (12), and adjustments (13).
Field Descriptions
Main Fields
| Field | Type | Required | Description |
|---|---|---|---|
branch_id | string | Yes | Branch identifier (bhf_id) |
sar_no | string | Yes | Stock adjustment/receipt number |
sar_ty_cd | string | Yes | SAR type code (11=Receive, 12=Out, 13=Adjustment) |
sar_dt | string | Yes | SAR date in YYYYMMDD format |
sar_rcv_dt | string | No | Receipt date in YYYYMMDD format |
tot_item_cnt | integer | Yes | Total number of items |
tot_taxbl_amt | number | Yes | Total taxable amount |
tot_tax_amt | number | Yes | Total tax amount |
tot_amt | number | Yes | Total amount including tax |
remark | string | No | Remarks/notes |
Item Fields
| Field | Type | Required | Description |
|---|---|---|---|
item_seq | integer | Yes | Item sequence number |
item_cd | string | Yes | Item code |
item_clss_cd | string | Yes | Item classification code |
item_nm | string | Yes | Item name |
bcd | string | No | Barcode |
pkg_unit_cd | string | Yes | Package unit code |
pkg | number | Yes | Number of packages |
qty_unit_cd | string | Yes | Quantity unit code |
qty | number | Yes | Quantity |
item_expr_dt | string | No | Expiry date (YYYYMMDD) |
prc | number | Yes | Unit price |
sply_amt | number | Yes | Supply amount |
tot_dcamt | number | No | Total discount amount |
taxbl_amt | number | Yes | Taxable amount |
tax_ty_cd | string | Yes | Tax type code |
tax_amt | number | Yes | Tax amount |
tot_amt | number | Yes | Total amount |
SAR Type Codes
| Code | Description |
|---|---|
11 | Stock In (Receipt) |
12 | Stock Out |
13 | Stock Adjustment |
Response
Status: 200 OK
{
"status": "success",
"data": {
"transaction_id": "9d3f4b1a-7c8e-4d2f-b5a6-1e3c9f8d2b4a",
"sar_no": "SAR-2024-001",
"sar_type": "11",
"item_count": 1,
"total_amount": 116000,
"vscu_receipt_code": "000",
"vscu_receipt_msg": "SUCCESS"
},
"meta": {
"timestamp": "2024-01-15T14:30:30Z",
"request_id": "req_123abc"
}
}List Stock Levels
Get current stock levels for all items in a branch.
/api/v1/stockList Stock Levels
Retrieve actual current stock quantities for all items. Stock levels are automatically updated by sales and purchases.
item_codeFilter by item code (partial match)
item_nameFilter by item name (partial match)
barcodeFilter by barcode (partial match)
low_stockFilter items below safety quantity
out_of_stockFilter items with zero or negative stock
sort_bySort field (item_code, item_name, current_qty, last_synced_at)
sort_orderSort direction (asc or desc)
per_pageResults per page (max 100)
Response
Status: 200 OK
{
"status": "success",
"data": [
{
"item_id": "123",
"item_code": "KE2BXU0000001",
"item_name": "Laptop Computer",
"item_class_code": "5020230201",
"barcode": "12345678",
"current_qty": 150.5,
"safety_qty": 20,
"is_low_stock": false,
"is_out_of_stock": false,
"qty_unit_code": "U",
"default_price": 2000,
"tax_type_code": "A",
"tax_type_name": "16% VAT",
"last_synced_at": "2024-01-15T14:30:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 50,
"total": 234,
"total_pages": 5,
"timestamp": "2024-01-15T14:30:00Z"
}
}Response Fields
| Field | Type | Description |
|---|---|---|
item_id | string | Internal item ID |
item_code | string | Item code |
item_name | string | Item name |
item_class_code | string | Item classification code |
barcode | string | Barcode |
current_qty | number | Current quantity in stock (updated by sales/purchases) |
safety_qty | number | Safety/minimum stock level |
is_low_stock | boolean | True if current_qty is less than or equal to safety_qty |
is_out_of_stock | boolean | True if current_qty is less than or equal to 0 |
qty_unit_code | string | Quantity unit code (U, BX, etc.) |
default_price | number | Default selling price |
tax_type_code | string | Tax type (A, B, C, D, E) |
tax_type_name | string | Tax type name (e.g., “16% VAT”) |
last_synced_at | string | Last sync with KRA timestamp |
Get Item Stock Details & History
Get current stock level and complete movement history for a specific item, including sales (OUT), purchases (IN), and explicit stock movements.
/api/v1/stock/{item_code}Get Item Stock Details
Retrieve current stock level and complete movement history including sales, purchases, and stock adjustments.
item_code*Item code
from_dateFilter movements from date (YYYY-MM-DD)
to_dateFilter movements to date (YYYY-MM-DD)
per_pageMovements per page (max 50)
Response
Status: 200 OK
{
"status": "success",
"data": {
"item": {
"item_id": "123",
"item_code": "KE2BXU0000001",
"item_name": "Laptop Computer",
"item_class_code": "5020230201",
"barcode": "12345678",
"current_qty": 150.5,
"safety_qty": 20,
"is_low_stock": false,
"is_out_of_stock": false,
"qty_unit_code": "U",
"default_price": 2000,
"tax_type_code": "A",
"last_synced_at": "2024-01-15T14:30:00Z"
},
"movements": [
{
"transaction_id": "abc-123",
"type": "sales",
"movement_type": "SALE",
"direction": "OUT",
"qty": 5,
"invoice_no": "INV-2024-001",
"reference": "Sale: INV-2024-001",
"date": "2024-01-15T10:00:00Z"
},
{
"transaction_id": "def-456",
"type": "purchase",
"movement_type": "PURCHASE",
"direction": "IN",
"qty": 50,
"invoice_no": "PUR-2024-001",
"reference": "Purchase: PUR-2024-001 from ABC Suppliers Ltd",
"date": "2024-01-14T14:30:00Z"
},
{
"transaction_id": "ghi-789",
"type": "stock",
"movement_type": "11",
"direction": "IN",
"qty": 100,
"invoice_no": null,
"reference": "Stock Adjustment: SAR-123",
"date": "2024-01-10T09:00:00Z"
}
]
},
"meta": {
"current_page": 1,
"per_page": 20,
"total_movements": 45,
"total_pages": 3,
"timestamp": "2024-01-15T14:30:00Z"
}
}Movement Types
| Type | Direction | Description |
|---|---|---|
SALE | OUT | Stock decreased by a sale |
PURCHASE | IN | Stock increased by a purchase |
11 | IN | Stock In (Receipt) |
21 | OUT | Stock Out |
| Other | ADJUST | Stock adjustment |
Use Case
This endpoint gives you complete visibility into why stock levels changed over time. You can see:
- Sales that decreased stock
- Purchases that increased stock
- Explicit stock movements/adjustments
- Complete audit trail for compliance
Get Stock Movement History
Get complete stock movement history across all items, including sales (OUT), purchases (IN), and explicit stock movements.
/api/v1/stock/movementsGet Stock Movement History
Retrieve complete movement history showing all stock changes from sales, purchases, and adjustments.
item_codeFilter by specific item code
typeFilter by transaction type (sales, purchase, stock)
from_dateFilter from date (YYYY-MM-DD)
to_dateFilter to date (YYYY-MM-DD)
sort_orderSort direction (asc or desc)
per_pageResults per page (max 100)
Response
Status: 200 OK
{
"status": "success",
"data": [
{
"transaction_id": "abc-123",
"item_code": "KE2BXU0000001",
"item_name": "Laptop Computer",
"type": "sales",
"movement_type": "SALE",
"direction": "OUT",
"qty": 5,
"unit_price": 2000,
"total_amount": 10000,
"invoice_no": "INV-2024-001",
"reference": "Sale: INV-2024-001",
"date": "2024-01-15T10:00:00Z"
},
{
"transaction_id": "def-456",
"item_code": "KE1BGKG0000002",
"item_name": "Maize Grain",
"type": "purchase",
"movement_type": "PURCHASE",
"direction": "IN",
"qty": 50,
"unit_price": 1500,
"total_amount": 75000,
"invoice_no": "PUR-2024-001",
"reference": "Purchase: PUR-2024-001 from ABC Suppliers Ltd",
"date": "2024-01-14T14:30:00Z"
},
{
"transaction_id": "ghi-789",
"item_code": "KE2BXU0000001",
"item_name": "Laptop Computer",
"type": "stock",
"movement_type": "11",
"direction": "IN",
"qty": 100,
"unit_price": 2000,
"total_amount": 200000,
"invoice_no": null,
"reference": "Stock Adjustment: SAR-123",
"date": "2024-01-10T09:00:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 50,
"total": 345,
"total_pages": 7,
"timestamp": "2024-01-15T14:30:00Z"
}
}Response Fields
| Field | Type | Description |
|---|---|---|
transaction_id | string | Unique transaction identifier |
item_code | string | Item code |
item_name | string | Item name |
type | string | Transaction type (sales, purchase, stock) |
movement_type | string | Human-readable movement type |
direction | string | Stock direction (IN, OUT, ADJUST) |
qty | number | Quantity moved |
unit_price | number | Unit price at time of movement |
total_amount | number | Total amount for this line item |
invoice_no | string | Invoice/reference number |
reference | string | Human-readable reference |
date | string | Movement date/time |
Use Cases
Inventory Audit Trail
// Get all movements for the last month
const response = await axios.get(`${baseURL}/stock/movements`, {
params: {
from_date: '2024-01-01',
to_date: '2024-01-31',
per_page: 100
},
headers: { Authorization: `Bearer ${apiKey}` }
});Track Specific Item
// Get all movements for a specific item
const response = await axios.get(`${baseURL}/stock/movements`, {
params: {
item_code: 'KE2BXU0000001',
sort_order: 'desc'
},
headers: { Authorization: `Bearer ${apiKey}` }
});Sales Analysis
// Get only sales movements
const response = await axios.get(`${baseURL}/stock/movements`, {
params: {
type: 'sales',
from_date: '2024-01-01',
to_date: '2024-01-31'
},
headers: { Authorization: `Bearer ${apiKey}` }
});Save Stock Master
Update stock master information (remaining quantity) for an item. This endpoint should be called AFTER recording stock movements to update the final inventory count.
/api/v1/stock/masterSave Stock Master
Update the stock master (remaining quantity) for an item in VSCU.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
item_code | string | Yes | Item code |
remaining_qty | number | Yes | Remaining quantity (min: 0) |
remark | string | No | Optional remark/notes |
Response
Status: 200 OK
{
"status": "success",
"message": "Stock master saved successfully with KRA",
"data": {
"item_code": "KE2BXU0000001",
"remaining_qty": 150.5,
"synced_to_kra": true
},
"meta": {
"timestamp": "2024-01-15T14:30:30Z",
"request_id": "req_123abc"
}
}Use Case
After recording stock movements (IN/OUT/ADJUSTMENTS), call this endpoint to update the final remaining quantity in the VSCU system. This ensures KRA has accurate inventory levels.
Code Example
// Update stock master after movements
await axios.post(`${baseURL}/stock/master`, {
item_code: 'KE2BXU0000001',
remaining_qty: 150.5,
remark: 'After physical count'
}, {
headers: { Authorization: `Bearer ${apiKey}` }
});Fetch Stock Items
Retrieve unrecorded stock items from VSCU for a branch. This endpoint fetches stock items that exist in the VSCU system but haven’t been recorded locally yet.
/api/v1/stock/itemsFetch Stock Items
Retrieve unrecorded stock items from VSCU.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
branch_id | string | Yes | Branch identifier (bhf_id) |
Response
Status: 200 OK
{
"status": "success",
"message": "Fetched pending stock items",
"data": [
{
"itemCd": "KE2BXU0000001",
"itemClsCd": "5020230201",
"itemNm": "Laptop Computer",
"bcd": "12345678",
"pkgUnitCd": "CT",
"qtyUnitCd": "U",
"qty": 50,
"prc": 2000,
"splyAmt": 100000,
"taxTyCd": "A",
"taxAmt": 16000,
"totAmt": 116000,
"lastReqDt": "20240115000000"
}
],
"meta": {
"timestamp": "2024-01-15T14:30:00Z",
"request_id": "req_123abc"
}
}Response Fields
| Field | Type | Description |
|---|---|---|
itemCd | string | Item code |
itemClsCd | string | Item classification code |
itemNm | string | Item name |
bcd | string | Barcode |
pkgUnitCd | string | Package unit code |
qtyUnitCd | string | Quantity unit code |
qty | number | Quantity |
prc | number | Unit price |
splyAmt | number | Supply amount |
taxTyCd | string | Tax type code |
taxAmt | number | Tax amount |
totAmt | number | Total amount |
lastReqDt | string | Last request datetime |
Use Case
This endpoint is used to synchronize stock items from VSCU that may have been created through other channels or branches. Call it periodically to ensure your local inventory is in sync with VSCU.
Code Example
// Fetch pending stock items
const response = await axios.post(`${baseURL}/stock/items`, {
branch_id: '00'
}, {
headers: { Authorization: `Bearer ${apiKey}` }
});
const pendingItems = response.data.data;
// Process and record stock movements
for (const item of pendingItems) {
// Create stock movement record
await axios.post(`${baseURL}/stock`, {
branch_id: '00',
sar_no: `SAR-${Date.now()}`,
sar_ty_cd: '11', // Stock In
sar_dt: new Date().toISOString().slice(0,10).replace(/-/g, ''),
tot_item_cnt: 1,
tot_taxbl_amt: item.splyAmt,
tot_tax_amt: item.taxAmt,
tot_amt: item.totAmt,
items: [{
item_seq: 1,
item_cd: item.itemCd,
item_clss_cd: item.itemClsCd,
item_nm: item.itemNm,
bcd: item.bcd,
pkg_unit_cd: item.pkgUnitCd,
pkg: 1,
qty_unit_cd: item.qtyUnitCd,
qty: item.qty,
prc: item.prc,
sply_amt: item.splyAmt,
taxbl_amt: item.splyAmt,
tax_ty_cd: item.taxTyCd,
tax_amt: item.taxAmt,
tot_amt: item.totAmt
}]
}, {
headers: { Authorization: `Bearer ${apiKey}` }
});
}Code Examples
JavaScript
const axios = require('axios');
const apiKey = process.env.CTAX_API_KEY;
const baseURL = 'https://c-ushuru.com/api/v1';
const stockData = {
branch_id: '00',
sar_no: `SAR-${Date.now()}`,
sar_ty_cd: '11', // Stock In
sar_dt: new Date().toISOString().slice(0,10).replace(/-/g, ''),
tot_item_cnt: 1,
tot_taxbl_amt: 100000,
tot_tax_amt: 16000,
tot_amt: 116000,
remark: 'Stock received',
items: [
{
item_seq: 1,
item_cd: 'KE2BXU0000001',
item_clss_cd: '5020230201',
item_nm: 'Laptop Computer',
pkg_unit_cd: 'CT',
pkg: 1,
qty_unit_cd: 'U',
qty: 50,
prc: 2000,
sply_amt: 100000,
taxbl_amt: 100000,
tax_ty_cd: 'A',
tax_amt: 16000,
tot_amt: 116000
}
]
};
const response = await axios.post(`${baseURL}/stock`, stockData, {
headers: { Authorization: `Bearer ${apiKey}` }
});PHP
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://c-ushuru.com/api/v1/',
'headers' => [
'Authorization' => 'Bearer ' . env('CTAX_API_KEY'),
'Content-Type' => 'application/json',
],
]);
$data = [
'branch_id' => '00',
'sar_no' => 'SAR-' . time(),
'sar_ty_cd' => '11',
'sar_dt' => date('Ymd'),
'tot_item_cnt' => 1,
'tot_taxbl_amt' => 100000,
'tot_tax_amt' => 16000,
'tot_amt' => 116000,
'items' => [
[
'item_seq' => 1,
'item_cd' => 'KE2BXU0000001',
'item_clss_cd' => '5020230201',
'item_nm' => 'Laptop Computer',
'pkg_unit_cd' => 'CT',
'pkg' => 1,
'qty_unit_cd' => 'U',
'qty' => 50,
'prc' => 2000,
'sply_amt' => 100000,
'taxbl_amt' => 100000,
'tax_ty_cd' => 'A',
'tax_amt' => 16000,
'tot_amt' => 116000,
],
],
];
$response = $client->post('stock', ['json' => $data]);Python
import requests
from datetime import datetime
import os
api_key = os.environ['CTAX_API_KEY']
base_url = 'https://c-ushuru.com/api/v1'
headers = {'Authorization': f'Bearer {api_key}'}
stock_data = {
'branch_id': '00',
'sar_no': f'SAR-{int(datetime.now().timestamp())}',
'sar_ty_cd': '11',
'sar_dt': datetime.now().strftime('%Y%m%d'),
'tot_item_cnt': 1,
'tot_taxbl_amt': 100000,
'tot_tax_amt': 16000,
'tot_amt': 116000,
'items': [
{
'item_seq': 1,
'item_cd': 'KE2BXU0000001',
'item_clss_cd': '5020230201',
'item_nm': 'Laptop Computer',
'pkg_unit_cd': 'CT',
'pkg': 1,
'qty_unit_cd': 'U',
'qty': 50,
'prc': 2000,
'sply_amt': 100000,
'taxbl_amt': 100000,
'tax_ty_cd': 'A',
'tax_amt': 16000,
'tot_amt': 116000
}
]
}
response = requests.post(f'{base_url}/stock', json=stock_data, headers=headers)Best Practices
- Automatic Stock Updates - Stock is automatically updated when you create sales (decreases) or purchases (increases). You don’t need to manually adjust stock for these operations.
- Use Stock Endpoints for Visibility - Use
GET /stockto view current levels andGET /stock/movementsto see complete history including sales and purchases. - Explicit Movements for Adjustments - Use
POST /stockonly for explicit stock adjustments (corrections, damages, transfers, etc.). - Regular Reconciliation - Perform physical counts and create adjustments when needed.
- Unique SAR Numbers - Use unique identifiers for each explicit stock movement.
- Monitor Stock Levels - Regularly check stock levels and set safety quantities to get low stock alerts.
- Complete Audit Trail - All stock movements (sales, purchases, adjustments) are tracked for compliance and reporting.
Related Endpoints
- Purchases API - Create purchases that automatically increase stock and sync to KRA
- Sales API - Create sales that automatically decrease stock and sync to KRA
- Transactions API - View all transaction details including stock movements
- Items API - Manage inventory items and product catalog
How Stock Updates Work
Automatic Process:
- When you create a sale, stock is automatically decreased
- When you create a purchase, stock is automatically increased
- Stock I/O movements are sent to KRA
- Stock master is synced with KRA
- All movements are tracked in the database
Manual Adjustments:
- Use
POST /stockonly for corrections, damages, transfers, or other explicit adjustments - Stock API GET endpoints show current levels and complete history