Back to Home

API Documentation

Fiscal Suite Web API Guidelines v1.0.1

01

Introduction

The Fiscal Support Services (FSS) Web API allows third-party applications and fiscal devices to integrate directly with the Fiscal Suite Cloud platform for invoice fiscalisation, status tracking, and reconciliation.

The API base URL for all endpoints is:

https://api.fiscalsupportservices.com/api/converter

All requests must be made over HTTPS. Unencrypted HTTP requests will be rejected.

02

Authentication

API consumers authenticate using an API key passed in the X-API-Key header. API keys are issued by Fiscal Support Services during onboarding and are tied to a specific entity and device.

X-API-Key: fss_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Key details:

  • Keys are prefixed with fss_ and are 40+ characters long
  • The first 8 characters are used as a lookup prefix; the full key is verified against a stored hash
  • Keys can be revoked at any time by FSS support
  • If a key is invalid or revoked, a 401 AuthenticationFailed response is returned
03

Invoice Submission

The invoice submission endpoint sends invoice data from your application to the fiscal system for processing and fiscalisation. Once received, the system validates the payload, processes the invoice, and returns a response with the job ID for tracking.

POST https://api.fiscalsupportservices.com/api/converter/invoices/submit/

Headers:

Content-Type: application/json
X-API-Key: fss_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The request body wraps the invoice data inside an invoice_data object. Two payload variants are supported: with and without HS Code on line items.

04

Payload Example (with HS Code)

Use this payload structure when HS Codes are applicable to your line items:

{
  "device_id": 32229,
  "invoice_data": {
    "invoiceNumber": "JSX-10145",
    "invoiceType": "invoice",
    "currency": "USD",
    "total": 979,
    "lineItems": [
      {
        "hscode": "00000000",
        "description": "Joe's A-Mouse",
        "quantity": 1,
        "unitPrice": 900,
        "total": 900,
        "vatRate": "Standard"
      },
      {
        "hscode": "00000000",
        "description": "Mouse",
        "quantity": 2,
        "unitPrice": 15,
        "total": 30,
        "vatRate": "Standard"
      },
      {
        "hscode": "00000000",
        "description": "Sticker",
        "quantity": 5,
        "unitPrice": 1,
        "total": 5,
        "vatRate": "Zero"
      },
      {
        "hscode": "00000000",
        "description": "Gift Card",
        "quantity": 1,
        "unitPrice": 20,
        "total": 20,
        "vatRate": "Exempt"
      },
      {
        "hscode": "00000000",
        "description": "USB-C Cable",
        "quantity": 3,
        "unitPrice": 8,
        "total": 24,
        "vatRate": "Standard"
      }
    ],
    "buyerData": {
      "buyerRegisterName": "ACME Trading",
      "buyerTIN": "2001239444",
      "vatNumber": "220006909",
      "buyerName": "Acme Corp",
      "buyerTradeName": "Acme",
      "email": "accounts@acme.com",
      "phoneNo": "+123456789",
      "province": "Harare",
      "city": "Harare",
      "street": "1 Main St",
      "houseNo": "10",
      "district": "CBD"
    }
  }
}
05

Payload Example (without HS Code)

When HS Codes are not applicable, simply omit the hscode field from line items:

{
  "device_id": 33719,
  "invoice_data": {
    "invoiceNumber": "JXX-10145",
    "invoiceType": "invoice",
    "currency": "USD",
    "total": 979.0,
    "lineItems": [
      { "description": "Joe's A-Mouse",   "quantity": 1, "unitPrice": 900.0, "total": 900.0, "vatRate": "Standard" },
      { "description": "Mouse",      "quantity": 2, "unitPrice": 15.0,  "total": 30.0,  "vatRate": "Standard" },
      { "description": "Sticker",    "quantity": 5, "unitPrice": 1.0,   "total": 5.0,   "vatRate": "Zero" },
      { "description": "Gift Card",  "quantity": 1, "unitPrice": 20.0,  "total": 20.0,  "vatRate": "Exempt" },
      { "description": "USB-C Cable","quantity": 3, "unitPrice": 8.0,   "total": 24.0,  "vatRate": "Standard" }
    ],
    "buyerData": {
      "buyerRegisterName": "ACME Trading",
      "buyerTIN": "2001239444",
      "vatNumber": "220006909",
      "buyerName": "Acme Corp",
      "buyerTradeName": "Acme",
      "email": "accounts@acme.com",
      "phoneNo": "+123456789",
      "province": "Harare",
      "city": "Harare",
      "street": "1 Main St",
      "houseNo": "10",
      "district": "CBD"
    }
  }
}
06

