Zum Inhalt springen

Hotel API (PMS)

Die Hotel-API ist die bidirektionale Brücke zwischen einer APRO-Kassa und einem Property-Management-System (PMS). Das PMS spielt Reservierungen in die Kassa ein, damit Gäste aufs Zimmer anschreiben können; die Kassa liefert die Zimmerumsätze an das PMS zurück, damit sie auf der Hotelrechnung landen.

Typischer Ablauf

PMS APRO POS
│ 1. POST /pms/reservations ─────────▶ │ (Reservierungen upsert)
│ │
│ │ Gäste schreiben aufs Zimmer …
│ │
│ 2. GET /pms/charges?hotelId=… ─────▶│
│ ◀─── Charges (optional inkl. Receipts) │
│ │
│ 3. POST /pms/confirm-charges ───────▶│ (ack; keine Wiederholung)
│ │
│ 4. DELETE /pms/reservations?… ───────▶│ (bei Check-out / Abschluss)

Schritt 2 ist die Polling-Schleife des PMS. Schritte 1 und 4 werden durch Ereignisse im PMS ausgelöst. Schritt 3 muss jeder erfolgreichen Abfrage folgen — sonst werden dieselben Charges beim nächsten Poll wieder geliefert.

1. Reservierungen upserten

Den kompletten aktiven Reservierungsstand ins POS übergeben. Schlüssel sind hotelId + Id + guestId; bestehende Zeilen werden in-place aktualisiert.

POST https://cloudgateway.apro.at/hotelservice/api/v1/pms/reservations

Request-Body

FeldTypPflichtBeschreibung
reservationsReservation[]Eine oder mehrere Reservierungen.

Reservation

FeldTypPflichtBeschreibung
IdstringReservierungs-ID im PMS.
hotelIdstringPMS-Mandant / Hotel.
guestIdstringGast-ID im PMS.
roomNrstringZugewiesene Zimmernummer.
titlestringAnrede (Mr., Mrs. …).
firstNamestring
lastNamestring
arrivalISO 8601Check-in-Zeitpunkt.
departureISO 8601Check-out-Zeitpunkt.
nrOfIndividualsintegerPersonenzahl — für Covers/Buffet-Regeln.
identifiersIdentifier[]Keycard-UIDs, NFC-Tokens, Zimmer-Tablets — alle Kennungen, mit denen das POS eine Zimmerbuchung erkennen soll.

Identifier

FeldTypBeschreibung
valuestringWert der Kennung (Keycard-UID, Token).

Beispielanfrage

POST /hotelservice/api/v1/pms/reservations
{
"reservations": [
{
"Id": "Aabc123",
"hotelId": "1",
"guestId": "Abc123",
"roomNr": "Abc123",
"title": "Mr.",
"firstName": "Max",
"lastName": "Mustermann",
"arrival": "2026-04-02T14:00:00",
"departure": "2026-04-04T14:00:00",
"nrOfIndividuals": 1,
"identifiers": [{ "value": "keycard-uid" }]
}
]
}

Download: hotel-reservations-upsert.json

Beispielantwort

200 OK
{
"newReservationsCount": 0,
"checkedOutReservationsCount": 0,
"updatedReservationsCount": 1,
"state": 1,
"isSuccessfull": true,
"errorCode": 0,
"message": null,
"context": null
}

Download: hotel-reservations-response.json

2. Charges abfragen

Holt alle seit dem letzten bestätigten Poll auf Zimmer gebuchten Umsätze.

GET https://cloudgateway.apro.at/hotelservice/api/v1/pms/charges
?hotelId=1
&excludeAlreadyExported=true

Query-Parameter

NameTypPflichtBeschreibung
hotelIdstringPMS-Mandant / Hotel.
excludeAlreadyExportedbooltrue = nur noch nicht bestätigte Einträge (der normale Polling-Modus). false = das gesamte konfigurierte Fenster erneut.

Antwortstruktur

Jedes Element hat ein chargeType, das bestimmt welche Felder befüllt sind:

chargeTypeBedeutungpayments vorhanden?
ChargeOffene Buchung aufs Zimmer (Gast hat noch nicht gezahlt — POS bucht aufs Zimmer-Folio).nein
ReceiptGeschlossener Beleg (Gast hat an der Kassa bezahlt; PMS kann ignorieren oder abgleichen).ja

Top-Level:

FeldTypBeschreibung
page.limitintegerAngewandte Seitengröße.
page.offsetintegerOffset im Backlog.
page.totalintegerNoch nicht bestätigte Einträge insgesamt.
dataItem[]Charges und Receipts.

Item

