CASY API

Hotel Reservation & Management API

Data Format Standards

This page documents the standard formats and structures used across all CASY API responses.

Response Format

All successful responses follow a consistent JSON structure with sensitive fields automatically removed:

{
  "ok": true,
  "requested_hotel": "9994",
  "target_db": "awscasyfront_demo_BK",
  "filters": { ... },
  "pagination": {
    "page": 1,
    "per_page": 50,
    "total": 150,
    "total_pages": 3
  },
  "sort": {
    "by": "Arrival",
    "order": "desc"
  },
  "meta": {
    "query_time_ms": 123.45
  },
  "reservations": [ ... ]
}

Note: The list key varies by endpoint (e.g., reservations, addresses, settings). When include_accounts=1 is used on reservations list endpoints, the response also appends top-level settings.meals and settings.accounts_multilanguage lookup arrays.

Date & Time Formats

Data Type Format Example Notes
Date Only YYYY-MM-DD 2026-05-21 Used for birthdays, arrival, departure dates
DateTime YYYY-MM-DD HH:MM:SS 2026-05-21 14:30:00 Server timestamps in UTC
Date Range Parameters arrival_from=YYYY-MM-DD&arrival_to=YYYY-MM-DD arrival_from=2026-05-01&arrival_to=2026-05-31 Inclusive date ranges

Currency & Numeric Formats

Data Type Format Example Notes
Price/Amount Decimal (2 places) 123.45 Always includes decimal point; 0.00 for zero
Integer IDs Numeric, no decimals 9994 CASY ID, hotel ID, reservation ID, etc.
Percentage 0-100 (decimal) 75.5 Occupancy rates, discount percentages
Boolean 0 or 1 (integer) 1 = true, 0 = false In some endpoints, may also be true/false

Location & Language Data

Data Type Format Example Notes
Country Code ISO 3166-1 alpha-2 CH, DE, IT, FR 2-letter uppercase country codes
Country (Full) ISO 3166-1 alpha-3 CHE, DEU, ITA, FRA 3-letter uppercase country codes (when extended)
Language ID Integer 1 = German, 2 = French, 3 = Italian, 4 = English System-specific language identifiers. This mapping is a common example only; values can vary by installation/CASY tenant and additional languages may be configured.
Email RFC 5322 format guest@example.com Lowercase preferred; validated on input
Phone International format (recommended) +41 44 123 4567 Spaces optional; stored as provided

Reservation Object Structure

{
  "ReservationId": 12345,
  "TitleId": 1,
  "ReservationStatus": 1,
  "ReservationType": 2,
  "Arrival": "2026-05-21",
  "Departure": "2026-05-25",
  "Person": "Doe John",
  "AddressId": 54321,
  "InvoiceAddressId": 98765,
  "NumberPersons": 2,
  "NumberOfRooms": 1,
  "TotalPrice": 450.00,
  "PaidAmount": 450.00,
  "ChannelId": 1,
  "Notify": 1,
  "CreateDate": "2026-05-20 10:30:00",
  "LastUpdateDate": "2026-05-20 14:15:00"
}

Notify is not returned by default — add fields=...,Notify to the request to include it. See Reservation Notify Flag below for details.

Reservation Notify Flag

The Notify field (integer, 0 or 1) controls whether a reservation should receive outbound communication from CASY — for example a ticket email, a pre-stay (presta) email, or any other automated guest notification. It is set per reservation directly in CASY.

Value Meaning Typical use
1 (default) Notification enabled Send ticket / presta e-mail / Deskline registration card to guest
0 Notification disabled Skip all outbound messages — e.g. internal bookings, test reservations, or guests who have opted out

How to expose it in the API: Notify is not returned by default. Add it to the fields query parameter to include it in each reservation row:

GET /v1/reservations/{casyId}?start_date=2026-06-01&end_date=2026-06-30&fields=ReservationId,Arrival,Departure,Person,Notify

To filter reservations by notify state (rather than just exposing the value) use notify_only=1 (notifiable only) or notify_only=0 (non-notifiable only; requires admin or reservations.view_non_notifiable permission).

Reservation Address Roles

Reservations can reference multiple address roles. They are distinct and should not be mixed:

Reservation Field Meaning List Endpoint Include Flag Response Key
AddressId Guest address (the person staying) include_guest_address=1 (or legacy include_address=1) guest_address (and legacy alias address)
InvoiceAddressId Billing / invoice address include_billing_address=1 billing_address
PersonId Internal link field — not exposed in API responses

Language enrichment: include_language=1 enriches each included address object with a nested language object and requires at least one address include flag.

Reservations List Example With Address Roles

GET /v1/reservations/{casyId}?start_date=2026-06-01&end_date=2026-06-30&include_guest_address=1&include_billing_address=1&include_language=1
{
    "ReservationId": 12345,
    "TitleId": 1,
    "Person": "Doe John",
    "AddressId": 54321,
    "InvoiceAddressId": 98765,
    "guest_address": {
        "AddressId": 54321,
        "FirstName": "John",
        "LastName": "Doe",
        "Street": "Main Street 1",
        "PostalCode": "8000",
        "City": "Zurich",
        "language": {
            "LanguageId": 2,
            "Abreviation": "de",
            "Language": "Deutsch"
        }
    },
    "billing_address": {
        "AddressId": 98765,
        "FirstName": "Company",
        "LastName": "AG",
        "Street": "Invoice Str. 99",
        "PostalCode": "3000",
        "City": "Bern",
        "language": {
            "LanguageId": 1,
            "Abreviation": "en",
            "Language": "English"
        }
    }
}