Invoice Data Fields

The invoice_data object contains the full transaction details:

FieldTypeRequiredDescription
invoiceNumberStringYesUnique invoice or note number from the client system
invoiceTypeStringYesTransaction type: Invoice, CreditNote, or DebitNote
currencyStringYesTransaction currency, e.g. USD
notesStringConditionalRequired for credit/debit notes to explain the reason
referenceInvoiceStringNoOriginal invoice reference for credit/debit notes
totalDecimalYesTotal invoice amount; must equal sum of all line item totals
lineItemsArrayYesList of goods or services in the transaction
buyerDataObjectNoBuyer details for the transaction
07

Line Items Structure

The lineItems array contains the detailed breakdown of the invoice:

FieldTypeRequiredDescription
descriptionStringYesDescription of the item or service
quantityDecimalYesQuantity sold
unitPriceDecimalYesUnit price of the item
totalDecimalYesTotal line amount (must equal quantity x unitPrice)
vatRateStringYesVAT classification: Standard, Zero, or Exempt
hscodeStringNoHarmonised System code (when applicable)

Validation rule: Each line item total must equal quantity x unitPrice.

08

Buyer Data Structure

The buyerData object holds customer information:

FieldTypeRequiredDescription
buyerRegisterNameStringYesRegistered legal name of the buyer
buyerTINStringYesBuyer tax ID, must be exactly 10 digits
vatNumberStringNoBuyer VAT number, must be exactly 9 digits
buyerNameStringNoBuyer display name
buyerTradeNameStringNoBuyer trade name
emailStringNoBuyer email (must contain @ and valid domain)
phoneNoStringNoBuyer phone number
provinceStringNoBuyer province
cityStringNoBuyer city
streetStringNoBuyer street address
houseNoStringNoBuyer house number
districtStringNoBuyer district
09

Invoice Type Rules

The invoiceType field determines how the transaction is interpreted by the API. Accepted values include:

  • Invoice
  • CreditNote
  • DebitNote

The API accepts these values in any letter casing (invoice, INVOICE, Invoice).

For CreditNote and DebitNote transactions:

  • notes should be provided to explain the reason for adjustment
  • referenceInvoice is mandatory where the transaction relates to a previously issued invoice
10

VAT Rate Values

The vatRate field indicates the VAT category applicable to each line item. Supported values:

  • Standard - Standard VAT rate applies
  • Zero - Zero-rated goods or services
  • Exempt - VAT-exempt items
11

Submission Responses

Success (HTTP 202):

{
  "success": true,
  "job_id": 32,
  "message": "Invoice received. Processing has been queued."
}

Failure (HTTP 404):

{
  "success": false,
  "detail": "Device with device_id '33308' not found or does not belong to entity inferred."
}
12

Synchronous Submission

For clients that cannot use the asynchronous submit-and-poll workflow, a synchronous endpoint is available. This endpoint processes the invoice immediately and returns the full result in the same response — no polling required.

Important: This endpoint is subject to additional moderation and requires technical consultation and review before access is granted. This ensures platform resources remain available to all clients. Devices configured to use the synchronous endpoint will incur additional costs, as maintaining synchronous processing without queueing through the standard asynchronous method requires dedicated resource allocation. Please contact support to discuss enablement for your account.

POST /api/converter/invoices/submit-synchronous/

Headers:

Content-Type: application/json
X-API-Key: fss_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The request body uses the same structure as the asynchronous endpoint — wrap the invoice data inside an invoice_data object. The same payload examples above apply.

Success (HTTP 200):

