Data Lookups & Inquiries
Almost every field code used in this documentation - units of measure, currencies, commodity categories, excise
duty codes, branch IDs - comes from EFRIS reference data that you query through these lookups. All lookups are
POST requests under the same base URL.
Pagination: endpoints marked as paginated accept a request body of:
{
"pageNo": 1,
"pageSize": 15 // Max 99 - a value of 100 or more throws an error
}
Endpoint overview
| Endpoint | Purpose |
|---|---|
/test-connection |
Connectivity check; returns the EFRIS server time (useful for clock-skew debugging) |
/login |
Taxpayer info, device details, and dictionary versions |
/refresh-aes-key |
Fetch a fresh encryption key (valid 24 hours) - normally handled automatically |
/sync-dictionary |
Full system dictionary: rateUnit (units of measure), currencyType,
payWay, etc.
|
/validate-tin |
Look up any taxpayer by tin or ninBrn (e.g. a buyer for B2B invoices)
- defaults to the TIN in the URL when the body is empty |
/query-branches |
All branches with IDs - required for /transfer-stock |
/query-exchange-rates |
All exchange rates (optional issueDate) |
/query-single-exchange-rate |
Rate for one currency. Required: currency (e.g. "USD"); optional
issueDate
|
/query-commodity-categories |
Full commodity classification tree (for commodityCategoryId /
goodsCategoryId)
|
/query-paginated-commodity-categories |
Same, paginated. Required: pageNo, pageSize (max 99) |
/query-excise-duty |
All excise duty codes and rates |
/query-deemed-projects |
Valid vatProjectId values for deemed invoices. Optional:
commodityCategoryCode
|
/register-good-or-service |
See Goods Registration |
/query-goods |
Registered goods (paginated: pageNo, pageSize) |
/query-stock-quantity |
Current stock for a good. Required: goodsId; optional branchId |
/query-good-details |
Full EFRIS record for one good. Required: goodsCode |
/query-stock-movement-history |
Stock in/out/transfer log. Required: pageNo, pageSize, plus at least
one of productionBatchNo, invoiceNo, referenceNo |
/query-invoices |
Search fiscalised invoices (filters: invoiceNo, buyerTin,
startDate, endDate, referenceNo, ...)
|
/query-normal-invoices |
Invoices eligible for a credit note |
/invoice-details |
Retrieve one fiscalised invoice. Required: invoiceNo (the FDN) - use this to
recover data if your ERP timed out during submission |
The system dictionary
No request body. Returns the full EFRIS system dictionary - the source of every value code used
elsewhere (units of measure, currencies, payment modes, Incoterms, ...).
Example data (abridged - each list contains many more entries):
{
"rateUnit": [
// Units of measure -> measureUnit, pieceMeasureUnit, exciseUnit
{ "value": "101", "name": "per stick" },
{ "value": "102", "name": "per litre" },
{ "value": "103", "name": "per kg" }
],
"currencyType": [
// Currency codes -> basicInformation.currency
{ "value": "101", "name": "UGX" },
{ "value": "102", "name": "USD" }
],
"payWay": [
// Payment modes -> payWay[].paymentMode
{ "value": "101", "name": "Credit" },
{ "value": "102", "name": "Cash" }
],
"deliveryTerms": [
// Incoterms -> basicInformation.deliveryTermsCode (export invoices)
{ "value": "CFR", "name": "Cost and Freight" },
{ "value": "CIF", "name": "Cost Insurance and Freight" }
],
"creditNoteMaximumInvoicingDays": {
"value": "90", // Credit notes only allowed within this many days of the original invoice
"name": "Credit Note Maximum Invoicing days"
},
"creditNoteValuePercentLimit": {
"value": "0.6",
"name": "credit Note Value Percent Limit"
},
"format": {
"dateFormat": "dd/MM/yyyy",
"timeFormat": "dd/MM/yyyy HH:mm:ss"
},
"customsPackUnitList": [
// Customs units for export goods - each has a validity window
{
"value": "101",
"name": "per stick",
"validPeriodFrom": "2021/08/17",
"periodTo": "2021/08/31"
}
],
"customsPieceUnitList": [
{
"value": "101",
"name": "per stick",
"validPeriodFrom": "2021/08/17",
"periodTo": "2021/08/31"
}
],
"sector": [
{ "code": "123", "name": "Cigarettes", "parentClass": "0", "requiredFill": "0" }
]
}
/login reports a new dictionaryVersion - the codes
rarely change.
TIN validation
Look up any taxpayer's URA registration profile - e.g. a buyer's legalName before issuing a B2B
invoice. Request (body optional - when both fields are omitted, the TIN in the URL is validated
instead):
{
"tin": "1000029771", // The taxpayer to look up
"ninBrn": "" // Alternative lookup by NIN (individuals) or BRN (companies)
}
Example data:
{
"taxpayer": {
"address": "198 NIP BUILDING Nakawa KAMPALA NAKAWA DIVISION BUGOLOBI",
"businessName": "UGANDA REVENUE AUTHORITY",
"contactEmail": "services@ura.go.ug",
"contactNumber": "256778497936",
"governmentTIN": "0", // "1": government entity, "0": not
"legalName": "UGANDA REVENUE AUTHORITY",
"taxpayerStatus": "101",
"taxpayerType": "202", // 201: Individual, 202: Non-Individual
"tin": "1000029771"
}
}
Branches
Example data:
[
{
"branchId": "206637525568955296",
"branchName": "Mr. STEPHEN BUNJO"
},
{
"branchId": "206637528324276772",
"branchName": "ARINAIT AND SONS CO. LIMITED"
}
]
Exchange rates (all currencies)
Request (body optional - omit issueDate for today's rates):
{
"issueDate": "2026-07-17" // Optional - format yyyy-MM-dd
}
Example data (one entry per currency):
[
{
"currency": "USD",
"rate": "3700", // 1 USD = 3700 UGX
"importDutyLevy": "3740.6388",
"inComeTax": "3740.6388",
"exportLevy": "3730.6444"
},
{
"currency": "EUR",
"rate": "4020.5",
"importDutyLevy": "4060.705",
"inComeTax": "4060.705",
"exportLevy": "4050.2"
}
]
Exchange rate (single currency)
Request:
{
"currency": "USD", // Required - 3-letter code from the currencyType dictionary
"issueDate": "2026-07-17" // Optional - yyyy-MM-dd; omit for today's rate
}
Example data:
{
"currency": "USD",
"rate": "3700", // 1 USD = 3700 UGX - use this for basicInformation.currencyRate
"importDutyLevy": "3740.6388",
"inComeTax": "3740.6388",
"exportLevy": "3730.6444"
}
Commodity categories
No request body. Returns the entire commodity classification tree - thousands of entries. Prefer the paginated variant below for interactive use; use this one only for a full local sync.
Example data:
[
{
"commodityCategoryCode": "50202203",
"parentCode": "50202200",
"commodityCategoryName": "Bottled water",
"commodityCategoryLevel": "4", // Tree depth; only leaf nodes can be assigned to goods
"rate": "0.18", // VAT rate of this category (0.18 = 18%, "-" = exempt)
"isLeafNode": "101", // 101: Yes (assignable), 102: No (grouping node)
"serviceMark": "102", // 101: service, 102: goods
"isZeroRate": "102", // 101: Yes, 102: No
"zeroRateStartDate": "",
"zeroRateEndDate": "",
"isExempt": "102", // 101: Yes, 102: No
"exemptRateStartDate": "",
"exemptRateEndDate": "",
"enableStatusCode": "1", // 1: enabled, 0: disabled
"exclusion": "2" // 0: Zero-rated, 1: Exempt, 2: No exclusion
}
]
Commodity categories (paginated)
Request:
{
"pageNo": 1,
"pageSize": 15 // Max 99 - 100+ throws an error
}
Example data:
{
"page": {
"pageNo": "1",
"pageSize": "15",
"totalSize": "8213", // Total records
"pageCount": "548" // Total pages
},
"records": [
{
"commodityCategoryCode": "50202203",
"parentCode": "50202200",
"commodityCategoryName": "Bottled water",
"commodityCategoryLevel": "4",
"rate": "0.18",
"isLeafNode": "101", // 101: Yes, 102: No
"serviceMark": "102", // 101: service, 102: goods
"isZeroRate": "102",
"zeroRateStartDate": "",
"zeroRateEndDate": "",
"isExempt": "102",
"exemptRateStartDate": "",
"exemptRateEndDate": "",
"enableStatusCode": "1", // 1: enabled, 0: disabled
"exclusion": "2", // 0: Zero, 1: Exempt, 2: No exclusion, 3: Both 0% & '-'
"excisable": "101", // 101: attracts excise duty, 102: does not
"vatOutScopeCode": "102" // VAT out of scope - 101: Yes, 102: No
}
]
}
Excise duty codes
Example data:
{
"exciseDutyList": [
{
"id": "000023",
"exciseDutyCode": "LED190400",
"goodService": "Mineral Water",
"parentCode": "LED190000",
"rateText": "shs.150.00 Per litre",
"isLeafNode": "1",
"effectiveDate": "19/02/2025",
"exciseDutyDetailsList": [
{
"exciseDutyId": "000023",
"type": "102", // 101: Percentage, 102: Unit of measurement
"rate": "150",
"unit": "102", // Empty when type = 101; rateUnit code when type = 102
"currency": "101"
}
]
}
]
}
type maps to exciseRule on invoices: 101 → rule "1"
(percentage), 102 → rule "2" (per unit). Codes with type: "102" are the
ones requiring havePieceUnit: "101" at registration - see
Good
Registration, scenario D.
Deemed VAT projects
The TIN is taken from the URL automatically. Request (body optional):
{
"commodityCategoryCode": "50202203" // Optional filter; multiple codes separated by commas
}
Example data:
{
"taxpayerType": "103", // 101: normal, 102: exempt, 103: deemed, 104: both deemed & exempt
"exemptType": "101", // 101: VAT, 102: Excise Duty, 103: both (only present for exempt taxpayers)
"commodityCategory": [
{
"commodityCategoryCode": "50202203",
"commodityCategoryTaxpayerType": "103" // Same codes as taxpayerType
}
],
"deemedAndExemptProjectList": [
{
"projectId": "893997229738400343", // -> goodsDetails[].vatProjectId
"projectName": "Kampala Water Project", // -> goodsDetails[].vatProjectName
"deemedExemptCode": "101", // 101: Strategic Investor, 102: Petroleum Licensee, 103: Aid funded project Contractor, 104: Government MDA, 105: VAT & Excise Duty Exempt, 106: Excise Duty Exempt, 107: Mining Licensee, 108: EACOP Licensee, 109: EACOP Level 1 Contractor
"commodityCategoryCode": "50202203",
"serviceMark": "102", // 101: service, 102: goods
"unit": "101", // rateUnit dictionary
"currentQty": "100",
"currentAmount": "100",
"currency": "USD",
"exchangeRateDate": "2026-06-12",
"currentAmountCurrency": "100"
}
]
}
projectId / projectName as vatProjectId /
vatProjectName on deemed invoice lines - see
Fiscal Invoices, scenario E.