Skip to main content

Direct Hotel Contracts

Direct contracts are pre-negotiated deals with specific hotels — guaranteed inventory and locked rates for a known airport. They participate in the allocation just like any other provider, with a few advantages.

Why contracts beat GDS

  • Rate certainty — locked for the contract period; no surprise at check-in.
  • Guaranteed inventory — rooms are held; no surge-pricing stock-outs during a disruption.
  • Margin transparency — Nexa surfaces savingsVsMarket, giving finance a clean report for each booking.
  • Faster inventory update — no provider callback; Nexa decrements its own counter on confirmation.

Loading a contract

Contracts are CSV/JSON-imported via the Ops Console or the admin API.

curl -X POST https://us-central1.api.nexastudio.io/contracts \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Ibis MAD — 2026 T2",
"airport": "MAD",
"hotel": {
"name": "Ibis Madrid Aeropuerto Barajas",
"address": "…",
"location": { "lat": 40.47, "lon": -3.58 },
"stars": 3,
"externalIds": {
"amadeus": "HTLABCMAD",
"hotelbeds": "12345"
}
},
"rates": [
{ "from": "2026-04-01", "to": "2026-06-30",
"roomType": "STANDARD", "nightlyRate": 95, "currency": "EUR",
"guaranteedRooms": 30 }
],
"acceptedPayments": ["GUARANTEE"],
"terms": "Late cancellation 24h; early check-in included."
}'

Key fields:

  • externalIds — the same hotel may appear in Amadeus and Hotelbeds. Listing the provider IDs enables cross-provider deduplication so Nexa doesn't double-count the same property.
  • rates — date-bounded; a contract can have several rate tiers.
  • guaranteedRooms — the cap Nexa will draw from. Bookings decrement it; cancellations restore it.

Dedup across providers

When allocation runs, Nexa:

  1. Searches Amadeus and Hotelbeds.
  2. Pulls matching contracts (by airport + date range).
  3. Deduplicates: provider-id matches via externalIds, then geo+stars, then name+address.
  4. Prefers the contract offer when a hotel is matched — cheapest rate + guaranteed inventory.

Inventory accounting

Contract:      Ibis MAD — 30 rooms
Case A books: 10 rooms → remaining 20
Case B books: 8 rooms → remaining 12
Case A cancels 4 rooms → remaining 16

Nexa persists a ledger per contract so you can audit inventory movements.

Savings vs market

On every booking against a direct contract, Nexa records:

{
"contractRate": 95,
"lowestGdsRate": 112,
"savingsPerNight": 17,
"savingsTotal": 17 * rooms * nights,
"currency": "EUR"
}

This drives the weekly finance report and the CFO dashboard.

When contracts expire

Nexa treats expired contracts as absent — the hotel falls back to GDS pricing. Expiring contracts produce a warning in the Ops Console 14 days before expiry so procurement has time to renegotiate.

Admin actions

  • Adjust inventoryPOST /contracts/:urn/inventory when the hotel releases extra rooms.
  • DeactivatePOST /contracts/:urn/deactivate when a hotel pulls out mid-contract; active bookings are unaffected; new allocations won't pick this contract.
  • Bulk importPOST /contracts/bulk for annual procurement refreshes.

All of these are audit-logged with the actor and reason.

Was this helpful?