ThatFiscal Knowledge Base

ZIMRA Fiscalisation REST API — Fiscalise From Any System

~1 hour · developer

Overview. One endpoint fiscalises anything: in-house systems, Dynamics 365, SAP Business One, Xero via Zapier, WooCommerce, mobile apps. POST the invoice JSON; get back the QR URL, verification code and fiscal numbers in the same response.

Step 1

Authenticate

Header X-Api-Key: tf_… on every call. Your key is in Portal → Settings & Branding.

Step 2

POST /api/invoices

Send the canonical invoice. Field names matter — this is the exact shape the API validates:

{
  "invoice_no": "INV-001",
  "receipt_type": "FiscalInvoice",
  "currency": "USD",
  "lines_tax_inclusive": true,
  "buyer": {"name": "Acme Distributors", "tin": "1010101010"},
  "lines": [
    {"name": "Cement 32.5N", "hs_code": "25232900", "qty": 10,
     "price": 11.55, "total": 115.50, "tax_percent": 15.5, "tax_id": 3}
  ],
  "payments": [{"money_type": "Cash", "amount": 115.00}]
}

The buyer object is buyer (not customer), the unit price is price (not unit_price) and the rate is tax_percent (not tax_rate). HS codes are optional — we auto-fill them.

Step 3

Know What Is Required

A payload that is missing something comes back 422 with a message naming every problem at once, not just the first. The rules:

  • invoice_no — required, 50 characters maximum.
  • currency — required, exactly 3 letters (USD, ZWG, ZAR…).
  • receipt_type — FiscalInvoice (the default), CreditNote or DebitNote. Nothing else.
  • lines — a non-empty list. Every line needs a name and a total or a price; send total whenever you can. Any of total, price, qty, tax_percent that is present must be a number.
  • payments — optional. If you send it, it must be a list and each entry needs a numeric amount. Leave it out and we settle the whole invoice to Cash.
  • credited_invoice — required when receipt_type is CreditNote or DebitNote.
Step 4

Use the Response

You receive id, status, qr_url, verification_code, receipt_global_no, receipt_counter, error_code and attempts — render the QR and verification code on your invoice. Always check status: fiscalised and fiscalised_yellow mean ZIMRA accepted it; error means it did not, and error_code tells you why. Full reference with worked examples: API Documentation.

Idempotency: re-posting the same invoice_no and receipt_type to the same device returns the receipt that was already fiscalised instead of creating a second one — safe to retry after a timeout. A credit note may reuse the invoice number it reverses.
If ZIMRA Is Down: the call is synchronous, so the receipt comes back with status: "error" and a retryable error_code — it is stored, never lost, and you re-submit it with Resend in the portal or POST /portal/receipts/{id}/resend. If you trade in places with no connectivity, ask us about offline batch mode (/api/offline/queue and /api/offline/sync), included on Enterprise and available as an add-on.
Need a Hand? Email support@thatfiscal.com or call +263 78 674 5282. If it is quicker, we will do the setup with you on the call.
← All Knowledge Base Guides