FeldTypBeschreibung
chargeType`“Charge""Receipt”`
bookDateISO 8601Buchungszeitpunkt im POS.
receiptNrintegerPOS-Belegnummer.
userIdintegerBediener-ID.
userNamestringBedienername.
outletintegerOutlet-ID (1 = Bar, 2 = Restaurant …).
tableNrintegerTischnummer.
tablestringTischbezeichnung.
totalAmountdecimalBruttosumme der Zeile.
tipdecimalEnthaltenes Trinkgeld.
businesscaseIdGUIDAPRO-Transaktions-ID — genau dieser Wert wandert als transactionIds in den Confirm-Aufruf.
reservationIdstring | nullReservierungs-ID (bei Charge).
guestIdstring | nullGast-ID.
roomNumberstring | nullZimmernummer.
chargesLineItem[]Einzelpositionen.
paymentsPayment[]Nur bei Receipt.

LineItem

FeldTypBeschreibung
articleNrintegerArtikelnummer.
articleNamestringArtikelname.
productgroupNrintegerSparten-Nummer.
productgroupNamestringSparten-Bezeichnung.
quantitydecimalStückzahl.
unitPricedecimalBrutto-Einzelpreis.
vatPercentdecimalAngewendeter Steuersatz.

Beispielantwort

200 OK · Charge + zwei Receipts (gekürzt)
{
"page": { "limit": 3, "offset": 0, "total": 8096 },
"data": [
{
"chargeType": "Charge",
"bookDate": "2026-04-15T09:15:04.95",
"receiptNr": 90,
"userId": 20,
"userName": "Johannes",
"outlet": 1,
"tableNr": 2,
"table": "Bar 2",
"totalAmount": 9.00,
"tip": 0.30,
"businesscaseId": "253c225f-7c4a-4d3f-80cd-63de4dbfca9e",
"reservationId": " 15631",
"guestId": " 6158",
"roomNumber": " 414",
"charges": [
{ "articleNr": 129, "articleName": "Zipfer 0,2", "productgroupName": "Bier", "quantity": 1.00, "unitPrice": 1.10, "vatPercent": 20.00 },
{ "articleNr": 213, "articleName": "Apfel ltg 0,5", "productgroupName": "Flaschen AF", "quantity": 1.00, "unitPrice": 2.70, "vatPercent": 20.00 },
{ "articleNr": 1626, "articleName": "Würstel Pommes", "productgroupName": "Hauptspeise", "quantity": 1.00, "unitPrice": 4.90, "vatPercent": 10.00 }
]
}
]
}

Vollständiges Beispiel (Charge + zwei Receipts) herunterladen: hotel-charges-response.json

3. Charges bestätigen

Bestätigt die erfolgreich verarbeitete Liste. Nach der Bestätigung liefert /charges mit excludeAlreadyExported=true diese businesscaseIds nicht mehr.

POST https://cloudgateway.apro.at/hotelservice/api/v1/pms/confirm-charges

Request-Body

FeldTypPflichtBeschreibung
hotelIdstringPMS-Mandant / Hotel.
transactionIdsGUID[]businesscaseId-Werte aus der vorangegangenen /charges-Antwort.
POST /hotelservice/api/v1/pms/confirm-charges
{
"hotelId": "1",
"transactionIds": [
"69F94B1A-3453-7017-8DDB-94E2175D0365",
"155FFA87-DC19-EB1F-3DD8-540EF62A115D"
]
}

Download: hotel-confirm-charges.json

4. Reservierung entfernen

Explizite Entfernung — sinnvoll beim Check-out oder wenn der Gast nicht mehr aufs Zimmer buchen darf.

DELETE https://cloudgateway.apro.at/hotelservice/api/v1/pms/reservations
?hotelId=1
&reservationId=Abc123
&guestId=Abc123

Alle drei Query-Parameter sind Pflicht. Die betroffene Reservierung wird entfernt, oder der Call ist ein No-Op, falls sie nicht existiert.

Idempotenz & Retries

  • POST /pms/reservations ist idempotent über { hotelId, Id, guestId }. Gleicher Payload → gleicher Zustand.
  • POST /pms/confirm-charges ist idempotent über transactionIds. Eine erneute Bestätigung derselben ID ist ein No-Op.
  • Poll → Confirm muss in eurem System transaktional sein: zuerst die Charges ins Journal schreiben, dann bestätigen. Schlägt die Bestätigung fehl, liefert der nächste Poll dieselben Zeilen erneut.

Fehler

Siehe Authentifizierung → Fehlerantworten. Bei fachlichen Fehlern liefert die Antwort:

{
"isSuccessfull": false,
"errorCode": 42,
"message": "No reservation found for guestId 'Abc123'.",
"context": { "guestId": "Abc123" }
}