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.
- Host:
cloudgateway.apro.at(Pfadpräfix/hotelservice/) - Auth: API-Key im
x-api-key - Content type:
application/json - Ergänzende Referenz: api-docs.apro.at → hotelservice ↗
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/reservationsRequest-Body
Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| Reservation[] | ✅ | Eine oder mehrere Reservierungen. |
Reservation
Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| string | ✅ | Reservierungs-ID im PMS. |
| string | ✅ | PMS-Mandant / Hotel. |
| string | ✅ | Gast-ID im PMS. |
| string | ✅ | Zugewiesene Zimmernummer. |
| string | — | Anrede ( |
| string | — | |
| string | — | |
| ISO 8601 | ✅ | Check-in-Zeitpunkt. |
| ISO 8601 | ✅ | Check-out-Zeitpunkt. |
| integer | — | Personenzahl — für Covers/Buffet-Regeln. |
| Identifier[] | — | Keycard-UIDs, NFC-Tokens, Zimmer-Tablets — alle Kennungen, mit denen das POS eine Zimmerbuchung erkennen soll. |
Identifier
Feld | Typ | Beschreibung |
|---|---|---|
| string | Wert 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
Tipp
Immer den vollständigen aktiven Stand übertragen, keine Deltas.checkedOutReservationsCountzeigt an, wie viele bisher bekannte
Reservierungen nicht mehr in der Payload waren — diese werden
automatisch ausgecheckt.
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=trueQuery-Parameter
Name | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| string | ✅ | PMS-Mandant / Hotel. |
| bool | — |
|
Antwortstruktur
Jedes Element hat ein chargeType, das bestimmt welche Felder befüllt sind:
| Bedeutung |
|
|---|---|---|
| Offene Buchung aufs Zimmer (Gast hat noch nicht gezahlt — POS bucht aufs Zimmer-Folio). | nein |
| Geschlossener Beleg (Gast hat an der Kassa bezahlt; PMS kann ignorieren oder abgleichen). | ja |
Top-Level:
Feld | Typ | Beschreibung |
|---|---|---|
| integer | Angewandte Seitengröße. |
| integer | Offset im Backlog. |
| integer | Noch nicht bestätigte Einträge insgesamt. |
| Item[] | Charges und Receipts. |
Item
Feld | Typ | Beschreibung |
|---|
| `"Charge" | "Receipt"` | Siehe Tabelle oben. |
| ISO 8601 | Buchungszeitpunkt im POS. |
| integer | POS-Belegnummer. |
| integer | Bediener-ID. |
| string | Bedienername. |
| integer | Outlet-ID ( |
| integer | Tischnummer. |
| string | Tischbezeichnung. |
| decimal | Bruttosumme der Zeile. |
| decimal | Enthaltenes Trinkgeld. |
| GUID | APRO-Transaktions-ID — genau dieser Wert wandert als |
| string | null | Reservierungs-ID (bei |
| string | null | Gast-ID. |
| string | null | Zimmernummer. |
| LineItem[] | Einzelpositionen. |
| Payment[] | Nur bei |
LineItem
Feld | Typ | Beschreibung |
|---|---|---|
| integer | Artikelnummer. |
| string | Artikelname. |
| integer | Sparten-Nummer. |
| string | Sparten-Bezeichnung. |
| decimal | Stückzahl. |
| decimal | Brutto-Einzelpreis. |
| decimal | Angewendeter 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
Achtung
String-Felder wiereservationId,guestIdoderroomNumberkönnen
links mit Leerzeichen aufgefüllt sein, wenn die Kassa diese Felder
fixer Breite speichert (" 15631"). Im PMS vor dem Matchingtrim()en.
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-chargesRequest-Body
Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| string | ✅ | PMS-Mandant / Hotel. |
| GUID[] | ✅ |
|
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=Abc123Alle drei Query-Parameter sind Pflicht. Die betroffene Reservierung wird entfernt, oder der Call ist ein No-Op, falls sie nicht existiert.
Hinweis
In der Praxis reicht der Voll-Upsert aus Schritt 1 — jede Reservierung,
die nicht mehr in der Payload steht, wird automatisch ausgecheckt
(checkedOutReservationsCount). Diesen Endpunkt nur für gezielte
Out-of-Band-Entfernungen nutzen.
Idempotenz & Retries
POST /pms/reservationsist idempotent über{ hotelId, Id, guestId }. Gleicher Payload → gleicher Zustand.POST /pms/confirm-chargesist idempotent übertransactionIds. 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" }
}