{
  "success": true,
  "job_id": 32,
  "invoice_number": "JXX-10145",
  "processing_status": "completed",
  "invoice": {
    "invoice_number": "JXX-10145",
    "processing_status": "done",
    "processing_status_human": "Done",
    "posted_status": true,
    "validation_status": "unvalidated",
    "error_message": null,
    "qr_url": "https://fdmstest.zimra.co.zw/Receipt/Result?...",
    "result_file": null,
    "fiscal_day_no": 1,
    "zimra": {
      "invoiceNum": "JXX-10145",
      "invoiceType": "invoice",
      "referenceNum": 1,
      "fiscalDayNum": 1,
      "deviceSerialNum": "DT000000033719",
      "fiscalDeviceId": "33719",
      "invoiceDate": "2026-07-27T10:00:00.000000+00:00",
      "verificationCode": "e91a-6b9e-78a0-e2be",
      "qrCodeURL": "https://fdmstest.zimra.co.zw/Receipt/Result?..."
    }
  }
}

Processing Failed (HTTP 200):

{
  "success": false,
  "job_id": 33,
  "processing_status": "failed",
  "detail": "Device has no DeviceConfiguration; please configure device first",
  "error_message": "Device has no DeviceConfiguration; please configure device first"
}

Sync Endpoint Not Enabled (HTTP 403):

{
  "success": false,
  "detail": "Synchronous endpoint access is not enabled for this device. Contact your administrator to enable the Synchronous Endpoint toggle in the device configuration."
}

Note: Because this endpoint processes synchronously, the response may take longer than the async endpoint (typically 1–5 seconds). If the invoice is still processing (e.g. queued for retry), a 202 status is returned with the job status — use the async status endpoint to check the final result.

13

Invoice Status Endpoint

Check the processing state of a previously submitted invoice. Useful for transaction monitoring, troubleshooting, and reconciliation.

GET https://api.fiscalsupportservices.com/api/converter/invoices/<invoice_number>/status/

Headers:

X-API-Key: fss_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Response (HTTP 200):

{
  "invoice_number": "JXX-10145",
  "processing_status": "done",
  "processing_status_human": "Done",
  "posted_status": true,
  "validation_status": "unvalidated",
  "error_message": null,
  "qr_url": "https://fdmstest.zimra.co.zw/Receipt/Result?...",
  "result_file": null,
  "fiscal_day_no": 1,
  "zimra": {
    "invoiceNum": "JXX-10145",
    "invoiceType": null,
    "referenceNum": 1,
    "fiscalDayNum": 1,
    "deviceSerialNum": null,
    "fiscalDeviceId": "33719",
    "invoiceDate": "2026-03-20T13:37:37.965390+00:00",
    "verificationURL": null,
    "verificationCode": null,
    "qrCodeURL": "https://fdmstest.zimra.co.zw/Receipt/Result?..."
  }
}
14

List Processed Invoices

Returns a list of all invoices that have been successfully processed (processing_status = "done") for the device associated with your API key. Useful for building dashboards or synchronising invoice records.

GET https://api.fiscalsupportservices.com/api/converter/invoices/

Headers:

X-API-Key: fss_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Response (HTTP 200):

{
  "success": true,
  "count": 2,
  "invoices": [
    {
      "invoice_number": "INV-20260614-001",
      "processing_status": "done",
      "processed_at": "2026-06-14T10:32:15.123456+00:00",
      "uploaded_at": "2026-06-14T10:31:02.789012+00:00"
    },
    {
      "invoice_number": "INV-20260614-002",
      "processing_status": "done",
      "processed_at": "2026-06-14T10:35:48.654321+00:00",
      "uploaded_at": "2026-06-14T10:34:55.321098+00:00"
    }
  ]
}
15

Invoice Details by Number

Retrieve the full invoice record for a specific invoice number, including fiscal data, ZIMRA response fields, QR code URL, verification code, and the original submitted payload.

GET https://api.fiscalsupportservices.com/api/converter/invoices/<invoice_number>/details/

Headers:

X-API-Key: fss_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Response (HTTP 200):

