POSfix API Reference
Overview
The POSfix API Server runs locally on the POS device and exposes a REST API on port 4567 (HTTP). It allows an external ERP system to perform fiscal operations — sales, cash-in/cash-out, Z/X reports, periodic reports, and queries — directly on the POS terminal over the local network.
Base URL: http://<device-ip>:4567
Quick Start
- Ensure the POS device and ERP are on the same local network.
- Obtain the device IP from
Settings > Hardwareon the POS app, or from the health endpoint. - Obtain your API Key from the POSfix cloud dashboard.
- Verify connectivity:
GET http://<device-ip>:4567/api/health - Start making fiscal operations with the
X-API-Keyheader.
Authentication
All endpoints (except /api/health) require the X-API-Key header.
X-API-Key: your-api-key-here
The API key is provisioned through the POSfix cloud platform and is unique per terminal.
Missing key → 401 MISSING_API_KEY
Invalid key → 401 INVALID_API_KEY
Response Format
Every response follows this envelope:
{
"success": true,
"data": { ... },
"error": null,
"timestamp": "2026-02-16T12:00:00.000Z"
}
On error:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable description",
"details": [ ... ]
},
"timestamp": "2026-02-16T12:00:00.000Z"
}
| Field | Type | Description |
|---|---|---|
success | boolean | true if the operation succeeded |
data | object | null | Response payload (null on error) |
error | object | null | Error info (null on success) |
error.code | string | Machine-readable error code |
error.message | string | Human-readable error message |
error.details | array | null | Validation error details (field-level) |
timestamp | string | ISO 8601 UTC timestamp |
Endpoints
1. Health & Status
GET /api/health
Check server status. No authentication required.
Returns the app version, fiscal status, terminal ID, device IP, and uptime.
Response fields:
| Field | Type | Description |
|---|---|---|
status | string | Server state: "ready" |
version | string | App version (e.g. "1.0.1+5") |
fiscalStatus | string | Fiscal status: "online", "offline", "not_fiscal" |
terminalId | string | Terminal identifier |
serverPort | int | Listening port (4567) |
uptime | int | Server uptime in seconds |
serverStartedAt | string | ISO 8601 timestamp when server started |
deviceIp | string | Device IP address on local network |
Example response:
{
"success": true,
"data": {
"status": "ready",
"version": "1.0.1+5",
"fiscalStatus": "online",
"terminalId": "T-12345",
"serverPort": 4567,
"uptime": 3600,
"serverStartedAt": "2026-02-16T10:00:00.000Z",
"deviceIp": "192.168.1.50"
},
"error": null,
"timestamp": "2026-02-16T12:00:00.000Z"
}
2. Sales
POST /api/sales
Create a new sale. Performs fiscal registration with MEV (tax authority), prints receipt, and optionally delivers receipt via SMS/email.
Request body:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
items | array | Yes | — | Array of sale items (at least 1) |
items[].id | string | No | null | External product ID from ERP. If omitted, sync payload will contain null |
items[].name | string | Yes | — | Product name (1-100 characters) |
items[].unitPrice | number | Yes | — | Unit price (must be > 0) |
items[].quantity | number | Yes | — | Quantity (must be > 0). Decimals allowed if allowDecimals: true |
items[].vatCode | string | Yes | — | VAT code: A, B, C, D, E, or _ |
items[].discountPercent | number | No | 0 | Item-level discount percentage (0-100) |
items[].allowDecimals | boolean | No | false | Allow fractional quantities (e.g. 0.750 kg) |
cartDiscount | object | No | null | Cart-level discount |
cartDiscount.percent | number | Yes | — | Cart discount percentage (0-100) |
payments | array | Yes | — | Array of payments (at least 1) |
payments[].type | string | Yes | — | ACPS payment type code (see Payment Types) |
payments[].amount | number | Yes | — | Payment amount |
payments[].rrn | string | No | null | Retrieval Reference Number (for card payments) |
amountReceived | number | Yes | — | Total amount received from customer |
change | number | Yes | — | Change returned to customer |
delivery | object | No | null | Receipt delivery options (SMS/email) |
delivery.customerPhone | string | No | null | Phone number for SMS delivery (format: +XXXXXXXXXXX) |
delivery.customerEmail | string | No | null | Email for receipt delivery |
delivery.customerName | string | No | null | Customer name (max 60 chars) |
delivery.language | string | No | "ro" | Language for receipt: "ro", "en", "ru" |
printReceipt | boolean | No | true | Print receipt on POS printer |
Response fields:
| Field | Type | Description |
|---|---|---|
saleId | string | Local sale UUID |
purchaseId | string | Server-side purchase ID |
serverSaleId | string | Server-side sale ID |
fiscalOperationId | string | Fiscal operation UUID |
receiptNumber | int | Sequential receipt number within current Z report |
reportNumber | int | Current Z report number |
fiscalCode | string | Fiscal code from MEV |
mevId | string | null | MEV transaction ID (null if offline) |
isOffline | boolean | true if MEV was unreachable (offline fiscal receipt) |
offlineFiscalCode | string | null | Offline fiscal code (when operating offline) |
total | number | Final sale total (after discounts) |
subtotal | number | Subtotal before cart discount |
amountReceived | number | Amount received from customer |
change | number | Change returned |
vatBreakdown | object | Per-VAT-code breakdown (see VAT Breakdown) |
paymentBreakdown | array | Array of { type, amount } objects |
qrCodeData | string | QR code URL for receipt verification |
mevResponseXml | string | SOAP XML response from MEV |
receiptDelivery | object | null | { smsSent, emailSent } — indicates delivery was requested, not confirmed |
createdAt | string | ISO 8601 timestamp |
Example — Simple sale (1 item, cash):
// Request
POST /api/sales
{
"items": [
{
"name": "Cafea espresso",
"unitPrice": 45.00,
"quantity": 1,
"vatCode": "B"
}
],
"payments": [
{ "type": "1", "amount": 45.00 }
],
"amountReceived": 45.00,
"change": 0,
"printReceipt": true
}
// Response 200
{
"success": true,
"data": {
"saleId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"purchaseId": "server-purchase-001",
"serverSaleId": "server-sale-001",
"fiscalOperationId": "fiscal-op-001",
"receiptNumber": 1,
"reportNumber": 1,
"fiscalCode": "MEV-TXN-001",
"mevId": "MEV-TXN-001",
"isOffline": false,
"offlineFiscalCode": null,
"total": 45.00,
"subtotal": 45.00,
"amountReceived": 45.00,
"change": 0.00,
"vatBreakdown": {
"B": {
"code": "B",
"percent": 20.0,
"vatAmount": 7.50,
"taxableBase": 37.50,
"totalWithVat": 45.00
}
},
"paymentBreakdown": [
{ "type": "1", "amount": 45.00 }
],
"qrCodeData": "https://sift-mev.sfs.md/verify?id=MEV-TXN-001",
"mevResponseXml": "<?xml version=\"1.0\"?><soap:Envelope>...</soap:Envelope>",
"receiptDelivery": null,
"createdAt": "2026-02-16T12:00:00.000Z"
},
"error": null,
"timestamp": "2026-02-16T12:00:00.000Z"
}
Example — Complex sale (multiple items, mixed payments, discounts, delivery):
// Request
POST /api/sales
{
"items": [
{
"id": "prod-001",
"name": "Cafea espresso",
"unitPrice": 45.00,
"quantity": 2,
"vatCode": "B"
},
{
"name": "Tort Napoleon (kg)",
"unitPrice": 180.00,
"quantity": 0.750,
"vatCode": "B",
"discountPercent": 10.0,
"allowDecimals": true
},
{
"name": "Apa minerala 0.5L",
"unitPrice": 15.00,
"quantity": 3,
"vatCode": "B"
}
],
"cartDiscount": {
"percent": 5.0
},
"payments": [
{ "type": "1", "amount": 200.00 },
{ "type": "2", "amount": 50.00, "rrn": "123456789012" }
],
"amountReceived": 250.00,
"change": 0,
"delivery": {
"customerPhone": "+37369123456",
"customerEmail": "client@email.com",
"customerName": "Vasile Munteanu",
"language": "ro"
},
"printReceipt": true
}
Validation errors return HTTP 400 with field-level details:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "items[0].name",
"code": "ITEM_NAME_INVALID",
"message": "Item name must be 1-100 characters"
},
{
"field": "items[0].unitPrice",
"code": "ITEM_PRICE_INVALID",
"message": "Unit price must be greater than 0"
}
]
},
"timestamp": "2026-02-16T12:00:00.000Z"
}
GET /api/sales
List sales with date range filtering and pagination.
Query parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
dateFrom | string | No | — | Start date (ISO: YYYY-MM-DD) |
dateTo | string | No | — | End date (ISO: YYYY-MM-DD) |
limit | int | No | 50 | Max results per page |
offset | int | No | 0 | Pagination offset |
Response fields:
| Field | Type | Description |
|---|---|---|
sales | array | Array of sale summaries |
sales[].id | string | Sale UUID |
sales[].purchaseId | string | Server purchase ID |
sales[].serverSaleId | string | Server sale ID |
sales[].fiscalOperationId | string | Fiscal operation UUID |
sales[].cashierId | string | Cashier ID |
sales[].cashierName | string | Cashier name |
sales[].subtotal | number | Subtotal amount |
sales[].total | number | Total amount |
sales[].paymentType | string | Primary payment type label |
sales[].paymentAmount | number | Amount paid |
sales[].changeAmount | number | Change returned |
sales[].status | string | Sync status |
sales[].createdAt | string | ISO 8601 timestamp |
total | int | Total number of matching sales |
limit | int | Applied limit |
offset | int | Applied offset |
Example:
GET /api/sales?dateFrom=2026-02-01&dateTo=2026-02-16&limit=50&offset=0
GET /api/sales/{saleId}
Get full details of a specific sale including items, payments, and fiscal operation data.
Path parameters:
| Parameter | Type | Description |
|---|---|---|
saleId | string | Sale UUID |
Response includes:
| Section | Description |
|---|---|
items[] | Product details: productId, productName, quantity, unitPrice, originalPrice, discountAmount, markupAmount, netAmount, vatCode, vatPercent, vatAmount |
payments[] | Payment details: paymentType, amount, notes |
fiscalOperation | Fiscal data: mevId, receiptNumber, reportNumber, status, isOffline, mevResponseXml, qrCodeData |
Error: 404 SALE_NOT_FOUND if the sale ID doesn't exist.
3. Cash Operations
POST /api/cash/in
Deposit cash into the register. Creates a fiscal service receipt sent to MEV.
Request body:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
amount | number | Yes | — | Amount to deposit (must be > 0) |
reason | string | No | null | Reason for the deposit |
printReceipt | boolean | No | true | Print service receipt |
Response fields:
| Field | Type | Description |
|---|---|---|
operationId | string | Operation UUID |
fiscalOperationId | string | Fiscal operation UUID |
receiptNumber | int | Service receipt number |
reportNumber | int | Current Z report number |
mevId | string | null | MEV transaction ID |
isOffline | boolean | Whether operation was offline |
amount | number | Deposited amount |
newBalance | number | New cash balance |
operationType | string | "cashIn" |
mevResponseXml | string | SOAP response XML |
createdAt | string | ISO 8601 timestamp |
Example:
// Request
POST /api/cash/in
{
"amount": 500.00,
"reason": "Depunere inceput zi",
"printReceipt": true
}
// Response 200
{
"success": true,
"data": {
"operationId": "op-uuid-001",
"fiscalOperationId": "fiscal-op-003",
"receiptNumber": 1,
"reportNumber": 1,
"mevId": "MEV-SVC-001",
"isOffline": false,
"amount": 500.00,
"newBalance": 500.00,
"operationType": "cashIn",
"mevResponseXml": "...",
"createdAt": "2026-02-16T08:00:00.000Z"
}
}
POST /api/cash/out
Withdraw cash from the register. Verifies sufficient balance before proceeding.
Request body:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
amount | number | Yes | — | Amount to withdraw (must be > 0) |
reason | string | No | null | Reason for the withdrawal |
printReceipt | boolean | No | true | Print service receipt |
Response fields: Same as cash-in, with operationType: "cashOut".
Error: 409 INSUFFICIENT_CASH_BALANCE if the current balance is less than the requested amount.
{
"success": false,
"error": {
"code": "INSUFFICIENT_CASH_BALANCE",
"message": "Cash balance (300.00) is insufficient for withdrawal of 500.00"
}
}
4. Reports
POST /api/reports/z
Generate a Z Report — closes the fiscal day.
This is an irreversible operation. It resets receipt counters and increments the report number.
Request body:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
printReport | boolean | No | true | Print the report |
Requires: Terminal must be fiscalized and have valid MEV credentials.
Response fields:
| Field | Type | Description |
|---|---|---|
reportNumber | int | Z report number |
operationId | string | Fiscal operation UUID |
mevId | string | null | MEV transaction ID |
isOffline | boolean | Whether operation was offline |
reportData | object | Full report data (see Report Data below) |
mevResponseXml | string | SOAP XML response from MEV |
generatedAt | string | ISO 8601 timestamp |
Report Data object:
| Field | Type | Description |
|---|---|---|
reportNumber | int | Z report number |
dailyTotal | number | Total sales for the day |
dailyTax | number | Total VAT for the day |
dailyUntaxed | number | Untaxed amount |
vatBreakdown | object | Per-VAT-code breakdown |
receiptsIssued | int | Number of receipts issued |
lastReceiptNumber | int | Last receipt number |
receiptsSentToMev | int | Receipts successfully sent to MEV |
paymentTotals | object | Amount per ACPS payment type code (e.g. { "1": 3000.00, "2": 2000.00 }) |
paymentCounts | object | Count per ACPS payment type code (e.g. { "1": 25, "2": 17 }) |
cashIn | number | Total cash deposits |
cashOut | number | Total cash withdrawals |
cashBalance | number | Current cash balance |
yearTotal | number | null | Cumulative yearly total (Z only) |
yearTax | number | null | Cumulative yearly tax (Z only) |
totalSales | number | Total gross sales |
totalReturns | number | Total returns amount |
returnsCount | int | Number of return operations |
cashInCount | int | Number of cash-in operations |
cashOutCount | int | Number of cash-out operations |
generatedAt | string | ISO 8601 timestamp |
POST /api/reports/x
Generate an X Report — intermediate fiscal day snapshot.
Does NOT reset any counters. Same request/response structure as Z Report.
POST /api/reports/periodic
Generate a Periodic Report — aggregated data across multiple Z reports.
This is a local report only (not sent to MEV). Supports two mutually exclusive filter modes.
Request body:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
dateFrom | string | Conditional | — | Start date (ISO: YYYY-MM-DD). Required for date range mode |
dateTo | string | Conditional | — | End date (ISO: YYYY-MM-DD). Required for date range mode |
reportFrom | int | Conditional | — | Starting Z report number. For report range mode |
reportTo | int | Conditional | — | Ending Z report number. For report range mode |
detailed | boolean | No | false | Include individual Z report breakdown |
printReport | boolean | No | true | Print the report on POS printer |
Filter modes (mutually exclusive — provide one set):
- Date range:
dateFrom+dateTo - Report number range:
reportFromand/orreportTo(both optional — omitreportFromto start from Z#1, omitreportTofor latest)
Response fields:
| Field | Type | Description |
|---|---|---|
filterMode | string | "dateRange" or "reportRange" |
dateFrom | string | Start date (YYYY-MM-DD) |
dateTo | string | End date (YYYY-MM-DD) |
reportFrom | int | (report range only) Starting Z report number |
reportTo | int | (report range only) Ending Z report number |
totalSales | number | Aggregated total sales |
totalTax | number | Aggregated total VAT |
totalUntaxed | number | Aggregated untaxed amount |
vatBreakdown | object | Per-VAT-code aggregated breakdown |
receiptsCount | int | Total receipts across all Z reports |
paymentTotals | object | Aggregated payment totals by type |
cashIn | number | Total cash deposits |
cashOut | number | Total cash withdrawals |
cashInCount | int | Number of cash-in operations |
cashOutCount | int | Number of cash-out operations |
zReportsCount | int | Number of Z reports in range |
xReportsCount | int | Number of X reports in range |
firstZReportNumber | int | First Z report number in range |
lastZReportNumber | int | Last Z report number in range |
firstZReportTimestamp | string | First Z report close timestamp |
lastZReportTimestamp | string | Last Z report close timestamp |
totalReturns | number | Aggregated returns |
returnsCount | int | Number of return operations |
individualZReports | array | null | Per-Z breakdown (when detailed: true) |
generatedAt | string | ISO 8601 timestamp |
Individual Z Report fields (when detailed: true):
| Field | Type | Description |
|---|---|---|
reportNumber | int | Z report number |
closedAt | string | ISO 8601 timestamp when Z was closed |
firstReceiptNumber | int | First receipt number in this Z |
lastReceiptNumber | int | Last receipt number in this Z |
receiptsCount | int | Number of receipts |
totalSales | number | Total sales for this Z |
totalTax | number | Total VAT for this Z |
vatBreakdown | object | VAT breakdown for this Z |
paymentTotals | object | Payment totals by type |
cashIn | number | Cash deposits in this Z |
cashOut | number | Cash withdrawals in this Z |
Example — Summary by date range:
// Request
POST /api/reports/periodic
{
"dateFrom": "2026-02-01",
"dateTo": "2026-02-16",
"detailed": false,
"printReport": true
}
Example — Summary by Z report number range:
// Request
POST /api/reports/periodic
{
"reportFrom": 5,
"reportTo": 10,
"detailed": false,
"printReport": true
}
Example — Detailed by date range:
// Request
POST /api/reports/periodic
{
"dateFrom": "2026-02-01",
"dateTo": "2026-02-16",
"detailed": true,
"printReport": false
}
Validation errors:
| Code | Condition |
|---|---|
FILTER_REQUIRED | Neither date range nor report range provided |
DATE_RANGE_INVALID | dateFrom is after dateTo |
DATE_TO_FUTURE | dateTo is in the future |
REPORT_NUMBER_INVALID | reportFrom or reportTo < 1 |
REPORT_RANGE_INVALID | reportFrom > reportTo |
5. Fiscal Queries
GET /api/fiscal/operations
Query fiscal operations from the audit database with filtering.
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
dateFrom | string | No | Start date (ISO: YYYY-MM-DD) |
dateTo | string | No | End date (ISO: YYYY-MM-DD) |
type | string | No | Operation type filter (see Reference Tables) |
status | string | No | Operation status filter (see Reference Tables) |
limit | int | No | Max results (default 50) |
offset | int | No | Pagination offset (default 0) |
Response fields:
| Field | Type | Description |
|---|---|---|
operations | array | Array of fiscal operations |
operations[].id | string | Operation UUID |
operations[].operationType | string | Type of fiscal operation |
operations[].receiptNumber | int | Receipt number |
operations[].reportNumber | int | Z report number |
operations[].mevId | string | null | MEV transaction ID |
operations[].status | string | Operation status |
operations[].isOffline | boolean | Whether operated offline |
operations[].totalAmount | number | Operation amount |
operations[].vatBreakdown | object | Simplified VAT breakdown |
operations[].vatDetails | object | Detailed VAT with percent, rate, cost, gross |
operations[].paymentsBreakdown | object | Payments by type |
operations[].mevResponseXml | string | SOAP response XML |
operations[].errorMessage | string | null | Error message if operation failed |
operations[].createdAt | string | ISO 8601 creation timestamp |
operations[].completedAt | string | ISO 8601 completion timestamp |
total | int | Total matching operations |
limit | int | Applied limit |
offset | int | Applied offset |
GET /api/fiscal/daily-summary
Get the current fiscal day summary. Returns the same data as an X Report but without sending anything to MEV. Read-only, no fiscal lock required.
Requires: Terminal must be fiscalized.
Response: Same as Report Data object (see Z Report section).
6. Print
POST /api/print
Print non-fiscal text on the POS thermal printer. Supports multi-column layouts.
Request body:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
lines | array | Yes | — | Array of line arrays |
feedLines | int | No | 3 | Number of blank lines after content |
cut | boolean | No | true | Cut paper after printing |
Line format — each line is an array of 1-3 strings:
| Columns | Layout |
|---|---|
["text"] | Full width, left-aligned |
["left", "right"] | Left + right aligned |
["left", "center", "right"] | Three-column layout |
[""] | Empty line (spacer) |
This is a non-fiscal operation — no MEV interaction, no fiscal receipt.
Response fields:
| Field | Type | Description |
|---|---|---|
linesCount | int | Number of lines printed |
printedAt | string | ISO 8601 timestamp |
Example — Inventory report (3 columns):
POST /api/print
{
"lines": [
["RAPORT INVENTAR"],
["Data:", "16.02.2026"],
[""],
["Cod", "Denumire", "Cantitate"],
["────────────────────────────────"],
["001", "Cafea espresso", "150 buc"],
["002", "Tort Napoleon", "12.5 kg"],
["003", "Apa minerala 0.5L", "340 buc"],
[""],
["Total pozitii:", "4"],
["────────────────────────────────"],
["Responsabil:", "", "Ion Popescu"]
],
"feedLines": 3,
"cut": true
}
Error: 503 PRINTER_UNAVAILABLE if the printer is disconnected or not available.
Reference Tables
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
MISSING_API_KEY | 401 | X-API-Key header not provided |
INVALID_API_KEY | 401 | Provided API key is not valid |
VALIDATION_ERROR | 400 | Request body validation failed (see details[]) |
INVALID_JSON | 400 | Request body is not valid JSON |
TERMINAL_NOT_FISCAL | 409 | Terminal is not fiscalized (no MEV certificate) |
MEV_CREDENTIALS_MISSING | 409 | Terminal is fiscalized but MEV credentials are missing |
FISCAL_DAY_EXPIRED | 409 | >24h since last Z Report — Z Report required before continuing |
INSUFFICIENT_CASH_BALANCE | 409 | Cash balance insufficient for the requested withdrawal |
MEV_ERROR | 502 | Communication with MEV (SFS) failed (timeout, SOAP error, expired certificate) |
BUSY | 429 | Another fiscal operation is in progress (30s timeout exceeded) |
SALE_NOT_FOUND | 404 | Sale with specified ID not found |
PRINTER_UNAVAILABLE | 503 | Printer is not available or disconnected |
VAT Codes
| Code | Description |
|---|---|
A | VAT rate A (as configured on terminal) |
B | VAT rate B (typically 20%) |
C | VAT rate C |
D | VAT rate D |
E | VAT rate E |
_ | Exempt (no VAT) |
Payment Types (ACPS WSDL)
| Type | Description |
|---|---|
"1" | NUMERAR (Cash) |
"2" | CARD |
"3.1" | VAUCHER |
"3.2" | CEC / Certificat valoric |
"3.3" | TICHET — plata cu document de valoare prestabilita (MDL) |
"5" | TME — tichet de masa pe suport electronic |
"6" | ABONAMENT |
"7" | ALT IP (alt instrument de plata) |
"8.1" | Credit |
"8.2" | Leasing |
"8.3" | Avans |
"8.4" | Arvuna |
"8.5" | Gaj |
"8.8" | Compensare |
"8.9" | Alt mod |
Fiscal Operation Types
| Type | Description |
|---|---|
receipt | Fiscal receipt (sale) |
cash_in | Cash deposit |
cash_out | Cash withdrawal |
refund | Refund/return |
x_report | X Report |
z_report | Z Report |
Fiscal Operation Statuses
| Status | Description |
|---|---|
pending | Created, not yet sent to MEV |
sent | Sent to MEV, awaiting response |
success | Successfully processed by MEV |
failed | MEV returned an error |
offline | Stored locally (MEV unreachable) |
VAT Breakdown Object
{
"B": {
"code": "B",
"percent": 20.0,
"vatAmount": 7.50,
"taxableBase": 37.50,
"gross": 45.00
}
}
| Field | Type | Description |
|---|---|---|
code | string | VAT rate code |
percent | number | VAT percentage |
vatAmount | number | VAT amount |
taxableBase | number | Net amount (excluding VAT) |
gross | number | Gross amount (including VAT) |
Notes
- All monetary amounts are in MDL (Moldovan Lei) as
numberwith 2 decimal precision. - All timestamps are in ISO 8601 UTC format.
- The server uses a fiscal operation lock — only one fiscal operation (sale, cash-in/out, Z/X report) can run at a time. Concurrent requests will wait up to 30 seconds before returning
429 BUSY. - Offline mode: When MEV (tax authority server) is unreachable, fiscal operations are stored locally and synced later. The response will have
isOffline: trueandmevId: null. - Receipt printing is fire-and-forget — the API response does not wait for printing to complete.