Beginner5 min read

Quick Start

Make your first Hotel Data API call and build a foundation for integrating room and property data into your application.

1

Fetch all properties

The /properties endpoint returns all registered hotel properties. This is usually the starting point for any integration.

Step 1
javascript
"color:#c4b5fd">const BASE_URL = "https:">//hotel-data.k3s.ahsm-krakow.com/api/v1";

"color:#c4b5fd">const response = "color:#c4b5fd">await fetch("color:#86efac">`${BASE_URL}/properties`);

"color:#c4b5fd">if (!response.ok) {
  "color:#c4b5fd">throw "color:#c4b5fd">new Error("color:#86efac">`API error: ${response.status}`);
}

"color:#c4b5fd">const { data } = "color:#c4b5fd">await response.json();
console.log(data); "color:#6b7280">// Property[]

Example response

json
{
  "data": [
    {
      "id": "apt",
      "name": "Aparthotel Stare Miasto",
      "slug": "aparthotel-stare-miasto",
      "enabled": true,
      "total_rooms": 32
    },
    {
      "id": "krw",
      "name": "Krowoderska 66B Apartments",
      "slug": "krowoderska-66b",
      "enabled": true,
      "total_rooms": 12
    }
  ]
}
2

Explore room types

Room types define the template for rooms — amenities, size, and category. Filter by property_id, category, has_balcony, and more.

Step 2
javascript
"color:#c4b5fd">const BASE_URL = "https:">//hotel-data.k3s.ahsm-krakow.com/api/v1";

"color:#6b7280">// List all room types for a property
"color:#c4b5fd">const response = "color:#c4b5fd">await fetch("color:#86efac">`${BASE_URL}/room-types?property_id=apt`);
"color:#c4b5fd">const { data: roomTypes } = "color:#c4b5fd">await response.json();

"color:#6b7280">// Find all suites with balconies
"color:#c4b5fd">const suitesWithBalconies = "color:#c4b5fd">await fetch(
  "color:#86efac">`${BASE_URL}/room-types?property_id=apt&category=suite&has_balcony=true`
).then((r) => r.json());

Example response

json
{
  "data": [
    {
      "id": "apt-penthouse",
      "property_id": "apt",
      "name": "Penthouse Suite",
      "category": "suite",
      "max_guests": 4,
      "size_m2": 85,
      "has_hot_tub": true,
      "has_balcony": true,
      "is_duplex": true,
      "active": true
    }
  ]
}
3

Look up individual rooms

Individual rooms are physical units within a property. Always pass property_id when fetching a single room — room numbers are not globally unique across properties.

Step 3
javascript
"color:#c4b5fd">const BASE_URL = "https:">//hotel-data.k3s.ahsm-krakow.com/api/v1";

"color:#6b7280">// All rooms on floor 3 at apt
"color:#c4b5fd">const response = "color:#c4b5fd">await fetch(
  "color:#86efac">`${BASE_URL}/rooms?property_id=apt&floor=3`
);
"color:#c4b5fd">const { data: rooms } = "color:#c4b5fd">await response.json();

"color:#6b7280">// Single room lookup (property_id is required)
"color:#c4b5fd">const room = "color:#c4b5fd">await fetch(
  "color:#86efac">`${BASE_URL}/rooms/301?property_id=apt`
).then((r) => r.json());

Example response

json
{
  "data": {
    "number": "301",
    "property_id": "apt",
    "floor": 3,
    "room_type_id": "apt-studio",
    "active": true,
    "room_type": {
      "id": "apt-studio",
      "name": "Studio",
      "max_guests": 2,
      "size_m2": 28
    }
  }
}

Production tips

Error handling with retries

Network errors and transient server failures happen. Use exponential backoff to retry safely.

retry.ts
javascript
"color:#c4b5fd">async "color:#c4b5fd">function fetchWithRetry(url: string, retries = 3): Promise<Response> {
  for ("color:#c4b5fd">let attempt = 0; attempt < retries; attempt++) {
    "color:#c4b5fd">try {
      "color:#c4b5fd">const response = "color:#c4b5fd">await fetch(url, {
        signal: AbortSignal.timeout(10_000), "color:#6b7280">// 10s timeout
      });

      "color:#6b7280">// Don't retry client errors (4xx)
      "color:#c4b5fd">if (response.status >= 400 && response.status < 500) {
        "color:#c4b5fd">throw "color:#c4b5fd">new Error("color:#86efac">`Client error ${response.status}`);
      }

      "color:#c4b5fd">if (!response.ok) {
        "color:#c4b5fd">throw "color:#c4b5fd">new Error("color:#86efac">`Server error ${response.status}`);
      }

      "color:#c4b5fd">return response;
    } "color:#c4b5fd">catch (err) {
      "color:#c4b5fd">if (attempt === retries - 1) "color:#c4b5fd">throw err;
      "color:#6b7280">// Exponential backoff: 1s, 2s, 4s
      "color:#c4b5fd">await "color:#c4b5fd">new Promise((r) => setTimeout(r, 1000 * 2 ** attempt));
    }
  }
  "color:#c4b5fd">throw "color:#c4b5fd">new Error("Max retries exceeded");
}

Client-side caching

Property and room-type data changes infrequently. Cache responses on the client to reduce latency and server load.

cache.ts
javascript
"color:#6b7280">// Cache property list for 5 minutes
"color:#c4b5fd">const CACHE_TTL_MS = 5 * 60 * 1000;
"color:#c4b5fd">const cache = "color:#c4b5fd">new Map<string, { data: unknown; expiresAt: number }>();

"color:#c4b5fd">async "color:#c4b5fd">function fetchCached(url: string): Promise<unknown> {
  "color:#c4b5fd">const cached = cache.get(url);
  "color:#c4b5fd">if (cached && cached.expiresAt > Date.now()) {
    "color:#c4b5fd">return cached.data;
  }

  "color:#c4b5fd">const response = "color:#c4b5fd">await fetch(url);
  "color:#c4b5fd">const data = "color:#c4b5fd">await response.json();

  cache.set(url, { data, expiresAt: Date.now() + CACHE_TTL_MS });
  "color:#c4b5fd">return data;
}

"color:#6b7280">// Usage
"color:#c4b5fd">const properties = "color:#c4b5fd">await fetchCached("color:#86efac">`${BASE_URL}/properties`);

Recommended cache TTLs

ResourceSuggested TTL
Properties5 minutes
Room Types5 minutes
Rooms2 minutes
Summary1 minute
Issues30 seconds
Maintenance Schedules1 minute