{
  "success": true,
  "invoice": {
    "id": 145,
    "invoice_number": "INV-20260614-001",
    "processing_status": "done",
    "processing_status_human": "Done",
    "posted_status": true,
    "validation_status": "unvalidated",
    "error_message": null,
    "input_type": "json",
    "uploaded_at": "2026-06-14T10:31:02.789012+00:00",
    "processed_at": "2026-06-14T10:32:15.123456+00:00",
    "fiscal_day_no": 42,
    "rcpt_counter": 15,
    "rcpt_global": 1042,
    "rcpt_hash": "a1b2-c3d4-e5f6-a7b8",
    "qr_url": "https://fdmstest.zimra.co.zw/Receipt/Result?...",
    "result_file": "https://api.fiscalsupportservices.com/media/invoices/...",
    "pdf_file": null,
    "entity": {
      "id": 12,
      "name": "ACME Trading Pvt Ltd"
    },
    "device": {
      "id": 33308,
      "device_sn": "FS-XXXX-001",
      "device_id": "33719"
    },
    "invoice_payload": {
      "invoiceNumber": "INV-20260614-001",
      "invoiceType": "Invoice",
      "currency": "USD",
      "total": 250.00,
      "lineItems": [...],
      "buyerData": {...}
    }
  }
}
16

Fiscal Days List

Lists fiscal day records for a device. Use this endpoint to discover the fiscal_day_record_id values needed for daily report requests.

GET https://api.fiscalsupportservices.com/api/device/<device_id>/fiscal-days/

Headers:

X-API-Key: fss_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The device_id path parameter can be the public device ID (e.g. PRDTEST-006) or the internal integer device ID.

Example request (cURL):

curl -X GET \
  "https://api.fiscalsupportservices.com/api/device/33719/fiscal-days/" \
  -H "X-API-Key: fss_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Success response (HTTP 200):

{
  "device_id": "33719",
  "count": 3,
  "fiscal_days": [
    {
      "id": 42,
      "fiscal_day_no": 42,
      "status": "closed",
      "opened_at": "2026-03-15T08:00:00.123456+00:00",
      "closed_at": "2026-03-15T18:30:00.789012+00:00"
    },
    {
      "id": 41,
      "fiscal_day_no": 41,
      "status": "closed",
      "opened_at": "2026-03-14T08:00:00.123456+00:00",
      "closed_at": "2026-03-14T18:15:00.789012+00:00"
    },
    {
      "id": 40,
      "fiscal_day_no": 40,
      "status": "open",
      "opened_at": "2026-03-16T08:00:00.123456+00:00",
      "closed_at": null
    }
  ]
}

Use the id field from each record as the fiscal_day_record_id in the daily report request. Records are returned ordered by fiscal_day_no descending (most recent first), up to 100 records.

Device not found (HTTP 404):

{
  "detail": "Device not found or not accessible."
}
17

Z-Report Request

Request a Z-Report (fiscal report) for a specific device. This endpoint validates your payload and returns a normalised report_id plus a download URL that you can use to fetch the generated PDF report.

POST https://api.fiscalsupportservices.com/api/device/<device_id>/report-request/

Headers:

Content-Type: application/json
X-API-Key: fss_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The device_id path parameter can be the public device ID (e.g. PRDTEST-006) or the internal integer device ID.

Resolving fiscal_day_record_id for daily reports: Call GET /api/device/<device_id>/fiscal-days/ to list fiscal day records for the device. Use the id field from the desired record as the fiscal_day_record_id.

Request body fields:

FieldTypeRequiredDescription
report_kindStringYesReport type: daily, monthly, annual, daily-date, or custom
fiscal_day_record_idIntegerWhen report_kind=dailyID of the fiscal day record to summarise
monthStringWhen report_kind=monthlyMonth in YYYY-MM format (e.g. 2026-03)
yearIntegerWhen report_kind=annualYear (e.g. 2026)
report_dateStringWhen report_kind=daily-dateDate in YYYY-MM-DD format (e.g. 2026-03-15)
start_dateStringWhen report_kind=customStart date in YYYY-MM-DD format
end_dateStringWhen report_kind=customEnd date in YYYY-MM-DD format

