SKYBIZ API — Sales Order Module
Sales Order
The Sales Order module allows you to retrieve and create sales order records in your SKYBIZ account. Supports both read and create operations.
Endpoint: /apiv2/modules/sales_order.php
Required Permissions: Sales Order — Read, Sales Order — Create
Allowed DocType: SO (Sales Order only)
Read Sales Orders
Retrieves sales orders created within the given date range. Returns all fields — no field filtering or custom filters are supported for this module.
Base Request Structure
{
"api_key": "your-api-key",
"api_secret": "your-api-secret",
"action": "read",
"date_from": "YYYY-MM-DD",
"date_to": "YYYY-MM-DD"
}
Request Parameters
| Parameter | Description | Required |
|---|---|---|
api_key |
Your API key | Yes |
api_secret |
Your API secret | Yes |
action |
Must be "read" |
Yes |
date_from |
Start date (YYYY-MM-DD) | Yes |
date_to |
End date (YYYY-MM-DD). Max 31 days range. | Yes |
Date Rules
- Format must be
YYYY-MM-DD— e.g."2026-04-01" - Maximum range is 31 days
date_fromcannot be afterdate_to
Available Fields (Read Only)
The Sales Order module returns all fields. Field filtering is not supported for this module.
| Field | Type | Description |
|---|---|---|
Doc1No |
string | Document number (identifier) |
Doc2No / Doc3No |
string | Reference document numbers |
D_ate |
string | Document date |
CusCode |
string | Customer code |
CusName |
string | Customer name |
CurCode |
string | Currency code (e.g., RM, SGD, USD) |
CurRate1 |
float | Exchange rate |
TermCode |
integer | Payment term in days |
HCNetAmt |
float | Net amount before tax |
HCDtTax |
float | Total tax amount |
DocType |
string | Document type — always "SO" |
Status |
string | Order status — "Waiting", "Completed", etc. |
Address / City / State / Zip |
string | Delivery address components |
ContactTel / Email |
string | Contact telephone and email |
Attention |
string | Attention note / special remarks |
ItemCode |
string | Item code |
Description / Description2 |
string | Item description lines |
Qty |
float | Quantity ordered |
FactorQty |
float | UOM conversion factor (usually 1) |
UOM |
string | Unit of measure |
UOMSingular |
string | Singular form of UOM |
HCUnitCost |
float | Unit cost |
HCLineAmt |
float | Line total amount |
HCTax |
float | Tax amount for the line |
TaxRate1 |
float | Tax rate in percent |
DetailTaxCode |
string | Tax code |
BlankLine |
string | Line type — "0" Stock Item, "4" Other Charge, "6" GL Account |
DeliveryDate |
string | Expected delivery date |
Example 1 — Get All Sales Orders (All Fields)
This request returns all sales order fields for orders created between April 1, 2026 and April 30, 2026.
Request
{
"api_key": "your-api-key",
"api_secret": "your-api-secret",
"action": "read",
"date_from": "2026-04-01",
"date_to": "2026-04-30"
}
Sample Code for making an API READ request using php
<?php
header('Content-Type: application/json');
// ============================================================
// STEP 1: CONFIGURATION
// ============================================================
$API_KEY = "your-api-key";
$API_SECRET = "your-api-secret";
$ACTION = "read";
// Date range (required for all endpoints, max 31 days)
$DATE_FROM = "2026-04-01";
$DATE_TO = "2026-04-30";
// ============================================================
// STEP 2: ENDPOINT
// ============================================================
$BASE_URL = "https://domain-name/01/clientportal/apiv2/modules"; //(replace it with your skybiz domain name url)
$ENDPOINT = "sales_order.php";
// ============================================================
// STEP 3: REQUEST PARAMETERS
// ============================================================
$requestParams = [
"date_from" => $DATE_FROM,
"date_to" => $DATE_TO
];
// ============================================================
// STEP 4: BUILD PAYLOAD
// ============================================================
$payload = array_merge(
[
"api_key" => $API_KEY,
"api_secret" => $API_SECRET,
"action" => $ACTION
],
$requestParams
);
// ============================================================
// STEP 5: SEND REQUEST
// ============================================================
$url = rtrim($BASE_URL, '/') . '/' . ltrim($ENDPOINT, '/');
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($payload),
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
// ============================================================
// STEP 6: HANDLE CURL ERROR
// ============================================================
if ($response === false) {
echo json_encode([
"status" => "error",
"timestamp" => date("c"),
"request_id" => uniqid("req_"),
"message" => curl_error($ch)
], JSON_PRETTY_PRINT);
curl_close($ch);
exit;
}
$httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// ============================================================
// STEP 7: DECODE RESPONSE
// ============================================================
$result = json_decode($response, true);
if (!$result) {
echo json_encode([
"status" => "error",
"timestamp" => date("c"),
"request_id" => uniqid("req_"),
"message" => "Invalid JSON from API",
"raw_response" => $response
], JSON_PRETTY_PRINT);
exit;
}
// ============================================================
// STEP 8: RETURN CLEAN JSON FORMAT
// ============================================================
echo json_encode([
"status" => $result['status'] ?? "error",
"timestamp" => date("c"),
"request_id" => $result['request_id'] ?? uniqid("req_"),
"data" => $result['data'] ?? null,
"message" => $result['message'] ?? null
], JSON_PRETTY_PRINT);
Response (Success)
{
"status": "response",
"timestamp": "2026-04-30T04:07:04+00:00",
"request_id": "req_69f2d56891e57",
"data": {
"requested_by": "your-api-key",
"mode": "2",
"date_range": {
"from": "2026-04-01",
"to": "2026-04-30",
"days": 30
},
"total_returned": 2,
"data": [
{
"Doc1No": "SO-001",
"CusCode": "CUST001",
"CusName": "Acme Sdn Bhd",
"CurCode": "RM",
"HCNetAmt": 1500.00,
"Status": "Waiting",
"D_ate": "2026-04-15",
"DateTimeModified": "2026-04-15 10:30:00"
},
{
"Doc1No": "SO-002",
"CusCode": "CUST002",
"CusName": "Tech Solutions",
"CurCode": "RM",
"HCNetAmt": 2500.00,
"Status": "Completed",
"D_ate": "2026-04-20",
"DateTimeModified": "2026-04-20 14:45:00"
}
]
}
}
Postman Steps — READ Request
- Set method to POST
2. Enter URL: https://your-domain/01/clientportal/apiv2/modules/sales_order.php
3. Set header: Content-Type: application/json
4. Under Body, select raw and format JSON
5. Paste your request payload and click Send
Create Sales Order
Creates one or more sales order records. All documents are validated before any are saved. If any document fails, the entire batch is rejected.
Compulsory Fields — Header
| Field | Type | Description |
|---|---|---|
Doc1No |
string | Unique document number. Must not already exist. |
CusCode |
string | Customer code. Must exist in SKYBIZ. |
DocType |
string | Must be "SO" |
HCNetAmt |
float | Net amount before tax. Must equal sum of all item HCLineAmt. |
HCDtTax |
float | Total tax amount. Must equal sum of all item HCTax. |
Compulsory Fields — Items
| Field | Type | Description |
|---|---|---|
ItemCode |
string | Item code. Must exist in SKYBIZ. |
Description |
string | Item description |
Qty |
float | Quantity. Must be greater than 0. |
FactorQty |
float | UOM conversion factor. Usually same as Qty. Must be greater than 0. |
UOM |
string | Unit of measure. Must exist in SKYBIZ UOM table. |
HCUnitCost |
float | Unit price. Must be greater than 0 for stock items. |
HCLineAmt |
float | Line total. Must equal Qty × HCUnitCost. |
BlankLine |
string | Line type — "0" Stock Item, "4" Other Charge, "6" GL Account |
Optional Fields — Header
| Field | Type | Description |
|---|---|---|
Doc2No / Doc3No |
string | Reference document numbers |
D_ate |
string | Document date in YYYY-MM-DD format. Defaults to today. |
CusName |
string | Customer name (for display on the order) |
CurCode |
string | Currency code. Default: MYR |
CurRate1 |
float | Exchange rate. Default: 1 |
Address |
string | Delivery address (Max length is 255 characters) |
City / State / Zip |
string | Delivery city, state, postcode |
ContactTel / Email |
string | Delivery contact telephone and email |
Attention |
string | Attention note or special remarks |
Optional Fields — Items
| Field | Type | Description |
|---|---|---|
Description2 |
string | Second description line (Max length is 255 characters) |
UOMSingular |
string | Singular form of UOM (auto-populated if empty) |
HCDiscount / DisRate1 |
float | Discount amount and discount rate (%) |
HCTax |
float | Tax amount for this line. Must equal HCLineAmt × (TaxRate1 / 100). |
TaxRate1 |
float | Tax rate in percent — e.g. 6 |
DetailTaxCode |
string | Tax code. If provided, must exist in SKYBIZ. |
SalesPersonCode |
string | Sales Person Code. If provided, must exist in SKYBIZ. |
BranchCode / DepartmentCode / ProjectCode |
string | Branch, department, and project codes. If provided, must exist in SKYBIZ. |
LocationCode |
string | Stock location code. If provided, must exist in SKYBIZ. |
DeliveryDate |
string | Expected delivery date in YYYY-MM-DD format |
DUD1 to DUD6 |
string | User-defined detail fields 1 through 6 (Max length is 40 characters) |
LineNo |
integer | Line sequence number. Auto-assigned if omitted. |
BlankLine Values
| Value | Type |
|---|---|
"0" |
Stock Item |
"4" |
Other Charge |
"6" |
GL Account |
Base Create Request Structure
{
"api_key": "your-api-key",
"api_secret": "your-api-secret",
"action": "create",
"order_data": {
"documents": [
{
"Doc1No": "SO-001",
"CusCode": "CUST001",
"DocType": "SO",
"D_ate": "2026-05-20",
"HCNetAmt": 550.00,
"HCDtTax": 44.00,
"CurCode": "RM",
"CurRate1": 1,
"CusName": "Acme Sdn Bhd",
"Address": "123 Jalan SS2",
"City": "Petaling Jaya",
"State": "Selangor",
"Zip": "47300",
"ContactTel": "0123456789",
"Email": "customer@test.com",
"Attention": "Urgent order",
"items": [
{
"ItemCode": "ITEM001",
"Description": "Product A",
"Qty": 10,
"FactorQty": 1,
"UOM": "Piece",
"HCUnitCost": 50.00,
"HCLineAmt": 500.00,
"BlankLine": "0",
"HCTax": 40.00,
"TaxRate1": 8,
"DeliveryDate": "2026-05-25",
"LineNo": 1
}
]
}
]
}
}
Sample Code for making an API CREATE request using php
<?php
header('Content-Type: application/json');
// ============================================================
// STEP 1: CONFIGURATION
// ============================================================
$API_KEY = "your-api-key";
$API_SECRET = "your-api-secret";
$ACTION = "create";
// ============================================================
// STEP 2: ENDPOINT
// ============================================================
$BASE_URL = "https://domain-name/01/clientportal/apiv2/modules"; //(replace it with your skybiz domain name url)
$ENDPOINT = "sales_order.php";
// ============================================================
// STEP 3: DATA KEY
// ============================================================
$DATA_KEY = "order_data";
// ============================================================
// STEP 4: BUILD YOUR DOCUMENTS ARRAY
// ============================================================
$DOCUMENTS = [];
// --- Sales Order example ---
$DOCUMENTS[] = [
"Doc1No" => "SO-001",
"CusCode" => "CUST001",
"DocType" => "SO",
"D_ate" => "2026-05-20",
"HCNetAmt" => 550.00,
"HCDtTax" => 44.00,
"CurCode" => "RM",
"CurRate1" => 1,
"CusName" => "Acme Sdn Bhd",
"Address" => "123 Jalan SS2",
"City" => "Petaling Jaya",
"State" => "Selangor",
"Zip" => "47300",
"ContactTel" => "0123456789",
"Email" => "customer@test.com",
"Attention" => "Urgent order",
"items" => [
[
"ItemCode" => "ITEM001",
"Description" => "Product A",
"Qty" => 10,
"FactorQty" => 1,
"UOM" => "Piece",
"HCUnitCost" => 50.00,
"HCLineAmt" => 500.00,
"BlankLine" => "0",
"HCTax" => 40.00,
"TaxRate1" => 8,
"DeliveryDate" => "2026-05-25",
"LineNo" => 1
]
]
];
// ============================================================
// STEP 5: CLIENT-SIDE COUNT CHECK (Please do not modify this)
// ============================================================
$totalDocuments = 0;
foreach ($DOCUMENTS as $document) {
$totalDocuments++;
if (empty($document['Doc1No'])) {
echo json_encode([
"status" => "REJECTED_BY_CLIENT",
"timestamp" => date("c"),
"request_id" => uniqid("req_"),
"message" => "CLIENT-SIDE REJECTION: Document at position {$totalDocuments} has empty Doc1No",
"action_required" => "Fix the document before sending to server"
], JSON_PRETTY_PRINT);
exit;
}
}
if ($totalDocuments > 500) {
echo json_encode([
"status" => "REJECTED_BY_CLIENT",
"timestamp" => date("c"),
"request_id" => uniqid("req_"),
"message" => "CLIENT-SIDE REJECTION: You have {$totalDocuments} documents. Maximum is 500.",
"your_document_count" => $totalDocuments,
"max_allowed" => 500,
"action_required" => "Reduce your documents to 500 or less BEFORE sending to server"
], JSON_PRETTY_PRINT);
exit;
}
echo "=== CLIENT-SIDE VALIDATION ===\n";
echo "Looped through all {$totalDocuments} documents one by one\n";
echo "All documents passed client validation\n";
echo "Document count: {$totalDocuments} (max 500)\n";
echo "Sending to server...\n\n";
// ============================================================
// STEP 6: SEND REQUEST
// ============================================================
$url = rtrim($BASE_URL, '/') . '/' . ltrim($ENDPOINT, '/');
$payload = [
"api_key" => $API_KEY,
"api_secret" => $API_SECRET,
"action" => $ACTION,
$DATA_KEY => ["documents" => $DOCUMENTS]
];
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_TIMEOUT => 120,
]);
$response = curl_exec($ch);
// ============================================================
// STEP 7: HANDLE CURL ERROR
// ============================================================
if ($response === false) {
echo json_encode([
"status" => "error",
"timestamp" => date("c"),
"request_id" => uniqid("req_"),
"message" => curl_error($ch)
], JSON_PRETTY_PRINT);
curl_close($ch);
exit;
}
$httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// ============================================================
// STEP 8: DECODE RESPONSE
// ============================================================
$result = json_decode($response, true);
if (!$result) {
echo json_encode([
"status" => "error",
"timestamp" => date("c"),
"request_id" => uniqid("req_"),
"message" => "Invalid JSON from API",
"raw_response" => $response
], JSON_PRETTY_PRINT);
exit;
}
// ============================================================
// STEP 9: RETURN CLEAN JSON FORMAT
// ============================================================
echo "=== SERVER RESPONSE ===\n";
echo json_encode([
"status" => $result['status'] ?? "error",
"timestamp" => date("c"),
"request_id" => $result['request_id'] ?? uniqid("req_"),
"data" => $result['data'] ?? null,
"message" => $result['message'] ?? null
], JSON_PRETTY_PRINT);
Response (Success)
{
"status": "response",
"timestamp": "2026-05-20T10:30:00+08:00",
"request_id": "req_69fc0070d83cf",
"data": {
"requested_by": "your-api-key",
"mode": "2",
"summary": {
"total_documents": 1,
"inserted": 1,
"failed": 0
},
"successful_documents": ["SO-001"],
"failed_documents": [],
"fail_details": {
"compulsory_fields_missing": [],
"duplicate_documents": [],
"invalid_customers": [],
"invalid_items": [],
"invalid_tax_codes": [],
"invalid_sales_persons": [],
"invalid_locations": [],
"invalid_departments": [],
"invalid_projects": [],
"invalid_branches": [],
"invalid_currencies": [],
"invalid_uoms": [],
"amount_mismatch": [],
"validation_errors": []
}
}
}
Response (Error — Duplicate Document)
{
"status": "response",
"timestamp": "2026-05-20T10:30:00+08:00",
"request_id": "req_69fc03e446a20",
"data": {
"requested_by": "your-api-key",
"mode": "2",
"summary": {
"total_documents": 1,
"inserted": 0,
"failed": 1
},
"successful_documents": [],
"failed_documents": ["SO-001"],
"fail_details": {
"duplicate_documents": ["SO-001"],
"invalid_currencies": [],
"invalid_uoms": [],
"amount_mismatch": [],
"validation_errors": []
}
}
}
Error Responses
Missing Date Range (READ)
{
"status": "error",
"timestamp": "2026-04-07T10:46:15+08:00",
"request_id": "req_6612f3b9c21a7",
"message": "date_from and date_to are required"
}
Invalid DocType (CREATE)
{
"status": "error",
"timestamp": "2026-04-07T10:46:15+08:00",
"request_id": "req_6612f3b9c21a7",
"message": "Invalid DocType 'XXX'. Allowed: SO"
}
Missing Compulsory Fields (CREATE)
{
"status": "response",
"timestamp": "2026-05-20T10:30:00+08:00",
"request_id": "req_123456",
"data": {
"summary": {
"total_documents": 1,
"inserted": 0,
"failed": 1
},
"failed_documents": ["SO-001"],
"fail_details": {
"compulsory_fields_missing": [
"Document 1 (Doc1No: SO-001): Missing header fields - CusCode, HCNetAmt, HCDtTax, DocType"
]
}
}
}
Invalid UOM Code (CREATE)
{
"status": "response",
"timestamp": "2026-05-20T10:30:00+08:00",
"request_id": "req_123456",
"data": {
"summary": {
"total_documents": 1,
"inserted": 0,
"failed": 1
},
"failed_documents": ["SO-001"],
"fail_details": {
"invalid_uoms": [
"Document 1 (Doc1No: SO-001), Item 1: UOM code 'INVALID' does not exist"
]
}
}
}
Invalid Currency Code (CREATE)
{
"status": "response",
"timestamp": "2026-05-20T10:30:00+08:00",
"request_id": "req_123456",
"data": {
"summary": {
"total_documents": 1,
"inserted": 0,
"failed": 1
},
"failed_documents": ["SO-001"],
"fail_details": {
"invalid_currencies": [
"Document 1 (Doc1No: SO-001): Currency code 'INVALID' does not exist"
]
}
}
}
No Read Permission
{
"status": "error",
"timestamp": "2026-04-07T10:46:15+08:00",
"request_id": "req_6612f3b9c21a7",
"message": "Sales Order read permission denied"
}
No Create Permission
{
"status": "error",
"timestamp": "2026-05-20T10:30:00+08:00",
"request_id": "req_123456",
"message": "Sales Order create permission denied"
}
Common Errors — Sales Order Module
| Error Message | Cause | Fix |
|---|---|---|
"date_from and date_to are required" |
Missing date range (READ only) | Add both fields to your request |
"Invalid date format. Use YYYY-MM-DD format." |
Wrong date format | Use YYYY-MM-DD — e.g. "2026-04-01" |
"Date range cannot exceed 31 days." |
Date range too wide | Narrow range to 31 days or fewer |
"Invalid DocType 'XXX'. Allowed: SO" |
Wrong DocType in CREATE request | Use "SO" as the DocType |
"Missing fields - ItemCode, Description, Qty, FactorQty, UOM, HCUnitCost, HCLineAmt, BlankLine" |
Compulsory item fields not provided (CREATE) | Include all required fields for each item |
"UOM code 'X' does not exist" |
Invalid Unit of Measure (CREATE) | Check the UOM exists in SKYBIZ (singular or plural form) |
"Currency code 'X' does not exist" |
Invalid currency code (CREATE) | Use a valid currency code (e.g., RM, SGD, USD) |
"Customer Code 'X' does not exist" |
Invalid customer code | Check the customer code exists in SKYBIZ |
"HCLineAmt does not match Qty × HCUnitCost" |
Amount calculation mismatch | Ensure HCLineAmt = Qty × HCUnitCost |
"Header HCNetAmt does not match sum of HCLineAmt" |
Header total doesn’t match item totals | Set HCNetAmt to the sum of all item HCLineAmt |
"Document already exists" |
Duplicate Doc1No |
Use a unique Doc1No |
"Sales Order read permission denied" |
No read permission for Sales Order module | Enable read permission in portal by contacting your SkyBiz Admin |
For complete field references and advanced usage, see the SKYBIZ API Advanced Documentation.




