API Documentation

Overview

The HotelifyPMS API allows you to integrate with our property management system to check room availability, create reservations, and manage bookings programmatically.

Base URL

https://your-domain.com/api/v1

Content Type

application/json

Available Endpoints

GET/availability
POST/reservations
GET/reservations
GET/reservations/:id
GET/reservations/:id/pdf
PATCH/reservations/:id
DELETE/reservations/:id

Authentication

All API requests require authentication using an API key. You can create and manage API keys from the Settings > API Keys page in your dashboard.

Request Headers

# Using Authorization header (recommended)
curl -X GET "https://your-domain.com/api/v1/availability" \
  -H "Authorization: Bearer htl_your_api_key_here"

# Or using X-API-Key header
curl -X GET "https://your-domain.com/api/v1/availability" \
  -H "X-API-Key: htl_your_api_key_here"

Keep your API keys secure

Never expose your API keys in client-side code or public repositories. Use environment variables and server-side requests only.

API Key Permissions

PermissionDescriptionEndpoints
readRead-only accessGET endpoints
writeCreate and modify resourcesPOST, PATCH, DELETE endpoints

Rate Limits

API requests are rate-limited to ensure fair usage and system stability. The default limit is 60 requests per minute per API key.

Rate Limit Headers

HeaderDescription
X-RateLimit-LimitMaximum requests per minute
X-RateLimit-RemainingRemaining requests in current window
X-RateLimit-ResetTime when the rate limit resets

Error Handling

The API returns consistent error responses with helpful error codes and messages.

Error Response Format

Error Response
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Missing required fields: checkIn, checkOut",
    "details": {
      "missingFields": ["checkIn", "checkOut"]
    }
  },
  "meta": {
    "requestId": "req_abc123def456",
    "timestamp": "2026-01-10T12:00:00.000Z"
  }
}

Error Codes

CodeHTTP StatusDescription
MISSING_API_KEY401No API key provided
INVALID_API_KEY401Invalid or unknown API key
INSUFFICIENT_PERMISSIONS403API key lacks required permission
RATE_LIMIT_EXCEEDED429Too many requests
VALIDATION_ERROR400Invalid request parameters
NOT_FOUND404Resource not found
NO_AVAILABILITY409No rooms available for dates

Check Availability

GET/availability

Returns available room types with pricing for the specified date range and guest count.

Query Parameters

ParameterTypeRequiredDescription
checkInstringCheck-in date (YYYY-MM-DD)
checkOutstringCheck-out date (YYYY-MM-DD)
adultsintegerNumber of adults (default: 2)
childrenintegerNumber of children (default: 0)
childAgesarrayAges of children for pricing
roomTypeIduuidFilter to specific room type

Example Request

curl -X GET "https://your-domain.com/api/v1/availability?checkIn=2026-02-15&checkOut=2026-02-18&adults=2&children=1&childAges=[8]" \
  -H "Authorization: Bearer htl_your_api_key"

Example Response

