Guida integrazione AlpineBits
Questa guida è rivolta a fornitori/PMS (property management system) che vogliono sincronizzare disponibilità, tariffe e prenotazioni con la piattaforma tramite il protocollo standard AlpineBits.
Cos'è AlpineBits
AlpineBits è un protocollo standard aperto per lo scambio di dati tra sistemi alberghieri (PMS/channel manager) e piattaforme di distribuzione, basato su XML OTA (OpenTravel Alliance) trasportato via HTTP. È largamente adottato nell'area alpina (Alto Adige, Trentino, Tirolo) per la sincronizzazione di inventario, tariffe e prenotazioni.
La piattaforma implementa la versione 2024-10 dello standard, come server (riceve richieste da PMS/channel manager esterni). Per la specifica completa del protocollo, consulta alpinebits.org.
Versione supportata:
2024-10è l'unica versione di protocollo accettata dal server. Richieste con un header di versione diverso vengono rifiutate con un erroreOTA_Error(nessun negoziato multi-versione).
Come ottenere le credenziali
Le credenziali di accesso (username e password) non si ottengono tramite autoregistrazione: vengono create dal referente commerciale/tecnico della struttura con cui stai integrando (il tenant che ti ha richiesto la connessione AlpineBits). Contatta direttamente il tuo interlocutore presso la struttura per richiedere un account fornitore.
Ogni account fornitore è associato a una singola struttura (multi-tenant): le credenziali che ricevi valgono solo per i dati di quella struttura.
Endpoint
POST https://<host>/api/alpinebits
Content-Type: multipart/form-data
Dove <host> è il dominio della piattaforma della struttura con cui stai
integrando (es. www.tripmaster.cloud o un dominio custom del tenant).
Autenticazione
L'endpoint usa HTTP Basic Authentication sulle credenziali dell'account fornitore:
Authorization: Basic base64(username:password)
Le credenziali NON sono legate a un utente della piattaforma: sono un account fornitore dedicato, creato appositamente per l'integrazione AlpineBits.
Header obbligatorio
Ogni richiesta deve includere l'header di versione protocollo:
X-AlpineBits-ClientProtocolVersion: 2024-10
Senza questo header la richiesta viene rifiutata con 400 Bad Request. Con un
valore diverso da 2024-10 la richiesta viene rifiutata con una risposta
OTA_Error XML (200 con <Errors> nel corpo, come da standard AlpineBits).
Formato della richiesta: multipart action + request
Il body è multipart/form-data con due campi:
| Campo | Descrizione |
|---|---|
action |
Identifica l'azione AlpineBits richiesta (vedi tabella sotto) |
request |
Il messaggio XML OTA della richiesta (es. OTA_PingRQ, ecc.) |
Azioni supportate
Azione (action) |
Messaggio richiesta → risposta | Capacità dichiarate |
|---|---|---|
OTA_Ping:Handshaking |
OTA_PingRQ → OTA_PingRS |
Scambio capacità/versioni supportate |
OTA_HotelDescriptiveContentNotif:Inventory |
OTA_HotelDescriptiveContentNotifRQ → ...RS |
Sincronizzazione tipi camera/inventory |
OTA_HotelRatePlanNotif:RatePlans |
OTA_HotelRatePlanNotifRQ → ...RS |
NotifType Full, Overlay e Remove — dettagli nella sezione RatePlans: Full, Overlay, Remove |
OTA_HotelInvCountNotif:FreeRooms |
OTA_HotelInvCountNotifRQ → ...RS |
UniqueID/@Instance="CompleteSet" (reset completo) e modalità delta (upsert incrementale, non tocca i giorni non inclusi) |
OTA_Read:GuestRequests (pull) |
OTA_ReadRQ → OTA_ResRetrieveRS |
Estrazione prenotazioni in coda (batch max 50, per data creazione) |
OTA_NotifReport:GuestRequests (ack) |
OTA_NotifReportRQ → OTA_NotifReportRS |
Acknowledgment delle prenotazioni ricevute (marca come "consegnate/lette") |
Ogni richiesta viene validata contro lo schema XSD AlpineBits prima del routing: un XML non conforme produce sempre una risposta di errore coerente, anche per azioni non riconosciute o non ancora supportate.
RatePlans: Full, Overlay, Remove
L'azione OTA_HotelRatePlanNotif:RatePlans accetta tre valori di
RatePlanNotifType:
- Full — replace completo del listino mappato al rate plan: periodi,
quote, supplementi, servizi, scontistiche e riduzioni vengono ricostruiti
da zero a partire dal messaggio. I dati inseriti a mano sul listino
(agenzie, gruppo/profili, gratuità, pagamenti, stop-sale manuali,
formato/
MinPax) vengono azzerati a ogni Full. - Overlay — aggiornamento parziale, solo dati date-dependent:
identifica il rate plan per
RatePlanCodee sostituisce soltanto ciò che viene effettivamente trasmesso. Un elemento assente dal messaggio resta intatto; un elemento presente ma vuoto (es.<Rates/>) cancella i dati corrispondenti già presenti sul listino. Non tocca mai i dati manuali elencati sopra, né lo static rate, le descrizioni statiche o leOffers(non modificabili via Overlay dalla spec: se trasmesse producono un warning e vengono ignorate). - Remove — cancella il listino mappato al rate plan.
Capacità dichiarate in handshake
Per action_OTA_HotelRatePlanNotif_RatePlans il server dichiara:
accept_full, accept_overlay, accept_Supplements, accept_FreeNightsOffers,
accept_FamilyOffers, accept_ArrivalDOW, accept_DepartureDOW,
accept_RatePlan_BookingRule, accept_OfferRule_DOWLOS. Per
action_OTA_HotelDescriptiveContentNotif_Inventory: use_rooms e
occupancy_children.
Non dichiarate (fase successiva): accept_RatePlanJoin, BookingRule per
singola camera (RoomType/mixed BookingRule), accept_OfferRule_BookingOffset,
ChargeTypeCode=12, PrerequisiteInventory con InvCode=ALPINEBITSDOW, DOW
sulle Offers. Se il PMS li invia comunque non è mai un errore bloccante: la
piattaforma li ignora e riporta un warning nella risposta.
Overlay: split automatico dei periodi e snapshot
Ogni <Rate InvTypeCode Start End> trasmessa individua il periodo del
listino che copre esattamente quel range. Se il range non corrisponde a un
periodo esistente, i periodi che lo intersecano solo in parte vengono
spezzati automaticamente sui confini del range trasmesso, in modo che le
tariffe trasmesse si applichino esattamente al range dichiarato senza
toccare le date adiacenti; i frammenti generati dallo split che restano
identici tra loro vengono poi fusi di nuovo a fine elaborazione, per non
lasciare il listino frammentato inutilmente. Un range che attraversa un
"buco" del listino (nessun periodo esistente lo copre interamente) è un
errore bloccante: in quel caso serve un Full.
Prima della prima modifica di un Overlay sul listino, la piattaforma crea in
automatico uno snapshot (nome AlpineBits pre-overlay <yyyy-MM-dd>,
massimo uno al giorno per listino), così un aggiornamento errato può
sempre essere ripristinato manualmente dall'interfaccia.
Semantica delle date: come da spec AlpineBits 4.4 ("departure ≤ End + 1"),
Start/Enddi rate e booking rule indicano cheEndè l'ultima notte inclusa, non la data di check-out. La piattaforma memorizza internamente la data di check-out (esclusiva): ogniEndricevuto viene convertito inEnd + 1prima di essere applicato a periodi e calendari.
Supplements: mapping su ChargeTypeCode
Per ogni InvCode è previsto un supplement statico
(MandatoryIndicator, ChargeTypeCode, descrizioni) più eventuali
supplement date-dependent con l'importo. In base a MandatoryIndicator e
ChargeTypeCode il comportamento sulla piattaforma cambia:
ChargeTypeCode |
Unità di misura (spec OTA) | MandatoryIndicator=true |
MandatoryIndicator=false |
|---|---|---|---|
19 |
per camera, per notte | applicato sempre, ogni notte | proposto come extra su richiesta |
21 |
per persona, per notte | applicato sempre, ogni notte per persona | proposto come extra su richiesta |
1 |
per item, per giorno | applicato sempre, ogni notte | proposto come extra su richiesta |
18 |
per camera, per soggiorno | applicato automaticamente una tantum | proposto come extra su richiesta |
20 |
per persona, per soggiorno | applicato automaticamente una tantum | proposto come extra su richiesta |
24 |
per item, per soggiorno | applicato automaticamente una tantum | proposto come extra su richiesta |
12 |
legacy, non presente nella spec 2024-10 | ignorato, warning | ignorato, warning |
In Overlay solo i prezzi date-dependent dei supplement possono essere
aggiornati (Start/End/Amount nel range trasmesso); il supplement
statico (definizione, obbligatorietà, ChargeTypeCode) non è modificabile
via Overlay e va ridichiarato con un Full.
Offerte supportate (Offers)
Ogni rate plan può avere fino a 3 Offer. Sono riconosciute:
- Notti gratis —
Discount Percent="100"conNightsRequired/NightsDiscounted(ed eventualeDiscountPatternper distribuire le notti gratis lungo il soggiorno invece di raggrupparle tutte alla fine): tradotta in una scontistica "notti gratis" applicata dal motore di calcolo (es. soggiorno di 7 notti pagate 6). - Family —
Discount Percent="100"conGuests/Guest AgeQualifyingCode="8"(bambino): tradotta in bambini gratuiti per posizione letto, secondo i vincoli di età dichiarati nell'offerta. - Ogni altra
Offer(non free-nights, non family) → warning "Offer non supportata", ignorata. - Le
Offerstrasmesse in un messaggio Overlay vengono sempre ignorate con warning: la spec AlpineBits non ammette la modifica delle offerte fuori da un Full.
Occupancy
Il prezzo base del listino corrisponde alla tariffa dichiarata per un numero
di ospiti pari alla StandardOccupancy della camera, letta
dall'Inventory (GuestRoom/Occupancy/@StandardOccupancy; se non dichiarata,
il default è 2). Tariffe trasmesse per un numero di ospiti diverso dallo
standard (BaseByGuestAmt con NumberOfGuests ≠ standard) generano
automaticamente supplementi di sottoccupazione (meno ospiti dello standard,
es. singola in doppia) o riduzioni per i letti aggiuntivi (più ospiti dello
standard). In un Overlay, se una rate ritrasmette valori di occupancy diversi
dallo standard queste righe derivate vengono ricalcolate e sostituite; se
l'elemento non viene ritrasmesso, quelle già presenti restano intatte.
Esempio curl: handshake completo
curl -X POST "https://<host>/api/alpinebits" \
-u "<username>:<password>" \
-H "X-AlpineBits-ClientProtocolVersion: 2024-10" \
-F "action=OTA_Ping:Handshaking" \
-F "request=<OTA_PingRQ xmlns=\"http://www.opentravel.org/OTA/2003/05\" Version=\"8.000\"><EchoData>{\"versions\":[{\"version\":\"2024-10\",\"actions\":[{\"action\":\"action_OTA_HotelRatePlanNotif_RatePlans\"},{\"action\":\"action_OTA_HotelInvCountNotif\"}]}]}</EchoData></OTA_PingRQ>"
La risposta è un OTA_PingRS XML con header X-AlpineBits-Server: BCMS e, in
assenza di errori, nessun elemento <Errors> nel corpo.
Download XSD e campioni
Scarica lo schema XSD usato per validare richieste e risposte.
Campioni XML di riferimento (
multipartfieldrequest):Campione Link Handshake — richiesta ( OTA_PingRQ)Scarica Handshake — risposta ( OTA_PingRS)Scarica Inventory — richiesta base Scarica RatePlans — richiesta Scarica FreeRooms — richiesta Scarica GuestRequests — risposta con prenotazione Scarica
Codici di errore comuni
| Codice / risposta | Significato |
|---|---|
401 Unauthorized |
Credenziali mancanti, errate o account fornitore disattivato |
402 Payment Required |
L'abbonamento della struttura non è attivo (trial scaduto/cancellato) oppure il pacchetto Channel Manager non è attivo per la struttura (corpo JSON error distingue i due casi) |
400 Bad Request — ERR:no protocol version |
Header X-AlpineBits-ClientProtocolVersion mancante |
OTA_Error — ERR:unsupported protocol version |
Header di versione presente ma diverso da 2024-10 |
OTA_*RS con <Errors> — ERR:... |
Errore di validazione XSD, azione sconosciuta o errore di business specifico dell'azione |
Tutti i tentativi (accettati o rifiutati) vengono registrati lato piattaforma per finalità di audit e supporto.
Flusso consigliato
- Handshake (
OTA_Ping:Handshaking) — verifica connettività e scambia le capacità supportate dalle due parti. - Inventory (
OTA_HotelDescriptiveContentNotif:Inventory) — sincronizza i tipi camera prima di inviare tariffe o disponibilità. - RatePlans (
OTA_HotelRatePlanNotif:RatePlans) — invia i listini tariffari. - FreeRooms (
OTA_HotelInvCountNotif:FreeRooms) — invia la disponibilità (consigliato unCompleteSetiniziale, poi aggiornamenti in delta). - GuestRequests — effettua periodicamente il pull (
OTA_Read) delle nuove prenotazioni e invia l'ack (OTA_NotifReport) una volta che il PMS le ha importate correttamente, per evitare di riceverle di nuovo nel pull successivo.