Fiscal Invoices

Fiscalisation is the heart of EFRIS: every sale is reported to URA in real time, and URA responds with a Fiscal Document Number (FDN), a verification code, and a QR code that must appear on the printed invoice. One endpoint handles all invoice types:

POST/generate-fiscal-invoice

The body wraps the full EFRIS invoice structure in an invoice object:

{
    "invoice": {
        "sellerDetails": {},
        "basicInformation": {},
        "buyerDetails": {},
        "goodsDetails": [],
        "taxDetails": [],
        "summary": {},
        "payWay": []
    }
}

A. Standard invoice

A complete, internally consistent example: 2 bottles at a gross (tax-inclusive) price of 100,000 UGX each. VAT at 18% is extracted from the gross: 200,000 × 18 ÷ 118 = 30,508.47.

{
    "invoice": {
        "sellerDetails": {
            "tin": "1014409555",
            "legalName": "YOUR BUSINESS NAME",
            "businessName": "Your Brand",
            "emailAddress": "info@yourbusiness.com",
            "referenceNo": "INV-2026-001", // Your ERP's own invoice number
            "isCheckReferenceNo": "0" // 0: No (default), 1: reject duplicates of referenceNo
        },
        "basicInformation": {
            "invoiceNo": "", // Leave empty - URA returns the FDN here
            "antifakeCode": "", // Leave empty - URA fills the verification code
            "deviceNo": "1014409555_02",
            "issuedDate": "2026-05-30 10:30:00", // yyyy-MM-dd HH:mm:ss
            "operator": "Jane Kasule", // The person serving the customer
            "currency": "UGX", // From the currencyType dictionary
            "invoiceType": "1", // 1: Invoice/Receipt, 4: Debit Note, 5: Credit Memo/Rebate
            "invoiceKind": "1", // 1: Invoice, 2: Receipt
            "dataSource": "103" // 103: WebService API - use this for ERP integrations
        },
        "buyerDetails": {
            "buyerType": "1", // 0: B2B, 1: B2C, 2: Foreigner, 3: B2G
            "buyerLegalName": "John Doe"
        },
        "goodsDetails": [
            {
                "item": "Premium Water 500ml",
                "itemCode": "SKU-BOTTLE-01", // Must match a registered good's goodsCode
                "qty": "2",
                "unitOfMeasure": "101", // From the rateUnit dictionary
                "unitPrice": "100000", // Gross (tax-inclusive)
                "total": "200000", // qty x unitPrice
                "taxRate": "0.18", // 0.18 = 18%, 0 = zero-rated, "-" = exempt
                "tax": "30508.47", // VAT portion of total: 200000 x 18/118
                "orderNumber": "0", // Starts at 0, +1 per line
                "discountFlag": "2", // 2: non-discount item
                "deemedFlag": "2", // 2: not deemed
                "exciseFlag": "2", // 2: no excise
                "goodsCategoryId": "22011000" // VAT commodity classification from registration
            }
        ],
        "taxDetails": [
            {
                "taxCategoryCode": "01", // 01: Standard (18%)
                "netAmount": "169491.53",
                "taxRate": "0.18",
                "taxAmount": "30508.47",
                "grossAmount": "200000.00" // netAmount + taxAmount must equal grossAmount
            }
        ],
        "summary": {
            "netAmount": "169491.53",
            "taxAmount": "30508.47",
            "grossAmount": "200000.00",
            "itemCount": "1", // Number of goodsDetails lines MINUS discount lines
            "modeCode": "1", // 1: Online, 0: Offline (qrCode required if 0)
            "remarks": "Thank you for your business" // Optional, max 500 chars
        },
        "payWay": [
            {
                "paymentMode": "102", // See payment codes below
                "paymentAmount": "200000.00",
                "orderNumber": "a" // Lowercase letters: a, b, c...
            }
        ]
    }
}

Key field reference

buyerType:

Code Meaning
0 B2B (Business to Business) - buyerTin required
1 B2C (Individual)
2 Foreigner
3 B2G (Government) - buyerTin required

paymentMode:

Code Meaning
101 Credit
102 Cash
103 Cheque
104 Demand Draft
105 Mobile Money
106 Visa/Mastercard
107 EFT
108 POS
109 RTGS
110 Swift Transfer

taxRate per line:

Value Meaning
0.18 Standard VAT (18%)
0 Zero Rated
"-" Exempt

