Skip to content

Revenue API

The Revenue API returns every fiscal transaction in a date range — with its positions, payments and tax breakdown — in a single call. Use it for accounting exports, revenue reconciliation, BI warehouses or ad-hoc reports.

  • Host: my.apro.at
  • Auth: API key in x-api-key
  • Content type: application/json

Endpoints

VariantEndpointLocation derived from
Path + keyPOST /api/v1/locations/{location}/reports/receipts{location} must match the key’s location.
Key onlyPOST /api/v1/reports/receiptsThe API key itself.

Both variants require a location-scoped API key. The key itself determines which location’s data is returned — there is no tenant-wide variant. Pick whichever feels more explicit in your client code — both return the same data and require the same key.

Request body

FieldTypeRequiredDescription
afterISO 8601 timestampReturn receipts after this point in time.
beforeISO 8601 timestampReturn receipts before this point in time.
limitintegerCap the number of results returned.
afterTransactionIDGUIDCursor — return transactions after this ID. Combine with limit for paging.

Example request

POST /api/v1/reports/receipts
{
"after": "2026-01-01T00:00:00Z",
"before": "2026-02-01T00:00:00Z",
"limit": 100,
"afterTransactionID": "f03e11de-6330-4a03-a8a8-b6e5fd4e32a5"
}

Download: revenue-request.json

Response

An array of receipts. Each element is one transaction with its positions, payments and metadata.

Top-level fields

FieldTypeDescription
transactionIdGUIDUnique transaction ID.
transactionTypestringSee Transaction types.
receiptTypestringBeleg, Ausgangsrechnung, or Lieferschein.
totalAmountdecimalGross total of the receipt.
tipdecimalTip included in totalAmount.
discountdecimalDiscount applied to the receipt.
dateTimeISO 8601When the transaction happened.
businessBusinessTenant / operator record.
locationLocationThe APRO location the data was queried for.
staffStaffOperator / waiter.
tableTableTable or delivery spot (e.g. “Bar 1”, “Room 301”).
areaAreaRoom / zone the table belongs to (e.g. Garden, Bar).
customerCustomer · nullableInvoice recipient. Always null on this endpoint — see below.
paymentGroupPayment groupGrouping the payment types roll up into.
paymentsPayment[]Payments settling the receipt.
itemsItem[]Line items.
guestCountintegerNumber of guests, summed over the receipt’s line items. 0 when not recorded.

Item

FieldTypeDescription
idstringUnique item ID.
numberintegerProduct number (as used in APRO). 0 when it cannot be parsed.
namestringProduct name.
uniqueIdstring · nullableStable per-line identifier. Use it to deduplicate or reconcile lines across repeated queries. null on older query configurations.
externalIdstring · nullableReference assigned by an external system. null on older query configurations.
bookDateISO 8601Time the line was booked.
grossAmountdecimalGross price.
netAmountdecimalNet price.
purchasePricedecimalCost price of the line, for margin reporting. 0 on older query configurations.
quantitydecimalUnits sold.
courseinteger · nullableCourse number in a multi-course service (Gang). null when not assigned.
taxTaxApplied tax rate.
categoryCategoryProduct category (a.k.a. “Sparte”).
sideDishesSide dish[] · nullableSide dishes / modifiers booked on this line. null when there are none.

Side dish

Side dishes (Unterartikel) are the modifiers booked underneath a line item — the Pommes under a schnitzel, the ohne Zwiebel on a burger. They are returned nested inside their parent item, never as items of their own.

A side dish reuses the Item shape, but only the following fields are populated. Every other field — bookDate, externalId, purchasePrice, course, tax, category, sideDishes — is null or its zero value, and side dishes do not nest recursively.

FieldTypeDescription
idstringUnique side dish ID.
numberintegerProduct number of the side dish. 0 when it cannot be parsed.
namestringSide dish name.
uniqueIdstringStable per-side-dish identifier. Also the key the API deduplicates on.
grossAmountdecimalGross price of the side dish.
netAmountdecimalNet price of the side dish.
quantitydecimalUnits of the side dish.

