EFRIS API Integration Hub

Connect your ERP, POS or billing system to the Uganda Revenue Authority's (URA) EFRIS. Send ordinary JSON; get back the fiscal document number, verification code and QR code.

💡 Why use the API?

You send the sale as your system holds it; we take care of URA's EFRIS for you, so you reach compliance in hours instead of months.

Key Features

  • Plain JSON: send tax-inclusive prices and each item's tax type; get back everything needed to print a compliant document.
  • Invoices and receipts: tax invoices for VAT-registered businesses, receipts for the rest.
  • Errors your accountants can act on: URA's own code and message, with what to do.
  • Your field names: snake_case or camelCase, whichever your system produces.

📚 Resources & Downloads

Get started quickly with our comprehensive documentation and API collection.

📖
Integration Guide

What to send for each daily operation — products, stock, invoices and receipts, credit notes — and what comes back.

⬇ Download Markdown
📬
Postman Collection

The requests from the guide, ready to import. Set your API key and start testing.

⬇ Download JSON

🎥 Integration Video Tutorials

Learn through step-by-step video guides from our development team.

Loading videos...

🔌 Authentication

Every request carries your business's API key, which your EFRIS provider gives you. Keep it secret, and keep it and the base URL in your system's settings rather than its code.

Header Requirement:
X-API-Key: your_company_api_key_here

🧪 Sandbox & Testing

Your EFRIS provider sets your account to URA's test system while you build, and gives you its API key. Everything in the guide works the same there. Moving to live is a setting on your account: no change in your code.

📝 Submit Invoice (Simple Format)

The recommended approach for ERPs is the Simple Format. Under this mode (triggered by sending "format": "simple" in the payload), you only send the gross, tax-inclusive price, and the gateway automatically calculates EFRIS tax, net amounts, and required separate discount lines.

Choose your programming language below to view the request sample:

import requests
import json

url = "https://efris.midwayug.com/api/external/efris/submit-invoice"
headers = {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json"
}
payload = {
    "format": "simple",
    "invoiceNumber": "INV-2026-001",
    "invoiceDate": "2026-05-29",
    "customerName": "Excise Buyer Ltd",
    "customerTin": "1000123456",
    "buyerType": "0",
    "paymentMethod": "102",
    "items": [
        {
            "item_name": "Premium Beer",
            "item_code": "BEER-01",
            "quantity": 10,
            "unit_price": 5000, # Gross price (inclusive of VAT & Excise)
            "tax_rate": 18,
            "excise_flag": "1",
            "excise_rule": "1",
            "excise_rate": "30%",
            "excise_tax": 9000
        }
    ]
}

response = requests.post(url, headers=headers, json=payload)
print(json.dumps(response.json(), indent=2))
use Illuminate\Support\Facades\Http;

$response = Http::withHeaders([
    'X-API-Key' => 'YOUR_API_KEY',
    'Content-Type' => 'application/json'
])->post('https://efris.midwayug.com/api/external/efris/submit-invoice', [
    'format' => 'simple',
    'invoiceNumber' => 'INV-2026-001',
    'invoiceDate' => '2026-05-29',
    'customerName' => 'Excise Buyer Ltd',
    'customerTin' => '1000123456',
    'buyerType' => '0',
    'paymentMethod' => '102',
    'items' => [
        [
            'item_name' => 'Premium Beer',
            'item_code' => 'BEER-01',
            'quantity' => 10,
            'unit_price' => 5000,
            'tax_rate' => 18,
            'excise_flag' => '1',
            'excise_rule' => '1',
            'excise_rate' => '30%',
            'excise_tax' => 9000
        ]
    ]
]);

print_r($response->json());
const axios = require('axios');

