Command types
Command types
Every fiscal action your POS performs through e-bon — printing a receipt, opening the cash drawer, closing the day with a Z report — is dispatched as a typed command to a registered AMEF device.
This page is the per-type reference. For each command it lists the wire identifier you send in the request body, the JSON payload (when one is required), and what the device returns. Pair it with the Commands API page, which documents the HTTP envelope, polling, and idempotency.
Send a command
Every command type uses the same HTTP entry point:
POST /api/v1/devices/:deviceId/commands
Content-Type: application/json
Authorization: Bearer <api-key>
{
"type": "print_receipt",
"payload": { /* per-type body, see below */ }
}
A single API-key scope (commands) authorizes every command type listed on this page. See API keys for how to mint and rotate keys.
Command catalogue
The 28 command types, grouped by purpose:
| Wire string | Category | Payload | Purpose |
|---|---|---|---|
print_receipt | Receipts | required | Print a fiscal sale receipt. |
void_receipt | Receipts | required | Void a previously emitted receipt by ID. |
print_reversal_receipt | Receipts | required | Issue a storno (fiscal reversal). |
void_open_receipt | Receipts | none | Cancel a receipt currently open on the device. |
print_duplicate | Receipts | none | Reprint the last receipt as a non-fiscal duplicate. |
non_fiscal_receipt | Receipts | required | Print a free-form non-fiscal slip. |
x_report | Reports | none | Read mid-day totals without closing the day. |
z_report | Reports | none | Close the fiscal day and write totals to fiscal memory. |
cash_in | Cash | required | Register a cash deposit. |
cash_out | Cash | required | Register a cash withdrawal. |
get_cash_amount | Cash | none | Read the running cash balance. |
open_drawer | Cash | none | Pulse the cash drawer open. |
set_datetime | Configuration | optional | Set the device clock. |
set_logo | Configuration | required | Upload a logo bitmap. |
delete_logo | Configuration | none | Remove the configured logo. |
set_vat_rates | Configuration | required | Configure the device's VAT rate table. |
set_header_footer | Configuration | required | Replace the printed header and footer lines. |
set_operator | Configuration | required | Add or replace a cashier identity. |
get_operators | Configuration | none | Read back all operator slots (names, passwords). |
get_status | Diagnostics | none | Read paper, cover, and error state. |
get_info | Diagnostics | none | Read serial, firmware, and fiscal memory status. |
get_last_receipt_info | Diagnostics | none | Read metadata of the last issued receipt. |
get_date_time | Diagnostics | none | Read the device's current clock. |
get_vat_rates | Diagnostics | none | Read the configured VAT rate table. |
get_vat_capabilities | Diagnostics | none | Read VAT rates supported by the firmware. |
get_header_footer_capabilities | Diagnostics | none | Read header/footer line and width limits. |
get_header_footer | Diagnostics | none | Read the configured header and footer. |
get_operator_capabilities | Diagnostics | none | Read operator-slot count and password limits. |
raw_command | Raw | passthrough | Send protocol-native bytes to the driver. |
Receipts
Print a fiscal receipt
Print a fiscal sale receipt on the AMEF.
Type: print_receipt
{
"items": [
{ "name": "Coffee", "quantity": 2, "price": 9.5, "vatGroup": "VAT1", "department": 1 }
],
"subtotalModifiers": [{ "type": "discount-amount", "value": 1.0 }],
"customerCif": "RO12345678",
"payments": [
{ "method": "cash", "amount": 10.0 },
{ "method": "card", "amount": 8.0 }
]
}
| Field | Type | Required | Notes |
|---|---|---|---|
items | array | yes | Must be non-empty. |
items[].name | string | yes | Non-empty product name. |
items[].quantity | number | yes | Strictly positive. |
items[].price | number | yes | Unit price. |
items[].vatGroup | string | yes | One of VAT1..VAT16 or exempt (device VAT group; the percent is resolved from the device's own rate table). |
items[].department | number | no | Department index on the device. |
subtotalModifiers | array | no | Whole-receipt adjustments applied to the items subtotal, in order. Supported drivers: Datecs, Tremol, Custom (rejected with E201 elsewhere). |
subtotalModifiers[].type | string | yes | discount-amount or surcharge-amount. Percent adjustments must be computed to an amount by the caller. |
subtotalModifiers[].value | number | yes | Strictly positive lei magnitude. |
customerCif | string | no | Customer fiscal code (CUI/CIF) printed on the receipt where the device supports it. |
payments | array | yes | Must be non-empty. Split tenders are multiple entries. |
payments[].method | string | yes | One of cash, card, check, credit, coupons, meal-vouchers, value-tickets, voucher, modern-payment, card-advance, foreign-currency, bank, ext-coupons, packaging, internal-usage, damage, reserved1, reserved2, other. |
payments[].amount | number | yes | Strictly positive. |
The total of items (quantity × price) adjusted by subtotalModifiers must equal the total of payments within 0.01.
On success: result.fiscalId carries the AMEF-assigned receipt ID. Driver-specific details land in result.data.
See also: Receipts API, Receipt emission flow.
Void a receipt
Void a previously emitted fiscal receipt by its ID.
Type: void_receipt
{ "receiptId": "rcpt_01HZ..." }
| Field | Type | Required | Notes |
|---|---|---|---|
receiptId | string | yes | ID of the receipt to void. |
Issue a fiscal reversal (storno)
Emit a Romanian storno that legally cancels an earlier sale and references the original receipt.
Type: print_reversal_receipt
{
"uniqueSaleNumber": "USN-2026-000123",
"originalReceiptNumber": "0000456",
"originalReceiptDateTime": "2026-04-20T14:32:11Z",
"fiscalMemorySerialNumber": "DY12345678",
"originalZReportNumber": "12",
"reason": "operator-error",
"items": [
{ "name": "Coffee", "quantity": 1, "price": 9.5, "vatGroup": "VAT1" }
],
"payments": [
{ "type": "cash", "amount": 9.5 }
]
}
| Field | Type | Required | Notes |
|---|---|---|---|
uniqueSaleNumber | string | yes | USN of the original sale. |
originalReceiptNumber | string | yes | Receipt number to reverse. |
originalReceiptDateTime | string | yes | Valid ISO-8601 timestamp. |
fiscalMemorySerialNumber | string | yes | Serial of the original AMEF. |
originalZReportNumber | string | no | Z-report number, if known. |
reason | string | yes | One of operator-error, refund, tax-base-reduction. |
items | array | yes | Same per-item rules as print_receipt. |
payments | array | no | If present, follows the same rules as print_receipt and is balance-checked. |
On success: the storno receipt's own fiscal ID is returned in result.fiscalId.
Cancel an open receipt
Cancel a receipt that is currently open on the device. Use this to reset state after a hardware or operator interruption.
Type: void_open_receipt — no payload.
Reprint the last receipt
Reprint the last receipt as a non-fiscal duplicate.
Type: print_duplicate — no payload.
Print a non-fiscal slip
Print a free-form, non-fiscal slip such as a pre-bill or loyalty notice. Non-fiscal prints do not write to fiscal memory and have no fiscal ID.
Type: non_fiscal_receipt
{
"lines": ["Thanks for visiting", "See you soon!"],
"header": "Loyalty receipt"
}
| Field | Type | Required | Notes |
|---|---|---|---|
lines | string | yes | Non-empty list of lines to print. |
header | string | no | Optional header line. |
Reports
Read an X report
Read mid-day totals without closing the fiscal day. Returns totals, VAT breakdown, and receipt count in result.data.
Type: x_report — no payload.
On success, e-bon also fires a report.generated webhook.
See also: X report.
Close the day with a Z report
Close the fiscal day, freeze daily totals into fiscal memory, and reset daily counters.
Type: z_report — no payload.
On success, e-bon also fires a report.generated webhook.
See also: Z report.
Cash management
Register a cash deposit
Register a cash deposit into the device drawer.
Type: cash_in
{ "amount": 200, "description": "Opening float" }
| Field | Type | Required | Notes |
|---|---|---|---|
amount | number | yes | Strictly positive. |
description | string | no | Free-text note. |
Register a cash withdrawal
Register a cash withdrawal from the device drawer. Same payload as cash_in.
Type: cash_out
{ "amount": 50, "description": "Bank deposit" }
Read the cash balance
Read the running cash balance the device tracks for the drawer. Returns { cashBalance, currency } in result.data.
Type: get_cash_amount — no payload.
Open the cash drawer
Pulse the cash drawer open without printing anything.
Type: open_drawer — no payload.
Configuration
Set the device clock
Sync the device clock, optionally to a specific timestamp.
Type: set_datetime
{ "datetime": "2026-04-25T10:00:00Z" }
| Field | Type | Required | Notes |
|---|---|---|---|
datetime | string | no | If present, must be a valid ISO-8601 timestamp. If omitted, the device syncs to current server time. |
Upload a logo
Upload a logo bitmap that the device prints at the top of receipts.
Type: set_logo
{ "logo": "iVBORw0KGgoAAAANSUhEUgAA..." }
| Field | Type | Required | Notes |
|---|---|---|---|
logo | string | yes | Base64-encoded bitmap. |
Delete the logo
Remove the configured logo from the device.
Type: delete_logo — no payload.
Configure VAT rates
Configure the device's VAT rate table by group (for example VAT1 → 21, VAT2 → 9).
Type: set_vat_rates
{
"rates": [
{ "group": "VAT1", "rate": 21, "enabled": true },
{ "group": "VAT2", "rate": 9, "enabled": true }
]
}
| Field | Type | Required | Notes |
|---|---|---|---|
rates | array | yes | At least one entry. |
rates[].group | string | yes | Device VAT group (VAT1..VAT16). |
rates[].rate | number | yes | Non-negative percentage. |
rates[].enabled | boolean | yes | Whether the group is active on the device. |
Set the header and footer
Replace the lines printed at the top and bottom of every receipt.
Type: set_header_footer
{
"header": ["My Coffee Shop SRL", "Bd. Magheru 12, București"],
"footer": ["Thank you!", "www.example.ro"]
}
| Field | Type | Required | Notes |
|---|---|---|---|
header | string | yes | Header lines (may be an empty array). |
footer | string | yes | Footer lines (may be an empty array). |
get_header_footer_capabilities before pushing — line counts and character widths vary by firmware.Configure an operator
Add or replace an operator slot (cashier identity) on the device.
Type: set_operator
{ "operatorId": 1, "name": "Maria", "password": "1234" }
| Field | Type | Required | Notes |
|---|---|---|---|
operatorId | number | yes | Integer ≥ 1. |
name | string | yes | Operator name. |
password | string | no | Optional password. |
oldPassword | string | no | Current password authorizing the change — required on devices reporting passwordChangeRequiresOldPassword. |
get_operator_capabilities first — slot count and password support vary by firmware.Diagnostics
Read device status
Read the device's current operating status — paper, cover, fiscal-day state, and any errors.
Type: get_status — no payload.
Read device identity
Read the device serial number, firmware version, fiscal-memory serial number, manufacturer, and model.
Type: get_info — no payload.
Returns { info: { serialNumber, firmwareVersion, fiscalMemorySerialNumber, manufacturer, model } } in result.data.
Read the last receipt
Read metadata of the last issued receipt.
Type: get_last_receipt_info — no payload.
Returns { lastReceipt: { receiptNumber, receiptDateTime, receiptAmount, fiscalMemorySerialNumber } } in result.data. Every field is nullable when the driver does not report it.
Read the device clock
Read the device's current date and time — the same reading the mobile app shows on its Home screen.
Type: get_date_time — no payload.
Returns { dateTime } (ISO-8601) in result.data. Also exposed directly as GET /api/v1/devices/{deviceId}/datetime.
Read configured VAT rates
Read the VAT rate table currently configured on the device.
Type: get_vat_rates — no payload.
Returns an array of { group, rate, enabled } in result.data — read live from the device's own rate table.
Read supported VAT rates
Read which VAT rates the device firmware accepts (the possible rates, not the configured ones).
Type: get_vat_capabilities — no payload.
Read header/footer limits
Read the device's header and footer limits.
Type: get_header_footer_capabilities — no payload.
Returns { maxHeaderLines, maxFooterLines, maxCharsPerLine } in result.data.
Read configured header and footer
Read the header and footer currently configured on the device.
Type: get_header_footer — no payload.
Returns { header: string[], footer: string[] } in result.data.
Read operator limits
Read the operator-slot count and password constraints supported by the firmware.
Type: get_operator_capabilities — no payload.
Returns { maxOperators, maxNameLength, maxPasswordLength, supportsPassword, passwordChangeRequiresOldPassword, canGetOperators } in result.data.
List operators
Read back every operator slot on the device — names, and passwords where the device exposes them (Datecs RO).
Type: get_operators — no payload.
Returns { operators: [{ operatorId, name, password? }] } in result.data. Only available when get_operator_capabilities reports canGetOperators: true; other drivers reject the command.
Send a raw command
Driver-specific escape hatch for sending protocol-native bytes when no typed command exists. Whatever you pass in payload is forwarded straight to the device driver.
Type: raw_command
raw_command bypasses every payload check e-bon performs. Misuse can put a device into an unusable state or emit non-compliant fiscal output. Treat it as a debugging tool, not a production primitive.Track a command result
Every command, regardless of type, moves through the same lifecycle. The status field on the command document takes one of six values:
| Status | When you see it |
|---|---|
pending | The API has accepted and persisted the command. |
sent | The command is in flight to the device. |
processing | The device has acknowledged and is working on it. |
completed | The device returned success. result.data and (for receipt commands) result.fiscalId are populated. |
failed | The device or dispatcher reported failure. result.errorCode and result.errorMessage are populated. |
timeout | The device did not respond in time. result.errorCode is E500 (TimeoutCommand). |
The full result envelope is { success, data?, fiscalId?, errorCode?, errorMessage? }.
Where to next
- Commands API — HTTP envelope, polling, and idempotency.
- Commands SDK — typed wrappers around this catalogue.
- Receipt emission flow — end-to-end pipeline.
- Errors —
errorCodevalues that surface in command results. - Glossary — USN, storno, AMEF, MF, X / Z reports.