Sales API
Create and manage sales transactions with automatic KRA/VSCU submission.
Overview
The Sales API allows you to submit sales transactions to KRA’s eTIMS system through your VSCU device. Sales are processed synchronously (default) or asynchronously for high-volume scenarios.
Create Sale
Submit a sales transaction to the KRA system. This is the primary endpoint for recording sales.
/api/v1/salesCreate Sale
Submit a sales transaction to KRA/VSCU. Supports synchronous and asynchronous processing.
asyncProcess asynchronously (default: false)
Field Descriptions
Main Fields
| Field | Type | Required | Description |
|---|---|---|---|
branch_id | string | Yes | Branch identifier (bhf_id) |
invoice_no | string | Yes | Unique invoice number (trader invoice number) |
original_invoice_no | string | No | Original invoice for refunds/credits |
sale_date | string | Yes | Date in YYYYMMDD format |
sale_time | string | Yes | Time in HHMMSS or HH:MM:SS format |
receipt_type | string | No | Receipt type (default: NORMAL) |
payment_type | string | Yes | Payment type |
sales_status | string | No | Sales status (default: COMPLETE) |
customer_tin | string | No | Customer TIN number |
customer_name | string | No | Customer name |
customer_id | string | No | Customer ID |
Receipt Types
| Value | Code | Description |
|---|---|---|
NORMAL | S | Standard sale |
COPY | R | Receipt copy |
PROFORMA | P | Proforma invoice |
DEBIT | T | Debit note |
CREDIT | C | Credit note |
Payment Types
| Value | Code | Description |
|---|---|---|
CASH | 01 | Cash payment |
CARD | 02 | Card payment |
MOBILE | 03 | Mobile money |
CREDIT | 04 | Credit |
BANK_TRANSFER | 05 | Bank transfer |
CHECK | 06 | Cheque |
OTHER | 07 | Other payment |
Sales Status
| Value | Code | Description |
|---|---|---|
COMPLETE | 02 | Completed sale |
PARTIAL | 01 | Partial sale |
CANCELLED | 03 | Cancelled sale |
Item Fields
| Field | Type | Required | Description |
|---|---|---|---|
item_code | string | Yes | Item code |
item_name | string | Yes | Item name |
quantity | number | Yes | Quantity sold |
unit_price | number | Yes | Unit price |
supply_amount | number | Yes | Supply amount (qty x price) |
discount_amount | number | No | Discount amount (default: 0) |
tax_type | string | Yes | Tax type (A, B, C, D, E) |
tax_rate | number | Yes | Tax rate percentage |
tax_amount | number | Yes | Tax amount |
total_amount | number | Yes | Total including tax |
Tax Types
| Code | Name | Rate | Description |
|---|---|---|---|
| A | Standard Rate | 16% | Standard VAT rate |
| B | Exempt | 0% | VAT exempt items |
| C | Special | 0% | Special category |
| D | Zero-rated | 0% | Zero-rated supplies |
| E | Special Exemption | 0% | Special exemption |
Response (Synchronous Mode)
Status: 200 OK
{
"status": "success",
"message": "Sale processed successfully with KRA",
"data": {
"transaction_id": "9d3f4b1a-7c8e-4d2f-b5a6-1e3c9f8d2b4a",
"invoice_no": "INV-2025-001",
"receipt_no": "20250115-00-00001",
"receipt_date": "2025-01-15",
"total_amount": 2320,
"tax_amount": 320,
"qr_code": "data:image/png;base64,...",
"synced_to_kra": true
},
"meta": {
"timestamp": "2025-01-15T14:30:30Z",
"request_id": "req_abc123"
}
}Response (Asynchronous Mode)
Status: 202 Accepted
{
"status": "processing",
"message": "Transaction is being processed",
"data": {
"transaction_id": "9d3f4b1a-7c8e-4d2f-b5a6-1e3c9f8d2b4a",
"invoice_no": "INV-2025-001",
"status": "pending"
},
"meta": {
"timestamp": "2025-01-15T14:30:00Z",
"request_id": "req_abc123",
"check_status_url": "/api/v1/transactions/9d3f4b1a-7c8e-4d2f-b5a6-1e3c9f8d2b4a"
}
}Get Sale Details
Retrieve details of a specific sales transaction.
/api/v1/sales/{id}Get Sale Details
Retrieve complete details of a sales transaction including items, tax breakdown, and KRA sync status.
id*Transaction UUID
Response
Status: 200 OK
{
"status": "success",
"data": {
"transaction_id": "9d3f4b1a-7c8e-4d2f-b5a6-1e3c9f8d2b4a",
"branch_id": "00",
"invoice_no": "INV-2025-001",
"receipt_no": "20250115-00-00001",
"sale_date": "20250115",
"sale_time": "143000",
"payment_type": "CASH",
"customer_name": "John Doe",
"total_amount": 2320,
"tax_amount": 320,
"status": "success",
"synced_to_kra": true,
"items": [
{
"item_code": "ITEM001",
"item_name": "Product A",
"quantity": 2,
"unit_price": 1000,
"supply_amount": 2000,
"tax_type": "A",
"tax_rate": 16,
"tax_amount": 320,
"total_amount": 2320
}
],
"qr_code": "data:image/png;base64,...",
"created_at": "2025-01-15T14:30:00Z",
"processed_at": "2025-01-15T14:30:05Z"
}
}Status: 404 Not Found
{
"status": "error",
"message": "Sale transaction not found"
}Search Sales
Search sales transactions with filters.
/api/v1/sales/searchSearch Sales
Search and filter sales transactions by date range, status, invoice number, and more.
Filter Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
branch_id | string | No | Filter by branch |
from_date | string | No | Start date (YYYY-MM-DD) |
to_date | string | No | End date (YYYY-MM-DD) |
invoice_no | string | No | Search by invoice number (partial match) |
status | string | No | Filter by status (pending, processing, success, failed) |
per_page | integer | No | Results per page (max 100, default 50) |
page | integer | No | Page number (default 1) |
Response
Status: 200 OK
{
"data": [
{
"transaction_id": "9d3f4b1a-7c8e-4d2f-b5a6-1e3c9f8d2b4a",
"branch_id": "00",
"invoice_no": "INV-2025-001",
"receipt_no": "20250115-00-00001",
"sale_date": "20250115",
"customer_name": "John Doe",
"total_amount": 2320,
"status": "success",
"synced_to_kra": true,
"created_at": "2025-01-15T14:30:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 50,
"total": 156,
"total_pages": 4
}
}Credit Notes (Refunds)
To create a credit note for a previous sale, use the CREDIT receipt type and reference the original invoice.
/api/v1/salesCreate Credit Note
Create a credit note (refund) referencing an original sale.
Tax Calculation
The system automatically calculates tax totals by tax type:
Tax Types: A (16%), B (0%), C (0%), D (0%), E (0%)
For each item:
taxable_amount = supply_amount - discount_amount
tax_amount = taxable_amount * tax_rate / 100
Totals are aggregated by tax type for VSCU submission.Example Calculation
const item = {
quantity: 2,
unit_price: 1000,
supply_amount: 2000, // 2 x 1000
discount_amount: 0,
tax_type: 'A',
tax_rate: 16,
tax_amount: 320, // 2000 x 0.16
total_amount: 2320 // 2000 + 320
};Code Examples
JavaScript
const axios = require('axios');
const apiKey = process.env.CTAX_API_KEY;
const baseURL = 'https://c-tax.1809ltd.co.ke/api/v1';
// Create sale (synchronous)
const sale = await axios.post(`${baseURL}/sales`, {
branch_id: '00',
invoice_no: `INV-${Date.now()}`,
sale_date: new Date().toISOString().slice(0,10).replace(/-/g,''),
sale_time: new Date().toTimeString().slice(0,8).replace(/:/g,''),
payment_type: 'CASH',
customer_name: 'John Doe',
items: [
{
item_code: 'ITEM001',
item_name: 'Product A',
quantity: 2,
unit_price: 1000,
supply_amount: 2000,
tax_type: 'A',
tax_rate: 16,
tax_amount: 320,
total_amount: 2320
}
]
}, {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
console.log('Receipt:', sale.data.data.receipt_no);JavaScript (Async with Webhook)
// Submit sale asynchronously
const response = await axios.post(`${baseURL}/sales?async=true`, saleData, {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const transactionId = response.data.data.transaction_id;
console.log('Transaction queued:', transactionId);
// Webhook will receive transaction.completed or transaction.failed eventPHP
$data = [
'branch_id' => '00',
'invoice_no' => 'INV-' . time(),
'sale_date' => date('Ymd'),
'sale_time' => date('His'),
'payment_type' => 'CASH',
'customer_name' => 'John Doe',
'items' => [
[
'item_code' => 'ITEM001',
'item_name' => 'Product A',
'quantity' => 2,
'unit_price' => 1000,
'supply_amount' => 2000,
'tax_type' => 'A',
'tax_rate' => 16,
'tax_amount' => 320,
'total_amount' => 2320,
],
],
];
$response = $client->post('/api/v1/sales', [
'json' => $data,
'headers' => ['Authorization' => 'Bearer ' . $apiKey],
]);
$result = json_decode($response->getBody(), true);
echo "Receipt: " . $result['data']['receipt_no'];Python
import requests
from datetime import datetime
import os
api_key = os.environ['CTAX_API_KEY']
base_url = 'https://c-tax.1809ltd.co.ke/api/v1'
now = datetime.now()
sale_data = {
'branch_id': '00',
'invoice_no': f'INV-{int(datetime.timestamp(now))}',
'sale_date': now.strftime('%Y%m%d'),
'sale_time': now.strftime('%H%M%S'),
'payment_type': 'CASH',
'customer_name': 'John Doe',
'items': [{
'item_code': 'ITEM001',
'item_name': 'Product A',
'quantity': 2,
'unit_price': 1000,
'supply_amount': 2000,
'tax_type': 'A',
'tax_rate': 16,
'tax_amount': 320,
'total_amount': 2320
}]
}
response = requests.post(
f'{base_url}/sales',
json=sale_data,
headers={'Authorization': f'Bearer {api_key}'}
)
result = response.json()
print(f"Receipt: {result['data']['receipt_no']}")Error Handling
Common Errors
400 Bad Request - Invalid request data
{
"status": "error",
"message": "Invalid request data. Please check your input and try again.",
"meta": {
"timestamp": "2025-01-15T14:30:00Z",
"request_id": "req_abc123"
}
}422 Unprocessable Entity - Validation failed
{
"status": "error",
"message": "Sale could not be processed. Please try again.",
"data": {
"transaction_id": "9d3f4b1a-7c8e-4d2f-b5a6-1e3c9f8d2b4a",
"synced_to_kra": false,
"can_retry": true
},
"meta": {
"timestamp": "2025-01-15T14:30:30Z",
"request_id": "req_abc123"
}
}500 Internal Server Error
{
"status": "error",
"message": "An error occurred while processing the sale. Please try again or contact support.",
"meta": {
"timestamp": "2025-01-15T14:30:00Z",
"request_id": "req_abc123"
}
}Best Practices
- Use Async for High Volume - Set
async=truefor bulk transactions - Unique Invoice Numbers - Ensure invoice numbers are unique per branch
- Validate Calculations - Verify tax calculations before submission
- Handle Retries - Implement retry logic for failed transactions
- Use Webhooks - Subscribe to
transaction.completedandtransaction.failedevents - Store Transaction IDs - Keep transaction IDs for reference and support
- Test in Sandbox - Use sandbox environment for development
Related Endpoints
- Transactions API - Monitor transaction status
- Items API - Get item details for sales
- Webhooks - Real-time status notifications
- Codes API - Get tax types and payment types