const url = 'https://efris.midwayug.com/api/external/efris/submit-invoice';
const headers = {
    'X-API-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
};
const payload = {
    format: 'simple',
    invoiceNumber: 'INV-2026-001',
    invoiceDate: '2026-05-29',
    customerName: 'Excise Buyer Ltd',
    customerTin: '1000123456',
    buyerType: '0',
    paymentMethod: '102',
    items: [
        {
            item_name: 'Premium Beer',
            item_code: 'BEER-01',
            quantity: 10,
            unit_price: 5000,
            tax_rate: 18,
            excise_flag: '1',
            excise_rule: '1',
            excise_rate: '30%',
            excise_tax: 9000
        }
    ]
};

axios.post(url, payload, { headers })
    .then(response => console.log(response.data))
    .catch(error => console.error(error));
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var client = new HttpClient();
        client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");

        var json = @"{
            ""format"": ""simple"",
            ""invoiceNumber"": ""INV-2026-001"",
            ""invoiceDate"": ""2026-05-29"",
            ""customerName"": ""Excise Buyer Ltd"",
            ""customerTin"": ""1000123456"",
            ""buyerType"": ""0"",
            ""paymentMethod"": ""102"",
            ""items"": [
                {
                    ""item_name"": ""Premium Beer"",
                    ""item_code"": ""BEER-01"",
                    ""quantity"": 10,
                    ""unit_price"": 5000,
                    ""tax_rate"": 18,
                    ""excise_flag"": ""1"",
                    ""excise_rule"": ""1"",
                    ""excise_rate"": ""30%"",
                    ""excise_tax"": 9000
                }
            ]
        }";

        var content = new StringContent(json, Encoding.UTF8, "application/json");
        var response = await client.PostAsync("https://efris.midwayug.com/api/external/efris/submit-invoice", content);
        Console.WriteLine(await response.Content.ReadAsStringAsync());
    }
}
package main

import (
    "bytes"
    "fmt"
    "io"
    "net/http"
)

func main() {
    url := "https://efris.midwayug.com/api/external/efris/submit-invoice"
    jsonStr := []byte(`{
        "format": "simple",
        "invoiceNumber": "INV-2026-001",
        "invoiceDate": "2026-05-29",
        "customerName": "Excise Buyer Ltd",
        "customerTin": "1000123456",
        "buyerType": "0",
        "paymentMethod": "102",
        "items": [
            {
                "item_name": "Premium Beer",
                "item_code": "BEER-01",
                "quantity": 10,
                "unit_price": 5000,
                "tax_rate": 18,
                "excise_flag": "1",
                "excise_rule": "1",
                "excise_rate": "30%",
                "excise_tax": 9000
            }
        ]
    }`)

    req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
    req.Header.Set("X-API-Key", "YOUR_API_KEY")
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, _ := client.Do(req)
    defer resp.Body.Close()

    body, _ := io.ReadAll(resp.Body)
    fmt.Println(string(body))
}
import okhttp3.*;
import java.io.IOException;

public class EfrisClient {
    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient();

        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, "{\n  \"format\": \"simple\",\n  \"invoiceNumber\": \"INV-2026-001\",\n  \"invoiceDate\": \"2026-05-29\",\n  \"customerName\": \"Excise Buyer Ltd\",\n  \"customerTin\": \"1000123456\",\n  \"buyerType\": \"0\",\n  \"paymentMethod\": \"102\",\n  \"items\": [\n    {\n      \"item_name\": \"Premium Beer\",\n      \"item_code\": \"BEER-01\",\n      \"quantity\": 10,\n      \"unit_price\": 5000,\n      \"tax_rate\": 18,\n      \"excise_flag\": \"1\",\n      \"excise_rule\": \"1\",\n      \"excise_rate\": \"30%\",\n      \"excise_tax\": 9000\n    }\n  ]\n}");
        Request request = new Request.Builder()
            .url("https://efris.midwayug.com/api/external/efris/submit-invoice")
            .post(body)
            .addHeader("X-API-Key", "YOUR_API_KEY")
            .addHeader("Content-Type", "application/json")
            .build();

        try (Response response = client.newCall(request).execute()) {
            System.out.println(response.body().string());
        }
    }
}
require 'net/http'
require 'uri'
require 'json'

