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, vatRate, department, discount? }.
paymentsarrayyesAt least one payment. Each { method, amount }. methodcash, card, voucher, credit, other.
totalnumberyesReceipt grand total (sum of payments).
vatBreakdownarrayyesAt least one entry. Each { rate, base, amount }. rate0, 9, 11, 21.
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, "vatRate": 9, "department": 1 }
    ],
    "payments": [{ "method": "cash", "amount": 10.98 }],
    "total": 10.98,
    "vatBreakdown": [{ "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, "vatRate": 9, "department": 1 }
    ],
    "payments": [{ "method": "cash", "amount": 10.98 }],
    "total": 10.98,
    "vatBreakdown": [{ "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, wrong VAT rate, 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
deviceIdstringFilter by device.
typestringOne of sale, refund, storno.
operatorIdstringFilter by operator.
minTotalnumberInclusive lower bound on total.
maxTotalnumberInclusive upper bound on total. Must be ≥ minTotal.
startDatestringISO 8601 timestamp; receipts with createdAt >= startDate.
endDatestringISO 8601 timestamp; receipts with createdAt <= endDate.
sortBystringcreatedAtcreatedAt or total. Ignored when startDate/endDate is set (orders by createdAt instead).
sortOrderstringdescasc or desc.
limitinteger50Page size, 1100.
startAfterstringCursor — 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, "vatRate": 9, "department": 1 }
    ],
    "payments": [{ "method": "cash", "amount": 10.98 }],
    "total": 10.98,
    "vatBreakdown": [{ "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 — X / Z / JE / MF reports built on top of the receipt journal.
  • 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.