sideDishes is null — not [] — when a line has none, and also on older query configurations that predate the feature. Test for null-or-empty rather than assuming an array is present.

Tax

FieldTypeDescription
idstringUnique tax rate ID.
valuedecimalRate, e.g. 20.0 for 20 %.
namestringDisplay name, e.g. Mwst 20 %.

Category

FieldTypeDescription
idstringUnique category ID.
numberintegerCategory number.
namestringDisplay name.

Payment

FieldTypeDescription
idstringUnique payment ID. Payments are deduplicated on this value.
amountdecimalAmount paid.
paymentTypePaymentTypeMethod used.
fibuAccountNrstring · nullableFinancial-accounting account number the payment posts to. Use it to map payments onto ledger accounts in an export.

Payment type

FieldTypeDescription
idinteger · nullableUnique payment method ID.
nrinteger · nullablePayment method number. Note the key is nr, not number.
namestringDisplay name, e.g. Bar, Kreditkarte.

Business

FieldTypeDescription
idstringTenant ID from the POS database.
namestringLegal name.

Staff

FieldTypeDescription
idstringUnique staff ID.
numberintegerPersonnel number.
namestringStaff name.

Table

FieldTypeDescription
idstringUnique table ID.
numberintegerTable number.
namestringTable label, e.g. Bar 1, Restaurant 5.

Location

FieldTypeDescription
idstringAPRO location ID — the locationId the query resolved to.
namestring · nullableLocation name.

Area

The room or zone a table sits in.

FieldTypeDescription
idstringUnique area ID.
numberintegerArea number.
namestringArea label, e.g. Garten, Bar.

Payment group

The grouping payment types roll up into — used for cash-book and settlement reporting.

FieldTypeDescription
idintegerPayment group ID. 0 when not set.
namestringGroup label.

Customer

FieldTypeDescription
idstringUnique customer ID.
numberintegerCustomer number.
namestringCustomer name.

Example response

Response · two receipts settled back-to-back
[
{
"transactionId": "f03e11de-6330-4a03-a8a8-b6e5fd4e32a5",
"transactionType": "Abrechnen",
"receiptType": "Beleg",
"totalAmount": 3.2,
"tip": 0.0,
"discount": 0.0,
"dateTime": "03.10.2021 21:59:57",
"business": { "id": "1", "name": "APRO Kassensysteme" },
"location": { "id": "7236", "name": "Wien Haupthaus" },
"staff": { "id": "8", "number": 9500, "name": "Onlinekellner" },
"table": { "id": "76", "number": 76, "name": "Daniel Z" },
"area": { "id": "3", "number": 3, "name": "Garten" },
"customer": null,
"paymentGroup": { "id": 2, "name": "Kartenzahlung" },
"payments": [
{
"id": "04b2d2f5-8765-41b5-ad5c-aed802dc23bc",
"amount": 3.2,
"paymentType": { "id": 26, "nr": 200, "name": "Smorder Kreditkarte" },
"fibuAccountNr": "2751"
}
],
"items": [
{
"id": "38",
"number": 216,
"name": "Wiener Schnitzel",
"uniqueId": "0f6c2c14-3f8a-4f0b-9a1e-2b7d5c8e4411",
"externalId": null,
"bookDate": "03.10.2021 21:59:55",
"grossAmount": 3.2,
"netAmount": 3.2,
"purchasePrice": 1.1,
"quantity": 1.0,
"course": 2,
"tax": { "id": "5", "value": 5.0, "name": "Mwst 5 %" },
"category": { "id": "12", "number": 12, "name": "Hauptspeisen" },
"sideDishes": [
{
"id": "512",
"number": 9001,
"name": "Pommes",
"uniqueId": "b41d9a77-55c2-4e3d-8f10-6cc0a2b93d88",
"grossAmount": 1.5,
"netAmount": 1.36,
"quantity": 1.0
},
{
"id": "518",
"number": 9007,
"name": "ohne Zwiebel",
"uniqueId": "c9a70e31-1d44-4a92-b7e5-30f8c1d6a204",
"grossAmount": 0.0,
"netAmount": 0.0,
"quantity": 1.0
}
]
}
],
"guestCount": 2
},
{
"transactionId": "db2b90d1-ab37-4557-b169-2289c3004a0a",
"transactionType": "Abrechnen",
"receiptType": "Beleg",
"totalAmount": 3.2,
"tip": 0.0,
"discount": 0.0,
"dateTime": "03.10.2021 22:00:12",
"business": { "id": "1", "name": "APRO Kassensysteme" },
"location": { "id": "7236", "name": "Wien Haupthaus" },
"staff": { "id": "8", "number": 9500, "name": "Onlinekellner" },
"table": { "id": "76", "number": 76, "name": "Daniel Z" },
"area": { "id": "3", "number": 3, "name": "Garten" },
"customer": null,
"paymentGroup": { "id": 2, "name": "Kartenzahlung" },
"payments": [
{
"id": "bb3e6300-0cc3-4922-80c4-a8a4c3530d3c",
"amount": 3.2,
"paymentType": { "id": 26, "nr": 200, "name": "Smorder Kreditkarte" },
"fibuAccountNr": "2751"
}
],
"items": [
{
"id": "38",
"number": 216,
"name": "Cola 0,5",
"uniqueId": "7d2f3b90-6c11-4c8e-93aa-5e4419c7f0d3",
"externalId": null,
"bookDate": "03.10.2021 22:00:11",
"grossAmount": 3.2,
"netAmount": 3.2,
"purchasePrice": 0.7,
"quantity": 1.0,
"course": null,
"tax": { "id": "5", "value": 5.0, "name": "Mwst 5 %" },
"category": { "id": "20", "number": 20, "name": "Alkoholfreie Getränke" },
"sideDishes": null
}
],
"guestCount": 1
}
]

