e-bon
e-bon.ro
API reference

Receipts

REST endpoints for storing, listing and retrieving fiscal receipts after they have been printed on the AMEF — request and response schemas, curl examples and per-endpoint error codes.

Receipts

The Receipts API is the journal layer of e-bon: once a fiscal command has been executed by the AMEF and the printer has returned a fiscal ID, the integration stores a copy of that receipt on the e-bon side so it can be searched, exported and audited later. The endpoints under /api/v1/receipts do not print anything themselves — printing goes through the Devices commands layer; the receipts collection is a write-once journal of what was printed.

All endpoints in this group accept either an API key (x-api-key / Authorization: Bearer …) or a Portal JWT and are governed by a single scope: receipts. There is no separate read-only access for these particular routes — receipts:read and receipts:admin cover other operations (history exports, storno) documented elsewhere. See Authentication › Choose scopes for the full scope catalogue.

The error envelope, idempotency rules and pagination conventions used below are documented once on API overview; only the per-endpoint error codes are listed in full on this page.

POST /api/v1/receipts

Stores a receipt after a successful fiscal print. Use this immediately after a print_receipt command on the device returns a fiscal ID, to keep the e-bon journal in sync.

  • Auth scope: receipts
  • Idempotency: supports Idempotency-Key header (replays return the original 201 response).
  • Side effect: broadcasts a receipt.created event on the org events WebSocket and dispatches a receipt.created webhook to subscribers.

Request body

FieldTypeRequiredNotes
deviceIdstringyesMust be a device that exists in your organization.
typestringyesOne of sale, refund, storno.
itemsarrayyesAt least one item. Each { name, quantity, price, vatGroup, department?, discount? } — omit department for a named sale booked under the item's own VAT group. vatGroup ∈ VAT1..VAT16, exempt (device VAT group).
paymentsarrayyesMay be empty (a receipt printed without explicit payment lines is closed by the device in cash). Each { method, amount }. method ∈ 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.
totalnumberyesReceipt grand total (sum of payments).
vatBreakdownarrayyesMay be empty (best-effort — the controller's post-print VAT table read can fail). Each { group, rate, base, amount } — group is the device VAT group, rate the percent snapshot from the device's own rate table.
operatorIdstringyesOperator / cashier identifier.
fiscalIdstringnoFiscal ID returned by the AMEF.
fiscalDatestringnoFiscal date string returned by the AMEF.
customerCifstringnoCustomer CIF, 2–20 chars, trimmed.
qrCodestringnoQR code data, ≤ 2048 chars.
sourcestringnoOne of api, local, portal. Defaults to api.

Response (201 Created)

{
  "receipt": {
    "id": "rec_abc123",
    "deviceId": "dev_pos_01",
    "type": "sale",
    "items": [
      { "name": "Paine alba 500g", "quantity": 2, "price": 5.49, "vatGroup": "VAT2", "department": 1 }
    ],
    "payments": [{ "method": "cash", "amount": 10.98 }],
    "total": 10.98,
    "vatBreakdown": [{ "group": "VAT2", "rate": 9, "base": 10.07, "amount": 0.91 }],
    "operatorId": "casier_01",
    "orgId": "acme_corp",
    "fiscalId": "AMEF-000123",
    "fiscalDate": "2026-04-09",
    "source": "api",
    "createdAt": "2026-04-09T08:10:00.000Z"
  }
}

Example

curl -X POST https://api.e-bon.ro/api/v1/receipts \
  -H "x-api-key: ebon_live_acme_corp_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-12345-attempt-1" \
  -d '{
    "deviceId": "dev_pos_01",
    "type": "sale",
    "items": [
      { "name": "Paine alba 500g", "quantity": 2, "price": 5.49, "vatGroup": "VAT2", "department": 1 }
    ],
    "payments": [{ "method": "cash", "amount": 10.98 }],
    "total": 10.98,
    "vatBreakdown": [{ "group": "VAT2", "rate": 9, "base": 10.07, "amount": 0.91 }],
    "operatorId": "casier_01",
    "fiscalId": "AMEF-000123",
    "fiscalDate": "2026-04-09"
  }'

