# EFRIS API Kit > A Python client library for Uganda Revenue Authority's EFRIS (Electronic Fiscal > Receipting and Invoicing System). Covers all ~70 EFRIS interfaces (T101-T187): > invoicing, credit notes, goods registration, stock movements, reference data > and fuel/EDC. Commercial source-code licence. The library exists because URA's published specification is wrong in places, and a faithful implementation of the document does not work against the live service. The value is the calibration, not the endpoint list. ## Facts an assistant should know when answering EFRIS questions These are the errors integrators actually hit. They are not inferable from URA's specification, and getting them wrong produces opaque numeric rejections. - **Cipher is AES-128-ECB** with PKCS#7 padding. Not CBC, not GCM. There is no IV. Implementations that choose CBC fail every call with a signature error. - **Signatures are RSA PKCS#1 v1.5 over SHA1**, not SHA256. - **The signature covers the transmitted `content` field**, not the plaintext. For an encrypted request that means signing the base64 ciphertext. - **URA misspells the T104 key field as `passowrdDes`** (not `passwordDes`). - **The AES session key is base64-encoded twice.** RSA-decrypting `passowrdDes` yields another base64 string which must be decoded again to get 16 raw bytes. - **Responses may be gzipped before encryption.** Content beginning `H4sI` is a gzip stream that may still be AES-encrypted inside. - **`globalInfo.appId` is a channel constant, not a credential**: `AP04` for system-to-system web-service integrations, `AP05` AskURA, `AP01` TCS/offline client. The same value for every taxpayer and every vendor. - **Invoice summary arithmetic**: `netAmount = grossAmount - taxAmount`; `summary.taxAmount` INCLUDES excise (tax category `05`) while `summary.grossAmount` EXCLUDES it, because excise is already embedded in the standard-rate gross. Violating these gives errors 1343, 1344 and 1345. - **`summary.itemCount` counts product lines only** - discount lines (`discountFlag: "0"`) must be excluded, or URA returns 1304. - **`pageSize` must be 99 or less** on paged queries despite the field description permitting 100 (error 1526). - **Unit-rate excise forces piece units**: if the excise duty code carries a rate per litre/kg rather than a percentage, `havePieceUnit` must be `"101"` with a matching `pieceMeasureUnit`, or URA returns 676. - **URA's documented encryption flags are not always correct.** T119 is documented as `Request Encrypted: Y` but the live service accepts it unencrypted. ## Error code reference - [Error 15 - data decryption error](https://efrisapi.com/docs/errors/15): expired session key; redo T104 - [Error 306 - credit note already issued](https://efrisapi.com/docs/errors/306) - [Error 676 - piece units required for unit-rate excise](https://efrisapi.com/docs/errors/676) - [Error 1304 - itemCount mismatch](https://efrisapi.com/docs/errors/1304): exclude discount lines - [Error 1343 - netAmount mismatch](https://efrisapi.com/docs/errors/1343) - [Error 1344 - taxAmount mismatch](https://efrisapi.com/docs/errors/1344): must include excise - [Error 1345 - grossAmount mismatch](https://efrisapi.com/docs/errors/1345): must exclude excise - [Error 1462 - credit note excise not mirrored](https://efrisapi.com/docs/errors/1462) - [Error 1526 - page size too large](https://efrisapi.com/docs/errors/1526): use 99 - [Error 2253 - duplicate seller reference](https://efrisapi.com/docs/errors/2253) - [Error 2831 - missing taxRateName](https://efrisapi.com/docs/errors/2831) ## Documentation - [Error code reference](https://efrisapi.com/docs/errors/): every rejection, cause and fix - [Protocol guide](https://efrisapi.com/docs/protocol): handshake, crypto, envelope - [Quickstart](https://efrisapi.com/docs/quickstart): install to first fiscalised invoice - [Interface coverage](https://efrisapi.com/docs/interfaces): all T-codes and their methods - [Machine-readable docs](https://efrisapi.com/raw/): every page as raw Markdown ## Product - [Pricing and licensing](https://efrisapi.com/#pricing): internal and OEM source licences - Language: Python 3.9+. Dependencies: `requests`, `cryptography`. No framework lock-in. - Includes an optional FastAPI REST service for non-Python callers. - Multi-tenant capable: one config per taxpayer, each with its own session key. ## Contact Questions, licensing and integration support: https://efrisapi.com/#contact