Example — Daily report (by fiscal day record):

{
  "report_kind": "daily",
  "fiscal_day_record_id": 42
}

Example — Monthly report:

{
  "report_kind": "monthly",
  "month": "2026-03"
}

Example — Annual report:

{
  "report_kind": "annual",
  "year": 2026
}

Example — Daily report (by calendar date):

{
  "report_kind": "daily-date",
  "report_date": "2026-03-15"
}

Example — Custom date range report:

{
  "report_kind": "custom",
  "start_date": "2026-03-01",
  "end_date": "2026-03-31"
}

Success response (HTTP 202):

{
  "status": "accepted",
  "device_id": "33719",
  "device_pk": 12,
  "report_id": "monthly:2026-03",
  "report_kind": "monthly",
  "report_title": "Monthly Breakdown",
  "period_label": "March 2026",
  "download_url": "/api/device/33719/reports/monthly:2026-03/download/",
  "summary": {
    "document_count": 145,
    "posted_count": 140,
    "failed_count": 5,
    "qr_url_count": 140,
    "qr_missing_count": 5,
    "document_types": ["FiscalInvoice"],
    "currencies": ["USD"],
    "invoice_total": 45230.50,
    "vat_total": 6784.58,
    "totals_by_currency": {"USD": 45230.50},
    "vat_by_currency": {"USD": 6784.58},
    "qr_verification_urls": [
      {"invoice_number": "INV-001", "qr_url": "https://fdmstest.zimra.co.zw/Receipt/Result?..."}
    ]
  },
  "invoices": [
    {
      "invoice_number": "INV-20260315-001",
      "processing_status": "done",
      "posted_status": true,
      "fiscal_day_no": 42,
      "processed_at": "2026-03-15T10:32:15.123456+00:00",
      "uploaded_at": "2026-03-15T10:31:02.789012+00:00",
      "qr_url": "https://fdmstest.zimra.co.zw/Receipt/Result?..."
    },
    {
      "invoice_number": "INV-20260315-002",
      "processing_status": "done",
      "posted_status": true,
      "fiscal_day_no": 42,
      "processed_at": "2026-03-15T11:05:48.654321+00:00",
      "uploaded_at": "2026-03-15T11:04:55.321098+00:00",
      "qr_url": "https://fdmstest.zimra.co.zw/Receipt/Result?..."
    }
  ]
}

The response now includes the full report data in JSON format:

  • summary — aggregate metrics: document count, posted/failed counts, invoice and VAT totals broken down by currency, QR verification URLs
  • invoices — array of individual invoice records (up to 1000) with invoice number, processing status, posted status, fiscal day number, timestamps, and QR URL
  • download_url — use this to download the PDF version of the same report

Validation error (HTTP 400):

{
  "report_kind": ["This field is required."]
}
{
  "fiscal_day_record_id": ["This field is required for daily reports."]
}

Device not found (HTTP 404):

{
  "detail": "Device not found or not accessible."
}
18

Z-Report Download

Download the generated PDF report using the report_id obtained from the report request endpoint. The response is a binary PDF file.

GET https://api.fiscalsupportservices.com/api/device/<device_id>/reports/<report_id>/download/

Headers:

X-API-Key: fss_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The report_id is the normalised value returned by the report request endpoint. Examples:

  • daily:42 — Fiscal day record ID 42
  • monthly:2026-03 — March 2026
  • annual:2026 — Full year 2026
  • daily-date:2026-03-15 — All invoices on 15 March 2026
  • custom:2026-03-01:2026-03-31 — Custom range from 1 to 31 March 2026

Example request (cURL):

curl -X GET \
  "https://api.fiscalsupportservices.com/api/device/33719/reports/monthly:2026-03/download/" \
  -H "X-API-Key: fss_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -o z-report-2026-03.pdf

Success response (HTTP 200):

Content-Type: application/pdf
Content-Disposition: attachment; filename="Monthly-Breakdown-2026-03.pdf"

(binary PDF data)

The PDF contains a summary of all invoices for the requested period, including:

  • Device information and entity details
  • Invoice count, posted count, and failed count
  • Total invoice value and VAT breakdown by currency
  • Individual invoice listings with invoice numbers, dates, and QR verification URLs