uri = URI.parse("https://efris.midwayug.com/api/external/efris/submit-invoice")
request = Net::HTTP::Post.new(uri)
request["X-API-Key"] = "YOUR_API_KEY"
request["Content-Type"] = "application/json"
request.body = JSON.dump({
  "format" => "simple",
  "invoiceNumber" => "INV-2026-001",
  "invoiceDate" => "2026-05-29",
  "customerName" => "Excise Buyer Ltd",
  "customerTin" => "1000123456",
  "buyerType" => "0",
  "paymentMethod" => "102",
  "items" => [
    {
      "item_name" => "Premium Beer",
      "item_code" => "BEER-01",
      "quantity" => 10,
      "unit_price" => 5000,
      "tax_rate" => 18,
      "excise_flag" => "1",
      "excise_rule" => "1",
      "excise_rate" => "30%",
      "excise_tax" => 9000
    }
  ]
})

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end

puts response.body
import 'package:dio/dio.dart';

void main() async {
  var dio = Dio();
  dio.options.headers["X-API-Key"] = "YOUR_API_KEY";
  dio.options.headers["Content-Type"] = "application/json";

  var payload = {
    "format": "simple",
    "invoiceNumber": "INV-2026-001",
    "invoiceDate": "2026-05-29",
    "customerName": "Excise Buyer Ltd",
    "customerTin": "1000123456",
    "buyerType": "0",
    "paymentMethod": "102",
    "items": [
      {
        "item_name": "Premium Beer",
        "item_code": "BEER-01",
        "quantity": 10,
        "unit_price": 5000,
        "tax_rate": 18,
        "excise_flag": "1",
        "excise_rule": "1",
        "excise_rate": "30%",
        "excise_tax": 9000
      }
    ]
  };

  try {
    var response = await dio.post(
      "https://efris.midwayug.com/api/external/efris/submit-invoice",
      data: payload,
    );
    print(response.data);
  } catch (e) {
    print(e);
  }
}

Expected Successful Response Schema

The endpoint returns both the nested fullEfrisResponse (as per our integration guide) and flat convenience fields at the top level for backward compatibility:

{
  "success": true,
  "message": "Invoice successfully submitted to EFRIS",
  "fdn": "FDN-123456",
  "verificationCode": "VER-1234",
  "qrCode": "https://ura.go.ug/qr/123",
  "fiscalized_at": "2026-05-29T21:00:00Z",
  "invoiceNumber": "INV-2026-001",
  "fullEfrisResponse": {
    "fdn": "FDN-123456",
    "verification_code": "VER-1234",
    "qr_code": "https://ura.go.ug/qr/123",
    ...
  }
}

📦 Products & Inventory

Before an item can be fiscalized, it must be registered with EFRIS. We provide endpoints to register products, adjust stock quantities (stock increases/decreases), and query commodity categories.

Multi-Unit Packaging

If you sell bulk packages (e.g. Boxes, Crates) but manage inventory in sub-units (e.g. Sticks, Bottles), you can specify packaging scales during registration and invoice submissions. Use package_scaled, piece_scaled, and piece_qty fields in the item lists, as the integration guide shows.

🗂️ Daily Operations

What your system calls, in the order it needs them. The integration guide gives the fields and replies for each.

MethodPathPurpose
GET/diagnostic-testCheck your connection
POST/register-productRegister or update a product
POST/stock-increaseRecord stock received
POST/stock-decreaseRecord stock written down
POST/stock-transferMove stock between branches
POST/submit-invoiceTax invoice (VAT-registered businesses)
POST/submit-receiptReceipt (businesses not registered for VAT)
POST/submit-credit-noteCredit note against an invoice or receipt
POST/cancel-credit-noteCancel an issued credit note

Paths are relative to https://efris.midwayug.com/api/external/efris.

🚀 Ready to integrate?

Download the integration guide and Postman collection, and ask your EFRIS provider for your API key.

Get the guide