200 OK
{
  "success": true,
  "data": {
    "searchParams": {
      "checkIn": "2026-02-15",
      "checkOut": "2026-02-18",
      "nights": 3,
      "adults": 2,
      "children": 1,
      "childAges": [8]
    },
    "availability": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "Deluxe Double Room",
        "nameBg": "Двойна стая Делукс",
        "description": "Spacious room with mountain view",
        "roomDetails": {
          "sizeSqm": 35,
          "totalBeds": 2,
          "bedConfiguration": [
            {
              "type": "king",
              "name": "King Bed",
              "nameBg": "Голямо легло",
              "count": 1,
              "maxAdults": 2,
              "maxChildren": 1
            }
          ],
          "amenities": [
            { "id": "a1", "name": "Free WiFi", "nameBg": "Безплатен WiFi", "category": "connectivity", "icon": "wifi" },
            { "id": "a2", "name": "Air Conditioning", "nameBg": "Климатик", "category": "comfort", "icon": "air-conditioning" },
            { "id": "a3", "name": "Minibar", "nameBg": "Минибар", "category": "amenity", "icon": "minibar" }
          ]
        },
        "capacity": {
          "maxAdults": 2,
          "maxChildren": 2,
          "maxOccupancy": 4,
          "baseOccupancy": 2
        },
        "imageUrl": "https://example.com/room.jpg",
        "availableRooms": 5,
        "ratePlans": [
          {
            "id": "660e8400-e29b-41d4-a716-446655440001",
            "name": "Bed & Breakfast",
            "mealPlan": {
              "code": "BB",
              "name": "Bed & Breakfast",
              "nameBg": "Нощувка и закуска",
              "description": "Start your day with our rich buffet breakfast",
              "includes": ["Buffet breakfast", "Coffee & tea all day"],
              "breakfast": {
                "type": "buffet",
                "time": "07:00-10:00",
                "location": "Main Restaurant"
              },
              "lunch": null,
              "dinner": null,
              "serviceTimes": "Breakfast: 07:00-10:00"
            },
            "pricing": {
              "baseRoomRate": 300.00,
              "additionalAdultCharge": 0,
              "additionalChildCharge": 52.50,
              "pricePerNight": 117.50,
              "totalPrice": 352.50,
              "currency": "EUR"
            }
          }
        ]
      }
    ],
    "totalRoomTypes": 1
  },
  "meta": {
    "requestId": "req_abc123def456",
    "timestamp": "2026-01-10T12:00:00.000Z"
  }
}

Meal Plan Object

Each rate plan includes detailed meal plan information with the following structure:

FieldTypeDescription
codestringMeal plan code (RO, BB, HB, FB, AI)
namestringMeal plan name in English
nameBgstringMeal plan name in Bulgarian
descriptionstring | nullDescription of what's included
includesstring[]Array of included items/services
breakfastobject | nullBreakfast details: type, time, location
lunchobject | nullLunch details: type, time, location
dinnerobject | nullDinner details: type, time, location
serviceTimesstring | nullHuman-readable service times summary

Room Details Object

Each room type includes detailed information about the room:

FieldTypeDescription
sizeSqmnumber | nullRoom size in square meters
totalBedsnumberTotal number of beds in the room
bedConfigurationarrayArray of bed types with count and capacity
amenitiesarrayRoom amenities (WiFi, AC, TV, etc.)

Bed Configuration Object

FieldTypeDescription
typestringBed type code (king, queen, twin, single, sofa)
namestringBed name in English
nameBgstring | nullBed name in Bulgarian
countnumberNumber of this bed type in the room
maxAdultsnumberMaximum adults this bed can accommodate
maxChildrennumberMaximum children this bed can accommodate

Create Reservation

POST/reservations

Creates a new reservation with the specified details. Requires write permission.

Request Body

application/json
{
  "checkIn": "2026-02-15",
  "checkOut": "2026-02-18",
  "roomTypeId": "550e8400-e29b-41d4-a716-446655440000",
  "ratePlanId": "660e8400-e29b-41d4-a716-446655440001",
  "rooms": 1,
  "adults": 2,
  "children": 1,
  "childAges": [8],
  "guest": {
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "phone": "+359888123456",
    "nationality": "BG",
    "address": {
      "street": "123 Main Street",
      "city": "Sofia",
      "postalCode": "1000",
      "country": "BG"
    }
  },
  "specialRequests": "Late check-in around 22:00",
  "externalReference": "PARTNER-BOOKING-123"
}

Example Response