Report not found (HTTP 404):

{
  "detail": "Report not found"
}

Unsupported report type (HTTP 400):

{
  "detail": "Unsupported report type"
}

Report generation unavailable (HTTP 500):

{
  "detail": "Report generation is not available"
}
19

Report Types Reference

The following report types are supported by the report request and download endpoints:

report_kindreport_id formatRequired fieldsDescription
dailydaily:<id>fiscal_day_record_idFiscal day summary (Z-Report) for a specific fiscal day record
monthlymonthly:<YYYY-MM>monthAll invoices for a given calendar month
annualannual:<YYYY>yearAll invoices for a given calendar year
daily-datedaily-date:<YYYY-MM-DD>report_dateAll invoices processed on a specific calendar date
customcustom:<start>:<end>start_date, end_dateAll invoices within a custom date range (inclusive)

Typical workflow:

  • Call POST /api/device/<device_id>/report-request/ with the desired report_kind and parameters
  • Extract the report_id and download_url from the response
  • Call GET /api/device/<device_id>/reports/<report_id>/download/ to download the PDF
  • Save or display the PDF as needed

Note: You can also construct the report_id manually using the formats above and skip the request step, calling the download endpoint directly.

20

Error Codes and Handling

When integrating with the FSS API, your application should handle the following error responses. All errors return a JSON body with a detail or success: false field describing the issue.

HTTP StatusErrorCause and Recommended Action
400Bad RequestMissing or invalid required fields. Validate payload structure before submitting. Ensure invoice_data is present and all required fields are populated.
401AuthenticationFailedAPI key is missing, invalid, or revoked. Verify the X-API-Key header is correct. Contact FSS support if the key needs to be reissued.
403PermissionDeniedAuthentication is valid but the consumer does not have access to the requested entity or device. Ensure the API key is associated with the correct entity/device.
404Not FoundThe requested invoice number, device, or entity was not found, or the authenticated consumer does not have access to it. Verify the invoice number or device_id is correct.
429ThrottledRate limit exceeded. The API consumer has exceeded the maximum requests per hour or per day. Implement exponential backoff and retry. Contact FSS to increase limits if needed.
500Internal Server ErrorAn unexpected error occurred on the server. Retry the request after a brief delay. If the error persists, contact FSS support with the job_id or invoice number.

Processing errors (invoice-level):

Even when the submission itself succeeds (HTTP 202), the invoice may encounter errors during processing. These are reflected in the invoice status response:

  • processing_status: "error" - The invoice failed during processing. Check the error_message field for details.
  • processing_status: "skipped" - The invoice was skipped (e.g. duplicate submission or validation failure).
  • processing_status: "pending" - The invoice is queued but has not yet been picked up by a worker.
  • processing_status: "processing" - The invoice is currently being processed.
  • processing_status: "done" - Processing completed successfully.

Recommended automation pattern:

  • Submit the invoice and capture the job_id
  • Poll the status endpoint every 5-10 seconds until processing_status is "done" or "error"
  • On "error", log the error_message and trigger an alert or retry workflow
  • On "done", verify posted_status is true to confirm ZIMRA submission succeeded
21

Rate Limiting

API consumers are subject to rate limits to ensure fair usage and platform stability:

  • Default: 1,000 requests per hour, 10,000 requests per day
  • Limits are configurable per consumer and can be increased based on your integration needs
  • When the limit is exceeded, a 429 Throttled response is returned
  • Implement exponential backoff: wait 2s, then 4s, then 8s before retrying

Contact FSS support to request increased rate limits for high-volume integrations.

22

Contact and Support

For API access, integration support, or to report issues:

Fiscal Support Services
36 East Road, Belgravia, Harare, Zimbabwe
Branch Office: 209 Yorkhouse Building, 8th Ave, Cnr Herbert Chitepo, Bulawayo
Email: supporthre@fiscalsupportservices.com
Phone: +263 242 703360/371
WhatsApp: +263 780 526 944
Website: fiscalsupportservices.co.zw