Download the same payload as a standalone file: revenue-response.json

Transaction types

The transactionType discriminates what the row represents. For revenue-effective reports, filter on Abrechnen (and RechnungZurückholen for reversals).

TypeMeaning
BonierenItem booked on an open table.
VerschiebenTable change.
AbrechnenSettlement — a paid receipt.
StornierenReversal of a booking.
RechnungZurückholenReversal of a settlement.
DebitBonierenDebit booking.
ARAusstellen · ARPreview · ARNachdruck · ARNachdruckOriginalOutgoing invoice lifecycle.
Tagesabschluss · TagesabschlussPreviewDay-end close / preview.
Kellnerabschlag · KellnerabschlagPreview · KellnerabschlagUndo · KelleruebergabeWaiter hand-over / settlement.
Startbeleg · Schlussbeleg · Nullbeleg · Monatsbeleg · JahresBeleg · NacherfassungssammelbelegLegal fiscal receipts (RKSV).
TischOeffnen · TischSchliessen · GaesteanzahlAendern · GaesteanzahlKorrigierenTable lifecycle.
BestellmanagerBestellung · …NextState · …SetFinaleState · …Undo · …Stornieren · …Verschieben · …NaechsterGang · …StatistikOrder-manager events.
WarenkorbErstellen · WarenkorbUpdate · WarenkorbVerwerfenCart lifecycle.
DatenExport · UndoDatenExportData export markers.
Kassabuch · Bargeldzählung · TerminalKassenschnitt · Lieferantabschlag · LieferantabschlagVorschau · Ansehen · Information · SchankanlageQrCode · Abrechnen HSK · Abrechnen AR · AbrechnenNachdruckOther operational events.

Calculating revenue

To compute revenue-effective turnover over a response, keep only paid settlements and their reversals, and sum the net line totals:

response
.filter(x =>
x.paymentGroup.name === "Umsatzwirksam" &&
["Abrechnen", "RechnungZurückholen"].includes(x.transactionType)
)
.map(x =>
x.items.reduce((sum, item) => sum + item.netAmount * item.quantity, 0)
)
.reduce((sum, val) => sum + val, 0);

Paging

There is no cursor-in-response — use the deterministic transactionId of the last row you saw as afterTransactionID on the next request, keeping after/before unchanged. Continue until the response contains fewer rows than your limit.

Errors

See Authentication → Error responses.