Room Object Structure

{
  "RoomId": 501,
  "RoomNumber": "301",
  "RoomType": "Deluxe Double",
  "FloorId": 3,
  "Beds": 1,
  "MaxCapacity": 2
}

Address Object Structure

{
  "AddressId": 54321,
  "FirstName": "John",
  "LastName": "Doe",
  "Email": "john@example.com",
  "Street": "Main Street 123",
  "Street2": "Apt 4B",
  "PostalCode": "8000",
  "City": "Zurich",
  "Country": "CH",
  "Phone": "+41 44 123 4567",
  "Mobile": "+41 79 123 4567",
  "BirthDate": "1985-03-15",
  "Nationality": "CHE"
}

Reservation Persons (Person Count by Type)

When include_persons=1 is passed, each reservation includes a persons array aggregated from active account rows (ReservationsAccounts). Each entry is one customer type with the summed number_persons and the tourism_free flag (see Customer Types).

{
  "ReservationId": 6150,
  "persons": [
    {
      "customer_type_id": 1,
      "name": "Adults",
      "tourism_free": false,
      "number_persons": 2
    },
    {
      "customer_type_id": 2,
      "name": "Children",
      "tourism_free": true,
      "number_persons": 1
    }
  ]
}

Customer Types Object Structure

Returned by GET /v1/settings/hotels/{casyId}/customer-types. The tourism_free field is derived from flag_id: false (flag_id=0) means the type is subject to the tourism tax (e.g. adults); true (flag_id=1) means exempt from tourism tax (e.g. children, seniors).

{
  "ok": true,
  "customer_types": [
    {
      "id": 1,
      "sort_order": 1,
      "flag_id": 0,
      "tourism_free": false,
      "merge": 0,
      "translations": [
        { "language_id": 1, "name": "Erwachsene" },
        { "language_id": 4, "name": "Adults" }
      ]
    },
    {
      "id": 2,
      "sort_order": 2,
      "flag_id": 1,
      "tourism_free": true,
      "merge": 0,
      "translations": [
        { "language_id": 1, "name": "Kinder" },
        { "language_id": 4, "name": "Children" }
      ]
    },
    {
      "id": 3,
      "sort_order": 3,
      "flag_id": 1,
      "tourism_free": true,
      "merge": 0,
      "translations": [
        { "language_id": 1, "name": "Senior" },
        { "language_id": 4, "name": "Senior" }
      ]
    }
  ],
  "meta": { "count": 3, "query_time_ms": 3.4 }
}

Account/Billing Object Structure

When include_accounts=1 is passed on GET /v1/reservations/{casyId} or GET /v1/reservations/{casyId}/all, each reservation includes an accounts array. Account rows keep the raw reservation-account fields and now also expose inline multilingual labels when available.

{
  "AccountId": 4099,
  "AccountOrder": 1,
  "Meals": 7,
  "Price": 180,
  "GroupId": 101,
  "PersonType": 0,
  "Active": 1,
  "ModifyDate": "2025-11-29 12:48:20",
  "NumberDays": 10,
  "NumberRooms": 1,
  "NumberPersons": 2,
  "CustomTitle": "",
  "translations": [
    {
      "AccountId": 4099,
      "LanguageId": 1,
      "Account": "Room charge",
      "Description": "English label",
      "LanguageAbbreviation": "ENG",
      "Language": "English"
    },
    {
      "AccountId": 4099,
      "LanguageId": 2,
      "Account": "Zimmerpreis",
      "Description": "German label",
      "LanguageAbbreviation": "DEU",
      "Language": "German"
    }
  ]
}

Lookup compatibility: the same multilingual label set remains available at top level in settings.accounts_multilanguage for callers that prefer a deduplicated reference table.

Settings & Reference Data

Reference data objects use consistent naming conventions:

// Reservation Statuses
{
  "ReservationStatusId": 1,
  "ReservationStatus": "Confirmed",
  "ReservationStatusOrder": 1,
  "ReservationColor": "#00AA00",
  "translations": [
    { "LanguageId": 1, "ReservationStatusName": "Bestätigt" },
    { "LanguageId": 2, "ReservationStatusName": "Confirmé" }
  ]
}

// Channels
{
  "ChannelId": 1,
  "Name": "Direct",
  "ChannelOrder": 1,
  "ChannelColor": "#0066CC"
}

// Meals
{
  "MealId": 4,
  "Abbreviation": "ZF",
  "MealOrder": 1,
  "Breakfast": 1,
  "Lunch": 0,
  "Dinner": 0,
  "Night": 1
}

Authentication & Pagination

Authorization Header

Authorization: Bearer your-token-value-here

Token values are 32+ character alphanumeric strings, case-sensitive.

Pagination Parameters

Parameter Type Default Description
page integer 1 Current page number (1-indexed)
limit / per_page integer 50 (or 100) Results per page (max: 1000)
sort_by string Arrival Field to sort by
sort_order string desc Sort direction: asc or desc

Response Pagination Structure

{
  "pagination": {
    "page": 1,
    "per_page": 50,
    "total": 250,
    "total_pages": 5,
    "has_next": true,
    "has_prev": false
  },
  "sort": {
    "by": "Arrival",
    "order": "desc"
  }
}

Field Selection (Where Supported)

Some endpoints support selective field retrieval:

GET /v1/reservations/9994?fields=ReservationId,GuestFirstName,Arrival,TotalPrice

This optimizes bandwidth by returning only needed fields. Only "safe" fields are allowed; sensitive data is filtered automatically.