Submit sales to KRA, manage invoices, and generate compliance reports. The Sales API covers the full lifecycle of a tax invoice from submission through to cancellation.
| Scope | Description |
|---|---|
etims:read |
View sales, get sale details, list sales, reports |
etims:write |
Submit sales, cancel sales |
| Method | Endpoint | Description | Scope |
|---|---|---|---|
POST |
/api/etims/sales/submit |
Submit a sale to KRA | etims:write |
POST |
/api/etims/sales/submit-with-items |
Submit sale with unregistered inline items | etims:write |
GET |
/api/etims/sales/{receipt_number} |
Get sale details | etims:read |
POST |
/api/etims/sales/{receipt_number}/cancel |
Cancel a submitted sale | etims:write |
GET |
/api/etims/sales |
List all sales | etims:read |
GET |
/api/etims/reports/sales |
Sales summary report | etims:read |
GET |
/api/etims/reports/sales-summary |
Aggregated sales summary | etims:read |
Submit a sale transaction to KRA eTIMS. Items must be pre-registered.
Endpoint: POST /api/etims/sales/submit
Required Scope: etims:write
Request Body:
{
"receipt_number": "INV-2026-001",
"receipt_date": "2026-03-29",
"customer_pin": "A009876543B",
"customer_name": "Jane Wanjiku",
"sales_type": "N",
"receipt_type": "S",
"payment_type": "01",
"items": [
{
"item_seq": 1,
"item_code": "ITEM001",
"item_name": "Office Chair",
"item_class_code": "94017100",
"quantity": 2,
"unit_price": 15000.00,
"discount": 0,
"tax_type": "B",
"tax_rate": 16
},
{
"item_seq": 2,
"item_code": "ITEM002",
"item_name": "Office Desk",
"item_class_code": "94033000",
"quantity": 1,
"unit_price": 25000.00,
"discount": 1000.00,
"tax_type": "B",
"tax_rate": 16
}
]
}
| Field | Type | Required | Description |
|---|---|---|---|
receipt_number |
string | Yes | Your unique invoice/receipt number |
receipt_date |
string | No | Sale date (YYYY-MM-DD), defaults to today |
customer_pin |
string | No | Customer's KRA PIN (required for B2B) |
customer_name |
string | No | Customer name |
sales_type |
string | Yes | Sale type code (see table below) |
receipt_type |
string | No | Receipt type code (default: S) |
payment_type |
string | Yes | Payment method code (see table below) |
items |
array | Yes | Array of item objects |
| Field | Type | Required | Description |
|---|---|---|---|
item_seq |
integer | Yes | Line item sequence number (1, 2, 3...) |
item_code |
string | Yes | Registered item code |
item_name |
string | Yes | Item description |
item_class_code |
string | No | HS code / item classification code |
quantity |
number | Yes | Quantity sold |
unit_price |
number | Yes | Unit price (inclusive of tax) |
discount |
number | No | Discount amount (default: 0) |
tax_type |
string | Yes | Tax type code (A-E) |
tax_rate |
number | No | Tax rate percentage |
| Code | Description |
|---|---|
N |
Normal sale |
C |
Copy of sale |
P |
Proforma invoice |
T |
Training mode sale |
| Code | Description |
|---|---|
01 |
Cash |
02 |
Credit |
03 |
Cheque |
04 |
Mobile Money (M-Pesa, etc.) |
05 |
Card (Visa, Mastercard) |
06 |
Other |
Request:
curl -X POST \
https://yourtenant.salami.dgl.co.ke/api/etims/sales/submit \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"receipt_number": "INV-2026-001",
"customer_pin": "A009876543B",
"sales_type": "N",
"payment_type": "01",
"items": [
{
"item_seq": 1,
"item_code": "ITEM001",
"item_name": "Office Chair",
"quantity": 2,
"unit_price": 15000.00,
"tax_type": "B"
}
]
}'
Response:
{
"success": true,
"data": {
"sale_id": 789,
"receipt_number": "INV-2026-001",
"cu_invoice_number": "CU2026001-00001",
"internal_data": "202603290001",
"receipt_signature": "ABCD1234EFGH5678",
"total_amount": 30000.00,
"total_taxable_amount": 25862.07,
"total_tax_amount": 4137.93,
"tax_breakdown": {
"A": {"taxable": 0, "tax": 0, "rate": 0},
"B": {"taxable": 25862.07, "tax": 4137.93, "rate": 16},
"C": {"taxable": 0, "tax": 0, "rate": 8},
"D": {"taxable": 0, "tax": 0, "rate": 0},
"E": {"taxable": 0, "tax": 0, "rate": 0}
},
"status": "submitted",
"submitted_at": "2026-03-29T16:05:00Z",
"qr_code_url": "https://yourtenant.salami.dgl.co.ke/etims/invoice/qr/789"
},
"message": "Sale submitted to eTims successfully"
}
Submit a sale where items are defined inline (items do not need to be pre-registered). Salami will auto-register any new items with KRA before submitting the sale.
Endpoint: POST /api/etims/sales/submit-with-items
Required Scope: etims:write
Request Body:
{
"receipt_number": "INV-2026-002",
"customer_pin": "A009876543B",
"customer_name": "Jane Wanjiku",
"sales_type": "N",
"payment_type": "04",
"items": [
{
"item_seq": 1,
"item_code": "NEW-ITEM-001",
"item_name": "Wireless Keyboard",
"item_class_code": "84716060",
"item_type": "2",
"origin_country": "CN",
"quantity": 5,
"unit_price": 3500.00,
"package_unit": "NT",
"quantity_unit": "U",
"tax_type": "B",
"tax_rate": 16
}
]
}
Response:
{
"success": true,
"data": {
"sale_id": 790,
"receipt_number": "INV-2026-002",
"cu_invoice_number": "CU2026001-00002",
"items_registered": 1,
"total_amount": 17500.00,
"total_tax_amount": 2413.79,
"status": "submitted",
"submitted_at": "2026-03-29T16:10:00Z"
},
"message": "Sale submitted to eTims successfully (1 new item registered)"
}
Retrieve details of a submitted sale by receipt number.
Endpoint: GET /api/etims/sales/{receipt_number}
Required Scope: etims:read
Request:
curl -X GET \
https://yourtenant.salami.dgl.co.ke/api/etims/sales/INV-2026-001 \
-H 'Authorization: Bearer YOUR_API_TOKEN'
Response:
{
"success": true,
"data": {
"id": 789,
"receipt_number": "INV-2026-001",
"cu_invoice_number": "CU2026001-00001",
"customer_pin": "A009876543B",
"customer_name": "Jane Wanjiku",
"total_amount": 30000.00,
"total_taxable_amount": 25862.07,
"total_tax_amount": 4137.93,
"sales_type": "N",
"receipt_type": "S",
"payment_type": "01",
"status": "approved",
"items": [
{
"item_seq": 1,
"item_code": "ITEM001",
"item_name": "Office Chair",
"quantity": 2,
"unit_price": 15000.00,
"discount": 0,
"total": 30000.00,
"tax_type": "B",
"tax_amount": 4137.93
}
],
"submitted_at": "2026-03-29T16:05:00Z",
"approved_at": "2026-03-29T16:05:15Z"
}
}
Cancel a previously submitted sale. Cancellation submits a reversal receipt to KRA.
Endpoint: POST /api/etims/sales/{receipt_number}/cancel
Required Scope: etims:write
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
reason |
string | Yes | Reason for cancellation |
refund_type |
string | No | Refund method code |
Refund Types:
| Code | Description |
|---|---|
01 |
Cash refund |
02 |
Credit note |
03 |
No refund |
Request:
curl -X POST \
https://yourtenant.salami.dgl.co.ke/api/etims/sales/INV-2026-001/cancel \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"reason": "Customer returned goods - defective product",
"refund_type": "01"
}'
Response:
{
"success": true,
"data": {
"original_receipt": "INV-2026-001",
"reversal_receipt": "INV-2026-001-R",
"status": "cancelled",
"cancelled_at": "2026-03-29T16:10:00Z",
"refund_type": "01"
},
"message": "Sale cancelled successfully"
}
Retrieve a list of all submitted sales.
Endpoint: GET /api/etims/sales
Required Scope: etims:read
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
start_date |
string | No | Filter from date (YYYY-MM-DD) |
end_date |
string | No | Filter to date (YYYY-MM-DD) |
status |
string | No | Filter by status (submitted, approved, cancelled) |
page |
integer | No | Page number (default: 1) |
per_page |
integer | No | Results per page (default: 50) |
Request:
curl -X GET \
'https://yourtenant.salami.dgl.co.ke/api/etims/sales?start_date=2026-03-01&end_date=2026-03-31' \
-H 'Authorization: Bearer YOUR_API_TOKEN'
Response:
{
"success": true,
"data": [
{
"id": 789,
"receipt_number": "INV-2026-001",
"cu_invoice_number": "CU2026001-00001",
"customer_name": "Jane Wanjiku",
"total_amount": 30000.00,
"total_tax_amount": 4137.93,
"status": "approved",
"submitted_at": "2026-03-29T16:05:00Z"
},
{
"id": 790,
"receipt_number": "INV-2026-002",
"cu_invoice_number": "CU2026001-00002",
"customer_name": "Jane Wanjiku",
"total_amount": 17500.00,
"total_tax_amount": 2413.79,
"status": "approved",
"submitted_at": "2026-03-29T16:10:00Z"
}
],
"pagination": {
"total": 45,
"per_page": 50,
"current_page": 1,
"last_page": 1
}
}
Get an aggregated sales summary for a date range.
Endpoint: GET /api/etims/reports/sales
Required Scope: etims:read
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
start_date |
string | Yes | Start date (YYYY-MM-DD) |
end_date |
string | Yes | End date (YYYY-MM-DD) |
Request:
curl -X GET \
'https://yourtenant.salami.dgl.co.ke/api/etims/reports/sales?start_date=2026-03-01&end_date=2026-03-31' \
-H 'Authorization: Bearer YOUR_API_TOKEN'
Response:
{
"success": true,
"data": {
"period": {
"start_date": "2026-03-01",
"end_date": "2026-03-31"
},
"summary": {
"total_sales": 45,
"total_amount": 1250000.00,
"total_taxable_amount": 1077586.21,
"total_tax_amount": 172413.79,
"cancelled_sales": 2
},
"by_tax_type": {
"A": {"count": 5, "taxable": 50000.00, "tax": 0},
"B": {"count": 38, "taxable": 1000000.00, "tax": 160000.00},
"C": {"count": 2, "taxable": 27586.21, "tax": 12413.79},
"D": {"count": 0, "taxable": 0, "tax": 0}
},
"by_payment_type": [
{"type": "Cash", "code": "01", "count": 20, "amount": 500000.00},
{"type": "Mobile Money", "code": "04", "count": 25, "amount": 750000.00}
]
}
}
This is the full body structure mapped to KRA's eTIMS fields:
{
"invcNo": 0,
"trdInvcNo": "INV-2026-001",
"orgInvcNo": 0,
"custTin": "A009876543B",
"custNm": "Jane Wanjiku",
"rcptTyCd": "S",
"pmtTyCd": "01",
"salesTyCd": "N",
"salesDt": "20260329",
"stockRlsDt": "20260329",
"totItemCnt": 2,
"taxblAmtA": 0,
"taxblAmtB": 25862.07,
"taxblAmtC": 0,
"taxblAmtD": 0,
"taxblAmtE": 0,
"taxRtA": 0,
"taxRtB": 16,
"taxRtC": 8,
"taxRtD": 0,
"taxRtE": 0,
"taxAmtA": 0,
"taxAmtB": 4137.93,
"taxAmtC": 0,
"taxAmtD": 0,
"taxAmtE": 0,
"totTaxblAmt": 25862.07,
"totTaxAmt": 4137.93,
"totAmt": 30000.00,
"remark": "",
"itemList": [
{
"itemSeq": 1,
"itemCd": "ITEM001",
"itemClsCd": "94017100",
"itemNm": "Office Chair",
"pkgUnitCd": "NT",
"qtyUnitCd": "U",
"qty": 2,
"prc": 15000.00,
"splyAmt": 30000.00,
"dcRt": 0,
"dcAmt": 0,
"taxblAmt": 25862.07,
"taxTyCd": "B",
"taxAmt": 4137.93,
"totAmt": 30000.00
}
]
}
{
"resultCd": "000",
"resultMsg": "It is succeeded",
"resultDt": "20260329160500",
"data": {
"rcptNo": 1,
"intrlData": "202603290001",
"rcptSign": "ABCD1234EFGH5678",
"totRcptNo": 45,
"vsdcRcptPbctDt": "20260329160500",
"sdcId": "SDC001",
"mrcNo": "MRC001"
}
}
| Code | Description |
|---|---|
200 |
Success |
401 |
Invalid Salami token or device not initialized |
403 |
Token lacks required scope |
404 |
Sale not found |
422 |
Validation error (missing items, invalid fields) |
502 |
KRA eTIMS server error |
Back to: eTIMS Device | eTIMS Credit Notes