201 Created
{
  "success": true,
  "data": {
    "reservation": {
      "id": "770e8400-e29b-41d4-a716-446655440002",
      "confirmationNumber": "API-LXYZ123-AB",
      "status": "confirmed",
      "paymentStatus": "pending",
      "checkIn": "2026-02-15",
      "checkOut": "2026-02-18",
      "nights": 3,
      "roomsBooked": 1,
      "roomType": {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "Deluxe Double Room",
        "nameBg": "Двойна стая Делукс",
        "maxOccupancy": 4,
        "baseOccupancy": 2
      },
      "ratePlan": {
        "id": "660e8400-e29b-41d4-a716-446655440001",
        "name": "Bed & Breakfast",
        "mealPlan": {
          "code": "BB",
          "name": "Bed & Breakfast",
          "nameBg": "Нощувка и закуска",
          "description": "Start your day with our rich buffet breakfast",
          "includes": ["Buffet breakfast", "Coffee & tea all day"],
          "breakfast": { "type": "buffet", "time": "07:00-10:00", "location": "Main Restaurant" }
        },
        "rateCategory": { "name": "Standard", "isRefundable": true, "discountPercentage": 0 }
      },
      "guest": {
        "id": "880e8400-e29b-41d4-a716-446655440003",
        "firstName": "John",
        "lastName": "Doe",
        "email": "john.doe@example.com",
        "phone": "+359888123456",
        "nationality": "BG"
      },
      "guests": { "adults": 2, "children": 1, "childAges": [8], "total": 3 },
      "pricing": {
        "baseRoomRate": 300.00,
        "pricePerNight": 100.00,
        "additionalAdultCharge": 0,
        "additionalChildCharge": 52.50,
        "childCharges": [{ "age": 8, "percentage": 50, "charge": 52.50 }],
        "totalAmount": 352.50,
        "paidAmount": 0,
        "balanceDue": 352.50,
        "currency": "EUR",
        "dailyRates": [
          { "date": "2026-02-15", "rate": 100.00 },
          { "date": "2026-02-16", "rate": 100.00 },
          { "date": "2026-02-17", "rate": 100.00 }
        ]
      },
      "specialRequests": "Late check-in around 22:00",
      "externalReference": "PARTNER-BOOKING-123",
      "source": "api",
      "createdAt": "2026-01-10T12:00:00.000Z"
    },
    "hotel": {
      "name": "Hotel Pirin SKI & SPA",
      "phone": "+359896699009",
      "email": "sales@hotelpirin.com",
      "address": "Tsar Simeon 68, Bansko 2770",
      "checkInTime": "14:00",
      "checkOutTime": "11:00"
    },
    "links": {
      "self": "/api/v1/reservations/770e8400-e29b-41d4-a716-446655440002",
      "confirmationLink": "/api/v1/reservations/770e8400-e29b-41d4-a716-446655440002/confirmation-link",
      "pdf": "/api/v1/reservations/770e8400-e29b-41d4-a716-446655440002/pdf"
    }
  },
  "meta": {
    "requestId": "req_def456ghi789",
    "timestamp": "2026-01-10T12:00:00.000Z"
  }
}

Get Reservation

GET/reservations/:id

Retrieves detailed information about a specific reservation by ID or confirmation number.

Path Parameters

ParameterTypeDescription
idstringReservation UUID or confirmation number

Example Request

# By UUID
curl -X GET "https://your-domain.com/api/v1/reservations/770e8400-e29b-41d4-a716-446655440002" \
  -H "Authorization: Bearer htl_your_api_key"

# By confirmation number
curl -X GET "https://your-domain.com/api/v1/reservations/API-LXYZ123-AB" \
  -H "Authorization: Bearer htl_your_api_key"

Search Reservations

GET/reservations

Search reservations with various filters and pagination support.

Query Parameters

ParameterTypeDescription
confirmationNumberstringSearch by confirmation number
guestEmailstringFilter by guest email
guestNamestringSearch by guest name
checkInFromstringFilter by check-in date (from)
checkInTostringFilter by check-in date (to)
statusstringFilter by status
externalReferencestringFilter by external reference
limitintegerResults per page (max: 100)
offsetintegerPagination offset

Example Request

curl -X GET "https://your-domain.com/api/v1/reservations?checkInFrom=2026-02-01&checkInTo=2026-02-28&status=confirmed&limit=20" \
  -H "Authorization: Bearer htl_your_api_key"

Example Response