invoiceIndustryCode:

Code Meaning
101 General Industry (default - omit this field for normal invoices)
102 Export (see scenario D)
104 Imported Service (see scenario F)
105 Telecom
106 Stamp Duty
107 Hotel Service
108 Other Taxes
109 Airline Business (see scenario G)
110 EDC (see scenario G)
111 Auction
112 Export Service
summary.itemCount must equal the number of goodsDetails lines minus the number of discount lines (discountFlag = 0), or EFRIS returns error 1304.

B. Discounts

A discounted item is expressed as two lines: the parent item (discountFlag: "1") followed immediately by a discount line (discountFlag: "0").

Rules:

  • Parent line: discountFlag: "1", discountTotal = negative discount amount (equal to the absolute value of the discount line's total), discountTaxRate as decimal (e.g. "0.18").
  • Discount line: discountFlag: "0", negative total and tax; qty, unitOfMeasure, unitPrice must be empty; item name = parent name + " (discount)".
  • qty, unitPrice are required (and positive) when discountFlag is 1 or 2.
  • The first goods line cannot be discountFlag: "0" and the last line cannot be "1".
{
    "goodsDetails": [
        {
            "item": "Premium Water 500ml",
            "itemCode": "SKU-BOTTLE-01",
            "qty": "5",
            "unitOfMeasure": "101",
            "unitPrice": "100000",
            "total": "500000",
            "taxRate": "0.18",
            "tax": "76271.19",
            "discountTotal": "-10000", // Negative; = |total| of the discount line
            "discountTaxRate": "0.18",
            "orderNumber": "0",
            "discountFlag": "1", // 1: discounted item
            "deemedFlag": "2",
            "exciseFlag": "2",
            "goodsCategoryId": "22011000"
        },
        {
            "item": "Premium Water 500ml (discount)", // Parent name + " (discount)"
            "itemCode": "SKU-BOTTLE-01",
            "qty": "", // Must be empty on the discount line
            "unitOfMeasure": "",
            "unitPrice": "",
            "total": "-10000", // Negative
            "taxRate": "0.18",
            "tax": "-1525.42", // Negative
            "orderNumber": "1",
            "discountFlag": "0", // 0: discount amount line
            "deemedFlag": "2",
            "exciseFlag": "2",
            "goodsCategoryId": "22011000"
        }
    ],
    "taxDetails": [
        {
            "taxCategoryCode": "01",
            "netAmount": "415254.23",
            "taxRate": "0.18",
            "taxAmount": "74745.77",
            "grossAmount": "490000.00"
        }
    ],
    "summary": {
        "netAmount": "415254.23",
        "taxAmount": "74745.77",
        "grossAmount": "490000.00",
        "itemCount": "1", // 2 lines - 1 discount line
        "modeCode": "1"
    }
}

C. Excise duty items

For items subject to excise duty, set exciseFlag: "1". The following per-item fields then become required: categoryId (the excise duty code), categoryName, exciseRate, exciseRule, exciseTax. When exciseRule = "2" (unit-based), pack, stick, exciseUnit, and exciseCurrency are also required.

{
    "goodsDetails": [
        {
            "item": "Mineral Water 1L",
            "itemCode": "WATER-LITRE",
            "qty": "100",
            "unitOfMeasure": "102",
            "unitPrice": "2000",
            "total": "200000",
            "taxRate": "0.18",
            "tax": "30508.47", // VAT portion only
            "orderNumber": "0",
            "discountFlag": "2",
            "deemedFlag": "2",
            "exciseFlag": "1", // 1: item attracts excise duty
            "goodsCategoryId": "50202310",
            "categoryId": "LED190400", // Excise Duty code - required when exciseFlag = 1
            "categoryName": "Mineral Water", // Required when exciseFlag = 1
            "exciseRule": "2", // 1: by rate (percentage), 2: by quantity (unit)
            "exciseRate": "150", // Rule 1: decimal e.g. "0.12"; Rule 2: amount per unit
            "exciseTax": "15000", // Total excise for this line - required when exciseFlag = 1
            "pack": "1", // Required when exciseRule = 2 - use packageScaledValue from registration
            "stick": "1", // Required when exciseRule = 2 - use pieceScaledValue from registration
            "exciseUnit": "102", // Required when exciseRule = 2 - rateUnit dictionary
            "exciseCurrency": "UGX", // Required when exciseRule = 2 - currencyType dictionary
            "exciseRateName": "UGX150 per litre" // Rule 1: (rate x 100) + "%"; Rule 2: currency + rate + " " + unit
        }
    ],
    "taxDetails": [
        {
            "taxCategoryCode": "01", // Standard VAT line
            "netAmount": "169491.53",
            "taxRate": "0.18",
            "taxAmount": "30508.47",
            "grossAmount": "200000.00"
        },
        {
            "taxCategoryCode": "05", // Separate Excise Duty line
            "netAmount": "154491.53",
            "taxRate": "150", // Per-unit rate
            "taxAmount": "15000.00",
            "grossAmount": "169491.53",
            "exciseUnit": "102", // Required in taxDetails when excise is per-unit
            "exciseCurrency": "UGX", // Required in taxDetails when excise is per-unit
            "taxRateName": "UGX150 per litre"
        }
    ]
}

exciseRule:

Code Meaning
"1" Percentage-based (exciseRate = decimal e.g. "0.12" for 12%; "-" if the rate is Nil)
"2" Quantity/unit-based (exciseRate = fixed amount per unit e.g. "150" = UGX 150 per litre)

exciseUnit codes (from the rateUnit dictionary):

Code Meaning
101 Per stick
102 Per litre
103 Per kg
104 Per user per day of access
105 Per minute
106 Per 1,000 sticks
107 Per 50 kgs
109 Per 1 g

D. Export invoices

For goods being exported, set basicInformation.invoiceIndustryCode: "102".

Rules for exports:

  • buyerDetails.deliveryTermsCode is mandatory (Incoterms): CFR, CIF, CIP, CPT, DAP, DDP, DPU, EXW, FAS, FCA, FOB.
  • Per-item totalWeight (Total Net Weight in KGM) is mandatory.
  • Per-item pieceQty and pieceMeasureUnit apply only to exports (optional).
  • hsCode / hsName (HS tariff code and description) are optional.
  • Exported goods are zero-rated: use taxRate: "0" and taxCategoryCode: "02".
  • buyerDetails.nonResidentFlag: "1" for non-resident buyers.
{
    "invoice": {
        "sellerDetails": { "...": "as in scenario A" },
        "basicInformation": {
            "invoiceIndustryCode": "102", // Export
            "...": "other fields as in scenario A"
        },
        "buyerDetails": {
            "buyerType": "2", // Foreigner
            "buyerLegalName": "Nairobi Traders Ltd",
            "nonResidentFlag": "1",
            "deliveryTermsCode": "FOB" // Mandatory for export
        },
        "goodsDetails": [
            {
                "item": "Ugandan Coffee",
                "itemCode": "COFFEE-001",
                "qty": "500",
                "unitOfMeasure": "103",
                "unitPrice": "12000",
                "total": "6000000",
                "taxRate": "0", // Zero-rated
                "tax": "0",
                "orderNumber": "0",
                "discountFlag": "2",
                "deemedFlag": "2",
                "exciseFlag": "2",
                "goodsCategoryId": "09011100",
                "totalWeight": "500", // Mandatory for export (KGM)
                "pieceQty": "500", // Export only
                "pieceMeasureUnit": "103", // Export only - rateUnit dictionary
                "hsCode": "0901110000", // Optional
                "hsName": "Coffee, not roasted, not decaffeinated" // Optional
            }
        ],
        "taxDetails": [
            {
                "taxCategoryCode": "02", // Zero rate
                "netAmount": "6000000",
                "taxRate": "0",
                "taxAmount": "0",
                "grossAmount": "6000000"
            }
        ],
        "summary": {
            "netAmount": "6000000",
            "taxAmount": "0",
            "grossAmount": "6000000",
            "itemCount": "1",
            "modeCode": "1"
        }
    }
}
For export of services, use invoiceIndustryCode: "112" with deliveryTermsCode; the per-item weight fields do not apply.

Bond / High-Sea sales (optional per item): highSeaBondFlag ("1" bond/high-sea, "2" not), highSeaBondCode ("101" Bond Sale, "102" High Sea Sale), highSeaBondNo.

E. Deemed VAT items

Deemed VAT applies when the buyer is a registered "deemed" party (e.g. Strategic Investors). Set deemedFlag: "1" on each deemed item.

Rules:

  • Item name must carry the suffix " (deemed)" per the EFRIS specification (name + space + (deemed)).
  • vatProjectId and vatProjectName must come from the URA project registry - query them via the deemed projects lookup first. Omitting them causes EFRIS to reject the invoice.
  • deemedExemptCode: "101" = Deemed, "102" = Exempt.
  • Group deemed lines under taxCategoryCode: "04" (Deemed 18%) in taxDetails.
{
    "goodsDetails": [
        {
            "item": "Consulting Services (deemed)", // Name + " (deemed)"
            "itemCode": "SVC-CONSULT-01",
            "qty": "1",
            "unitOfMeasure": "112",
            "unitPrice": "5000000.00",
            "total": "5000000.00",
            "taxRate": "0.18",
            "tax": "762711.86",
            "orderNumber": "0",
            "discountFlag": "2",
            "deemedFlag": "1", // 1: deemed
            "exciseFlag": "2",
            "goodsCategoryId": "73110000",
            "deemedExemptCode": "101", // 101: Deemed, 102: Exempt
            "vatProjectId": "893997229738400343", // From the deemed projects lookup - REQUIRED
            "vatProjectName": "Strategic Investor Project" // REQUIRED
        }
    ],
    "taxDetails": [
        {
            "taxCategoryCode": "04", // Deemed (18%)
            "netAmount": "4237288.14",
            "taxRate": "0.18",
            "taxAmount": "762711.86",
            "grossAmount": "5000000.00"
        }
    ]
}

F. Imported services

For imported services, set invoiceIndustryCode: "104". The importServicesSeller block then becomes required:

{
    "invoice": {
        "sellerDetails": {
            "branchId": "207300908813650312", // Cannot be empty when invoiceIndustryCode = 104
            "...": "as in scenario A"
        },
        "basicInformation": {
            "invoiceIndustryCode": "104",
            "...": "as in scenario A"
        },
        "importServicesSeller": {
            "importBusinessName": "Foreign Supplier Ltd", // Required when industry = 104
            "importAddress": "Nairobi, Kenya", // Required when industry = 104
            "importInvoiceDate": "2026-05-19", // yyyy-MM-dd
            "importEmailAddress": "supplier@example.com",
            "importContactNumber": "+254701234567",
            "importAttachmentName": "invoice.pdf", // png, doc, pdf, jpg, txt, docx, xlsx, cer, crt, der
            "importAttachmentContent": "BASE64_FILE_CONTENT"
        },
        "...": "goodsDetails / taxDetails / summary as in scenario A"
    }
}

G. Airline & EDC (fuel) invoices

Airline Business (invoiceIndustryCode: "109"): the airlineGoodsDetails array becomes required. It mirrors goodsDetails fields (item, itemCode, qty, unitOfMeasure, unitPrice, total, taxRate, tax, orderNumber, discountFlag, excise fields, etc.).

EDC / Fuel (invoiceIndustryCode: "110"): the edcDetails block becomes required:

{
    "edcDetails": {
        "tankNo": "1111", // Required
        "pumpNo": "2222", // Required
        "nozzleNo": "3333", // Required
        "controllerNo": "44444",
        "acquisitionEquipmentNo": "5555",
        "levelGaugeNo": "66666",
        "mvrn": ""
    }
}

H. Debit notes

A debit note is uploaded through the same invoice endpoint with:

  • basicInformation.invoiceType: "4" (Debit Note)
  • basicInformation.oriInvoiceId = the invoiceId URA returned for the original invoice (leave empty for normal invoices/receipts)
  • an extend block with the reason:
{
    "extend": {
        "reason": "Extra goods delivered", // Max 1024 chars
        "reasonCode": "101"
    }
}

extend.reasonCode when invoiceType = 4 (Debit Note):

Code Meaning
101 Increase in the amount payable/invoice value due to extra goods delivered or goods charged at an incorrect value
102 Buyer asked for a new debit note
103 Others (Please specify)

I. Batch invoice upload

POST/generate-fiscal-invoice/batch

Fiscalise multiple invoices in one request. Each element of invoices is a complete invoice object (same structure as scenario A):

{
    "invoices": [
        { "sellerDetails": {}, "basicInformation": {}, "...": "invoice 1" },
        { "sellerDetails": {}, "basicInformation": {}, "...": "invoice 2" }
    ]
}

What comes next

The response to a successful fiscalisation carries the FDN, verification code, and QR code - see Invoice Response for where to find each one. To reverse an invoice, see Credit Notes.

Stuck on an integration step? Our engineers reply fast.