Error codes

  • VALIDATION_ERROR (400) — the request body is invalid (missing fields, invalid VAT group, etc.).
  • NOT_FOUND (404) — deviceId does not exist in your organization.
  • UNAUTHORIZED / FORBIDDEN — see Authentication › Handle auth errors.

The full HTTP catalogue is on API overview › HTTP error code catalogue.

GET /api/v1/receipts

Lists receipts for the organization with cursor pagination and a set of optional filters. Receipts are returned newest-first by default.

  • Auth scope: receipts

Query parameters

ParameterTypeDefaultNotes
deviceIdstring—Filter by device.
typestring—One of sale, refund, storno.
operatorIdstring—Filter by operator.
minTotalnumber—Inclusive lower bound on total.
maxTotalnumber—Inclusive upper bound on total. Must be ≥ minTotal.
startDatestring—ISO 8601 timestamp; receipts with createdAt >= startDate.
endDatestring—ISO 8601 timestamp; receipts with createdAt <= endDate.
sortBystringcreatedAtcreatedAt or total. Ignored when startDate/endDate is set (orders by createdAt instead).
sortOrderstringdescasc or desc.
limitinteger50Page size, 1–100.
startAfterstring—Cursor — pass the previous response's lastId.
When you combine a total range filter (minTotal / maxTotal) with sorting, the server orders by total first to satisfy Firestore's range-query rule, then by createdAt desc as a tiebreaker.

Response (200 OK)

{
  "receipts": [
    {
      "id": "rec_abc123",
      "deviceId": "dev_pos_01",
      "type": "sale",
      "total": 10.98,
      "operatorId": "casier_01",
      "orgId": "acme_corp",
      "createdAt": "2026-04-09T08:10:00.000Z"
    }
  ],
  "hasMore": true,
  "lastId": "rec_abc123"
}

Example

curl "https://api.e-bon.ro/api/v1/receipts?deviceId=dev_pos_01&limit=20" \
  -H "x-api-key: ebon_live_acme_corp_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"

Then, to fetch the next page:

curl "https://api.e-bon.ro/api/v1/receipts?deviceId=dev_pos_01&limit=20&startAfter=rec_abc123" \
  -H "x-api-key: ebon_live_acme_corp_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"

Error codes

GET /api/v1/receipts/{receiptId}

Returns a single receipt by ID.

  • Auth scope: receipts

Path parameters

ParameterTypeNotes
receiptIdstringReceipt document ID.

Response (200 OK)

{
  "receipt": {
    "id": "rec_abc123",
    "deviceId": "dev_pos_01",
    "type": "sale",
    "items": [
      { "name": "Paine alba 500g", "quantity": 2, "price": 5.49, "vatGroup": "VAT2", "department": 1 }
    ],
    "payments": [{ "method": "cash", "amount": 10.98 }],
    "total": 10.98,
    "vatBreakdown": [{ "group": "VAT2", "rate": 9, "base": 10.07, "amount": 0.91 }],
    "operatorId": "casier_01",
    "orgId": "acme_corp",
    "fiscalId": "AMEF-000123",
    "fiscalDate": "2026-04-09",
    "createdAt": "2026-04-09T08:10:00.000Z"
  }
}

Example

curl https://api.e-bon.ro/api/v1/receipts/rec_abc123 \
  -H "x-api-key: ebon_live_acme_corp_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"

Error codes

See also

  • Devices commands — issue a print_receipt command before storing the receipt here.
  • Reports — live device reports: MF/EJ reads, X/Z/periodic prints, ANAF archive export.
  • API overview — base URL, error envelope, rate limits, idempotency, pagination.
  • Troubleshooting — symptom-driven recipes when receipts fail to print, time out, or trigger ANAF rejections.