200 OK
{
  "success": true,
  "data": {
    "reservations": [
      {
        "id": "770e8400-e29b-41d4-a716-446655440002",
        "confirmationNumber": "API-LXYZ123-AB",
        "status": "confirmed",
        "paymentStatus": "pending",
        "checkIn": "2026-02-15",
        "checkOut": "2026-02-18",
        "nights": 3,
        "guests": {
          "adults": 2,
          "children": 1,
          "childAges": [8]
        },
        "roomsRequested": 1,
        "roomType": {
          "id": "550e8400-e29b-41d4-a716-446655440000",
          "name": "Deluxe Double Room",
          "nameBg": "Двойна стая Делукс"
        },
        "guest": {
          "id": "880e8400-e29b-41d4-a716-446655440003",
          "firstName": "John",
          "lastName": "Doe",
          "email": "john.doe@example.com"
        },
        "pricing": {
          "totalAmount": 352.50,
          "paidAmount": 0,
          "balance": 352.50,
          "currency": "EUR"
        },
        "createdAt": "2026-01-10T12:00:00.000Z"
      }
    ],
    "pagination": {
      "total": 42,
      "limit": 20,
      "offset": 0,
      "hasMore": true
    }
  },
  "meta": {
    "requestId": "req_ghi789jkl012",
    "timestamp": "2026-01-10T12:00:00.000Z"
  }
}

Download PDF

GET/reservations/:id/pdf

Generate and download a confirmation PDF for a specific reservation. The PDF includes hotel details, reservation dates, guest information, room details, and pricing.

Path Parameters

ParameterTypeDescription
idstringReservation UUID or confirmation number

Query Parameters

ParameterTypeDefaultDescription
formatstringbinaryOutput format: binary (direct download) or base64 (JSON with base64 encoded PDF)

Example Request

# Download PDF directly (binary)
curl -X GET "https://your-domain.com/api/v1/reservations/API-LXYZ123-AB/pdf" \
  -H "Authorization: Bearer htl_your_api_key" \
  -o confirmation.pdf

# Get PDF as base64 JSON
curl -X GET "https://your-domain.com/api/v1/reservations/API-LXYZ123-AB/pdf?format=base64" \
  -H "Authorization: Bearer htl_your_api_key"

Response (binary format)

Content-Type:application/pdf
Content-Disposition:attachment; filename="Confirmation-API-LXYZ123-AB.pdf"

Response (base64 format)

200 OK
{
  "success": true,
  "data": {
    "filename": "Confirmation-API-LXYZ123-AB.pdf",
    "contentType": "application/pdf",
    "base64": "JVBERi0xLjQKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZw..."
  },
  "meta": {
    "requestId": "req_pdf123abc456",
    "timestamp": "2026-01-10T12:00:00.000Z"
  }
}

PDF Contents

The generated PDF includes: hotel branding, confirmation number, check-in/out dates, room type, meal plan, guest details, pricing summary, payment status, and special requests.

Cancel Reservation

DELETE/reservations/:id

Important

The DELETE endpoint does not permanently delete a reservation. Instead, it changes the reservation status to cancelled and records the cancellation timestamp and reason. This preserves the booking history for auditing and reporting purposes.

Cancel a reservation by ID or confirmation number. The reservation will be marked as cancelled along with all associated room assignments and stays. Open folios will be closed.

Path Parameters

ParameterTypeDescription
idstringReservation UUID or confirmation number

Request Body (Optional)

FieldTypeDescription
reasonstringOptional reason for cancellation

Validation Rules

  • Cannot cancel a reservation that is already cancelled
  • Cannot cancel a reservation that has been checked out

Example Request

curl -X DELETE "https://api.hotelify.com/api/v1/reservations/API-LXYZ123-AB" \
  -H "Authorization: Bearer htl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"reason": "Guest requested cancellation"}'

Example Response

{
  "success": true,
  "data": {
    "reservation": {
      "id": "abc123-def456-ghi789",
      "confirmationNumber": "API-LXYZ123-AB",
      "status": "cancelled",
      "cancelledAt": "2026-01-10T14:30:00.000Z",
      "cancellationReason": "Guest requested cancellation"
    },
    "message": "Reservation cancelled successfully."
  },
  "meta": {
    "requestId": "req_cancel123",
    "timestamp": "2026-01-10T14:30:00.000Z"
  }
}

Need help? Contact us at support@hotelify.com