######################## HORES HTTP API / Web API ######################## ******************* General information ******************* HORES Web api interface acts as HTTP server. Communication is done via HTTPS protocol. Unencrypted connection is available only for testing purposes. SSL is used only to encrypt communication, no client authentication based on SSL certificates is currently available. Data are transfered in JSON format (you must use "Content-Type: application/json" header for POST requests!). Only methods corresponding to actions allowed by user-rights of user, who's credentials are used to access API, are allowed. Authentication is done via HTTP Authorization header. Depending on configuration, two methods of authentication are available: HTTP Basic authentication (RFC 2617) ==================================== Used for testing and legacy purpose. Login and password are checked against HORES users database. User must have "API access" enabled to use this login method. .. warning:: Do not use Basic authentication for production implementation. Permanent token =============== Can be defined for each user in HORES and allows for non-interactive authentication of API operations in the name of that user. Use "Authorization" header with "Token" keyword such as: .. sourcecode:: http GET /api/rooms HTTP/1.1 Host: example.com Accept: application/json Authorization: Token 65sad4f64df6sd6f4sdffassdfa *********** Data format *********** Request format ============== No common data-structure Response format =============== Returned data have common JSON structure: .. sourcecode:: json { "result": 0, "error": null, "warning": null, "data": null } * **result**: result code, 0 for success, non-zero for errors * **error**: optional error message (only when result != 0) * **warning**: optional warning message * **data**: returned data. May be empty or not present when no results found or when calling method without return value Sample success response: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "result": 0, "data": [ { "id": 120, "code": "118", "room_type_id": 2, "description": "DBL", "floor": 0, "beds": 2, "room_service_code": null, "phone_number": 118, "attr_1": null, "attr_2": null, "floor_code": "1", "building": null, "clean": false, "inspection": true, "used": true, "ord": 26 } ] } Sample error response: .. sourcecode:: http HTTP/1.1 404 Not Found Vary: Accept Content-Type: application/json { "result": 1, "error": "Guest account not found!", "data": null } *************** API description *************** .. http:get:: /api/hores_info Version and build info about running instance .. http:get:: /api/rooms List of existing rooms **Example response**: .. sourcecode:: json [ { "id": 120, "code": "118", "room_type_id": 2, "description": "DBL", "floor": 0, "beds": 2, "room_service_code": null, "phone_number": 118, "attr_1": null, "attr_2": null, "floor_code": "1", "building": null, "clean": false, "inspection": true, "used": true, "ord": 26 } ] :>json int id: Unique identifier :>json string code: Code :>json int room_type_id: Type :>json string description: Description :>json int floor: Floor :>json int beds: Number of beds :>json string room_service_code: Maid's code :>json string phone_number: Phone number :>json string attr_1: Attribute 1 :>json string attr_2: Attribute 2 :>json string floor_code: Floor code :>json string building: Building code :>json boolean clean: Cleaned :>json boolean inspection: Inspection required :>json boolean used: Used :>json int ord: Display order number .. http:get:: /api/roomTypes List of existing room types **Example response**: .. sourcecode:: json [ { "id": 10, "code": "DBL", "description": "Double", "beds": 2, "rooms_cnt": 20, "rooms_total": 30, "pricelist_code": "DB", "technical": false, "multi": false, "ord": 1, "translation": { "cs": null, "de": null, "en": null } } ] :>json int id: Unique identifier :>json string code: Code :>json string description: Room type description :>json int beds: Standard number of beds for room type :>json int rooms_cnt: Internal use :>json int rooms_total: Internal use :>json string pricelist_code: Internal use :>json boolean technical: True for technical rooms :>json boolean multi: Internal use :>json int ord: Display order number :>json dict translation: Dictionary of available translations, may be empty or null .. http:get:: /api/rasters List of existing rasters **Example response**: .. sourcecode:: json [ { "id": 2, "code": "AR", "name": "Aranzma", "type": 3, "accounting_group": 5, "cash_register_code": 0, "variant": 1, "vat": "0.0", "promote_to_cash": false, "print_description": false, "translation": { "cs": null, "de": null, "en": null }, "ord": 2, "allow_discount": true, "exclude_from_income": false } ] :>json int id: Unique identifier :>json string code: Raster code :>json string name: Raster name :>json int type: Raster type: 1 = Accommodation, 2 = F&B, 3 = Other :>json int variant: Raster variant: 1 = revenue, 2 = prepayment, 3 = other. A variant is valid only for type = 3, rasters with type = 1 or 2 have no variants (variant = 0) :>json int accounting_group: Accounting group :>json int cash_register_code: Used for statistical/internal purpose :>json int variant: Raster variant: 1 = revenue, 2 = prepayment, 3 = other. A variant is valid only for type = 3, rasters with type = 1 or 2 have no variants (variant = 0) :>json numeric vat: VAT value in percent (e.g., 21.0) :>json boolean promote_to_cash: Project into cash :>json boolean print_description: If true, description can be printed on receipt :>json int ord: Use defined order :>json boolean allow_discount: If true, discount can be used with this raster :>json boolean exclude_from_income: If true, cass office items with this raster should not be included in certain reports :>json dict translation: Dictionary of available translations, may be empty or null .. http:get:: /api/fandb_codes List of existing fandb codes **Example response**: .. sourcecode:: json [ { "id": 7, "code": "LUN2", "name": "Small Buffet Lunch", "meal_category": "breakfast", "price": "12.00", "currency_id": 1, "raster_id": 3, "meal_type": "food", "ord": null, "translation": null }, ] :>json int id: Unique identifier :>json string code: FandB code :>json string name: FandB name :>json string meal_category: 'breakfast', 'dinner', 'supper', 'half_board', 'full_board', 'all_inclusive', 'other' :>json numeric price: Predefined unit price :>json int currency_id: Price currency :>json int raster_id: Price raster :>json string meal_type: 'food', 'beverage' :>json int ord: Use defined order :>json dict translation: Dictionary of available translations, may be empty or null .. http:get:: /api/fandb List of fandb codes usage for specified period :query date date_from: Filter data from date :query date date_to: Filter data to date **Example response**: .. sourcecode:: json [ { "fb_code": "SN", "fb_name": "Snídaně", "quantity": 1, "price": "50.00", "note": null, "currency_code": "EUR", "center_name": null, "isgroup": false, "title": "FBTEST", "checkin_date": "2023-06-20", "checkout_date": "2023-06-23", "rooms": "116", "source_id": 4 }, ] :>json int id: Unique identifier :>json string fb_code: FandB code :>json string fb_name: FandB name :>json int quantity: Meal count :>json numeric price: Unit price :>json string note: Note for given serving :>json string currency_code: Currency code :>json string center_name: Center name :>json boolean isgroup: True if fandb is part of group reservation :>json string title: guest or reservation name :>json date checkin_date": guest checkin date :>json date checkout_date: guest checkout date :>json string rooms: Room numbers :>json string source_id": Reservation source ID .. http:get:: /api/pricelists List of existing pricelists **Example response**: .. sourcecode:: json [ { "id": 6, "code": "AVP", "name": "Availpro", "description": "w ddrf", "price_calculation": 2, "accomodation_currency_id": 2, "accomodation_raster_id": 56, "breakfast_raster_id": 51, "breakfast_currency_id": 2, "breakfast_price": "50.00", "breakfast_in_accomodation": true, "breakfast_bill_separately": false, "city_fee_raster_id": 25, "city_fee_currency_id": 2, "city_fee": "0.50", "city_fee_in_accomodation": false, "city_fee_bill_separately": false, "ignore_zero_price": false, "ord": null, "raster_1_id": 3, "raster_1_price": "266.00", "raster_1_in_accomodation": false, "raster_2_id": null, "raster_2_price": "0.00", "raster_2_in_accomodation": false, "raster_3_id": null, "raster_3_price": "0.00", "raster_3_in_accomodation": false, "raster_4_id": null, "raster_4_price": "0.00", "raster_4_in_accomodation": false, "raster_5_id": null, "raster_5_price": "0.00", "raster_5_in_accomodation": false, "city_fee_force_guest_account": true, "deleted": false } ] .. http:get:: /api/reservation_sources List of existing reservation_sources **Example response**: .. sourcecode:: json [ { "id": 2, "code": "W", "name": "WEB", } ] :>json int id: Unique identifier :>json string code: Source code :>json string name: Source name .. http:get:: /api/packages List of existing packages. Packages can be used instead of simple prices for each date of stay. Package contains one or more raster items each with given price. When printing guest account, only package name/code is shown to guest, but internally items are stored and processed for reports/accounting exports by rasters inside package. Optionally package may contain date-specific raster items (date_specific = true). Such items are charged to guest-account only when charge-date corresponds to rasters date_from/date_to dates. In this case, package has varying price depending on date when charged. **Example response**: .. sourcecode:: json [ { "id": 2, "code": "FL", "name": "Flowers", "description": "Fresh flowers in room before arrival", "currency_id": 3, "single_value": false, "include_accomodation": false, "translation": { "cs": null, "de": null, "en": null }, "ord": 2, "date_specific": true, "rasters": [ { "id": 9, "packages_id": 2, "rasters_id": 43, "price": "20.00", "date_from": "2017-10-20", "date_to": "2017-11-20" } ] } ] :>json int id: Unique identifier :>json string code: Package code :>json string name: Package name :>json string description: Package description :>json int currency_id: Package currency :>json boolean single_value: When true, package is charge to guest-account as single item, all raster items are kept internal. When false, package is broken to raster items when charge to guest account. :>json boolean include_accomodation: When true, accomodation price from pricelist is embedded to package when package is charged to guest-account :>json boolean date_specific: True value indicates that some raster items may have date-specific validity :>json int ord: Use defined order :>json dict translation: Dictionary of available translations, may be empty or null rasters :>json int id: Unique identifier of given package-raster item :>json int packages_id: Parent package id :>json int rasters_id: ID of corresponding raster, see :http:get:`/api/rasters` :>json decimal price: Item price :>json date date_from: Item is valid/usable only from this date :>json date date_to: Item is valid/usable only until this date .. http:get:: /api/payment_methods List of available payment methods **Example response**: .. sourcecode:: json [ { "id": 2, "code": "C", "name": "Cred.card", "type": 2, "translation": null, "rounding": false } ] :>json int id: Unique identifier :>json string code: Payment method code :>json string name: Payment method name :>json int type: Type: 1 = cash, 2 = payment/credit card, 3 = foreign currency, 4 = other, 5 = invoice :>json boolean rounding: If true, total receipt payment in cash should be rounded according currency settings :>json dict translation: Dictionary of available translations, may be empty or null .. http:get:: /api/payment_card_types List of available payment card types **Example response**: .. sourcecode:: json [ { "id": 4, "code": "MA", "name": "Maestro", "text": null, "limit": 999999, "bonus": "0.00", "type_id": 12, "ord": 4 } ] :>json int id: Unique identifier :>json string code: Card type code :>json string name: Card type name :>json string text: Text :>json int limit: :>json numeric bonus: Commissions (%) :>json int type_id: Internat type representation :>json int ord: User defined order .. http:get:: /api/currencies List of available currencies **Example response**: .. sourcecode:: json [ { "id": 5, "code": "USD", "name": "USD", "valuta": "23.000", "deviza": "0.000", "units": 1, "note": null, "round": 0, "pricing_round": 0, "symbol": "$", "ord": null, "code_iso": "USD" } ] :>json int id: Unique identifier :>json string code: Currency code (used for internal identification) :>json string name: Name of currency :>json numeric valuta: Foreign currency rate :>json numeric deviza: Foreign exchange rate :>json int units: Number of units to calculate the rate :>json string note: Note :>json int round: Rounding to x decimal places :>json int pricing_round: :>json string symbol: Symbol or code printed when price is displayed or printed :>json int ord: Used defined order :>json string code_iso: ISO code of given currency (used for interoperability purposes) .. http:get:: /api/current_accounts A list of accounts of groups and guests that are accommodated. Technical rooms are ignored. :query string room_code: Optional, when present, only room-account and group-accounts relevant for given room_code are returned :query string include_disabled: Optional, default False. If True, accounts with user disabled external charging flag will be included. **Example response**: .. sourcecode:: json { "groups": [ { "account_id": 6371, "id": 5017, "name": "Group", "checkout_date": "2015-01-31", "checkin_date": "2015-01-28" } ], "rooms": [ { "account_id": 5953, "id": 5852, "checkout_date": "2014-11-22", "code": "401", "checkin_date": "2014-10-15", "last_name": "Brown", "first_nae": "Bill", "gdpr_consent": true, "accommodation_prepayed": false } ] } groups :>json int id: Unique identifier for given checked-in group :>json int account_id: Account number :>json string name: Name of group :>json date checkin_date: Check-in date :>json date checkout_date: Check-out date rooms :>json int id: Unique identifier for given checked-in room :>json int account_id: Account number :>json string last_name: Surname of main guest :>json string first_name: Name of main guest :>json date checkin_date: Check-in date :>json date checkout_date: Check-out date :>json string code: Room code (number) :>json boolean gdpr_consent: Consent with personal info processing :>json boolean accommodation_prepayed: True when accommodation is already payed in advance .. http:get:: /api/account_for_guest/ Designed for systems that keep data in their database and need to check while charging if the guest has moved. :query int current_guest_id: Guest ID (value "id" returned in :http:get:`/api/current_guests`) **Example response**: .. sourcecode:: json { "current_account_id": 11122 } :>json int current_account_id: Guest account number .. http:get:: /api/current_guests List of individual guests :query int room_id: Room ID (value "id" returned in :http:get:`/api/current_accounts`) :query date ci_date_from: Check-in date from :query date ci_date_to: Check-out date until :query boolean include_departured: Include already departured guests (default false) :query datetime modified_since: Return only records modified after given date, format YYYY-MM-DD HH:MM:SS **Example response**: .. sourcecode:: json [ { "id": 11570, "first_name": "Gerald", "last_name": "Fryson", "guest_card_id": 10512, "res_guest_id": 5738, "res_id": 4619, "checkin_date": "2017-10-21", "checkout_date": "2017-10-23", "a_hn": null, "a_street": null, "a_town": null, "a_zip": null, "citizenship": "USA", "birth_date": "1965-01-13", "sex": null, "room": "501", "room_note": "2xDBL", "gc_note": null, "gcs_note": null, "guest_code": "O", "email": null, "departured": false, "order_email": null, "order_phone_number": null, "phone_number": null, "order_phone_number_int": null, "phone_number_int": null, "current_room_id": 6216, "gdpr_consent": true, "room_type_code": "DBL", "room_type_description": "Double", "group_name": "Fryson", "pricelist_code": "BAR", "source_code": "BOOK" }, ] :>json int id: Unique identifier :>json string first_name: Guest’s name :>json string last_name: Guest’s surname :>json int guest_card_id: Guest card ID (identical for repeated stays) :>json int res_guest_id: Reservation ID of a particular guest (allows to pair a specific reserved room-name with a particular guest) :>json int res_id: Reservation number :>json date checkin_date: Check-in date :>json date checkout_date: Check-out date :>json string a_hn: House number :>json string a_street: Street :>json string a_town: City :>json string a_zip: Zip code :>json string citizenship: Citizenship :>json date birth_date: Date of birth :>json string sex: Sex („M“ - male, „F“ - female, „C“ - child) :>json string room: Room number :>json string room_note: Note (applies to the whole room) :>json string gc_note: Note (refers to a particular guest in general - stored in the guest card, independent of the particular stay) :>json string gcs_note: Short note (refers to a particular guest in general - stored in the guest card, independent of the particular stay) :>json string email: Guest e-mail address :>json boolean departured: True if guest is checked-out :>json string guest_code: Guest category (business trip, holiday, etc hotel specified) :>json string order_email: Contact email filled in order-info on reservation level – same for whole reservation) :>json string order_phone_number: Contact phone number filled in order-info on reservation level – same for whole reservation) :>json string phone_number: Contact phone number for given guest-card :>json string order_phone_number_int: Number in international format if valid, else null :>json string phone_number: Number in international format if valid, else null :>json int current_room_id: Guests staying on same room together have same current_room_id :>json boolean gdpr_consent: Consent with personal info processing :>json string room_type_code: Room type code :>json string room_type_description: Room type description (usually name) :>json string group_name: Group name if guest is part of some group :>json string pricelist_code: Code of selected pricelist :>json string source_code: Code of reservation source .. http:get:: /api/reservation_guests List of guests in reservations :query date ci_date_from: Check-in date from :query date ci_date_to: Check-in date until :query boolean include_canceled: If true, results will include canceled reservation (default false) :query boolean include_checked_in: If true, results will include already checked-in guests (default false) :query datetime modified_since: Return only records modified after given date, format YYYY-MM-DD HH:MM:SS :query boolean technical: If set, return only reservations for technical/non-technical rooms :query boolean confirmed: If set, return only confirmed/unconfirmed reservations **Example response**: .. sourcecode:: json [ { "id": 9035, "first_name": null, "last_name": "Abc", "guest_card_id": 831223, "res_id": 6961, "checkin_date": "2017-03-22", "checkout_date": "2017-03-25", "a_hn": null, "a_street": null, "a_town": null, "a_zip": null, "a_country": null, "citizenship": null, "birth_date": null, "sex": null, "room": "102", "rg_note": null, "res_note": null, "gc_note": null, "gcs_note": null, "guest_code": "O", "email": null, "checked_in": false, "guest_count": 2, "res_no_show": false, "canceled": false, "departured": null, "order_email": null, "order_phone_number": null, "phone_number": null, "order_phone_number_int": null, "phone_number_int": null, "gdpr_consent": true, "room_type_code": "DBL", "room_type_description": "Double", "group_name": "Abc", "pricelist_code": "BAR", "source_code": "BOOK", "header_note": "some text", "reservation_id": 8556, "r_country_code": "CZE" }, ] :>json int id: Reservation ID of a particular guest (allows to pair a specific reserved room-name with a particular guest, see the res_guest_id column for accommodated guests) :>json string first_name: Guest’s name :>json string last_name: Guest’s surname :>json int guest_card_id: Guest card ID (identical for repeated stays) :>json int res_id: Reservation number :>json date checkin_date: Check-in date :>json date checkout_date: Check-out date :>json string a_hn: House number :>json string a_street: Street :>json string a_town: City :>json string a_zip: Zip code :>json string a_country: Address country :>json string citizenship: Citizenship :>json date birth_date: Date of birth :>json string sex: Sex („M“ - male, „F“ - female, „C“ - child) :>json string room: Room number :>json string rg_note: Note (refers to a particular guest in given reservation – is relevant for given reservation only) :>json string res_note: Note (applies to the whole reservation) :>json string gc_note: Note (refers to a particular guest in general - stored in the guest card, independent of the particular stay) :>json string gcs_note: Short note (refers to a particular guest in general - stored in the guest card, independent of the particular stay) :>json string guest_code: Guest category (business trip, holiday, etc hotel specified) :>json string email: Guest e-mail address :>json boolean checked_in: True if guest is/was checked_in :>json int guest_count: Number of guests in reservation segment :>json boolean res_no_show: When true, reservation was canceled as no-show. That means, at least one room did not arrived. :>json boolean canceled: True when reservation-row was canceled :>json boolean departured: True when there is link to departured checked-in guest (see :http:get:`/api/current_guests`) :>json string order_email: Contact email filled in order-info on reservation level – same for whole reservation) :>json string order_phone_number: Contact phone number filled in order-info on reservation level – same for whole reservation) :>json string phone_number: Contact phone number for given guest-card :>json string order_phone_number_int: Number in international format if valid, else null :>json string phone_number: Number in international format if valid, else null :>json boolean gdpr_consent: Consent with personal info processing :>json string room_type_code: Room type code :>json string room_type_description: Room type description (usually name) :>json string group_name: Reservation name :>json string pricelist_code: Code of selected pricelist :>json string source_code: Code of reservation source :>json string header_note: Special reservation note :>json int reservation_id: Reservation row ID :>json string r_country_code: Reservation country code .. http:get:: /api/check_card If the hotel uses HORES lock cards, a specific room can be identified by reading the card. The lock card identifier is an integer type written in the first usable trace or the first usable field on the card or by card serial number. This function is not supported on all connected lock systems/card readers! :query int check_id: Card ID from the card (written by PMS or other system) :query string serial_number: Card serial number (identificator of given physical card, non-editable) Verification was successful: **Example response**: .. sourcecode:: json { "result": 0, "room_id": 4232, "account_id": 5996, "room_code": "322" } Verification failed: **Example response**: .. sourcecode:: json { "result":3, "message":"Card validity expired" } :>json int result: 0 - Verification was OK. In this case, room_id and room_code are present and filled in. If the result is nonzero, the message contains more information and room_id and room_code are missing. 1 - Card ID is not in the database 2 - Date and time of the card validity expired 3 - Card expired or card has been cancelled (there is a newer valid card for the selected room) 4 - The lock system module is not installed, the card cannot be verified 5 - Room is not accommodated :>json int room_id: Room ID which can be used to get a list of guests in the room using :http:get:`/api/current_guests` :>json int account_id: Account number for the selected room :>json string room_code: Room code :>json string message: Report in case of error .. http:get:: /api/lock_cards_numbers List of valid card serial numbers for currently occupied rooms. This method can by used to offline match cards to HORES rooms/guests by external system. !!! Warning, sending out lock-system cards serial numbers may be sensitive and pottentiall security risk, depending on lock-system in hotel and it's configuration. This method must be enabled by special runtime parameter --webapi-enable-lock-card-numbers and should be used only after consultation with given lock-system provider. **Example response**: .. sourcecode:: json { "result": 0, "data": [ { "current_account_id": 6845, "room_id": 301, "room_code": "ONE", "serial_number": "12345687", "valid_from": "2021-05-28 14:00:00", "valid_to": "2021-07-16 12:00:00" }, { "current_account_id": 6845, "room_id": 301, "room_code": "ONE", "serial_number": "9898965456", "valid_from": "2021-05-28 14:00:00", "valid_to": "2021-07-16 12:00:00" } ] } .. http:post:: /api/charge_account Charging the sent items to a guest/group account **Example request**: .. sourcecode:: json { "account_id": 5696, "guest_id": 5899, "items": [ { "price": "200.00", "raster_id": 5, "currency_id": 2, "description": "Soup", "receipt_number": "R01225214", "unit_price": "100.00", "units": 2, "vat": "11.0", "item_identification_code": "XYZ5566" } ] } : "Cash register system" -> "Revenue transfers"). In one request, it is possible to enter revenues from multiple cash registers, data is passed in the form of a field of records of the structure below. **Example request**: .. sourcecode:: json [ { "cash_register_code": "Cash register 1", "items": [ { "price": "200.00", "raster_id": 5, "currency_id": 2, "payment_method_id": 2, "note": "Wine", "vat_price": "42.00", "vat": "20.0", "tax_date": "2024-01-02", "default_currency_price": "200.00", "exchange_rate": "1.00", "receipt_number": "R0122512014", "credit_card_type_id": 3, "credit_card_number": "1564xxxx5899" } ] } ] : aid for accounts, or id > cid for cash register items. Currently, you cannot select the change date, the linked system must remember the last processed item’s id. Only records that have passed through the final accounts are returned. The server response is a two-dimensional field of values (because of the amount of data being used, the dictionary is not used as in the previous cases, as the number of items can really be high) :query int aid: Last account item id :query int cid: Last cass office item id **Example response**: .. sourcecode:: json [ ["a", 40001, 25, "50.0000000", 1, "2015-06-02T00:07:26.647987+02:00", null, "50.0000000", 1, 0, "2331123", 0, 1, "50.0000000", 332], ["a", 40002, 25, "50.0000000", 1, "2015-06-02T00:07:26.647987+02:00", null, "50.0000000", 1, 0, "2331123", 0, 1, "50.0000000", 332], ["a", 40003, 51, "400.0000000", 1, "2015-06-02T00:07:26.647987+02:00", null, "200.0000000", 2, 0, "2331123", 0, 1, "50.0000000", 332], ["a", 40005, 66, "-18.1620051", 2, "2015-06-02T00:07:26.647987+02:00", null, "-18.1620051", 1, 0, "2331123", 0, -1, "50.0000000", 332] ] +----------+--------------+------------------------------------------------------------------------------------------+ | Position | Type | Value | +==========+==============+==========================================================================================+ | 0 | char | Item type - „a“ = account item, „c“ = cash register item | +----------+--------------+------------------------------------------------------------------------------------------+ | 1 | int | Item ID | +----------+--------------+------------------------------------------------------------------------------------------+ | 2 | int | Raster ID | +----------+--------------+------------------------------------------------------------------------------------------+ | 3 | numeric | Total price | +----------+--------------+------------------------------------------------------------------------------------------+ | 4 | int | Change ID | +----------+--------------+------------------------------------------------------------------------------------------+ | 5 | datetime | The date of the item creation (for cancelled and modified items it may be misleading as | | | | it is sometimes copied from the source item. The solution is planned, but not ready yet) | +----------+--------------+------------------------------------------------------------------------------------------+ | 6 | string | Document for account items, note for cash register items | +----------+--------------+------------------------------------------------------------------------------------------+ | 7 | numeric | Unit price | +----------+--------------+------------------------------------------------------------------------------------------+ | 8 | int | Quantity | +----------+--------------+------------------------------------------------------------------------------------------+ | 9 | int | The parent's item ID for editing (cancellation, change, division ...) | +----------+--------------+------------------------------------------------------------------------------------------+ | 10 | string | Item identification - stock code. For complementary sales products, the stock code is | | | | set in the complementary sale. | +----------+--------------+------------------------------------------------------------------------------------------+ | 11 | int | Payment method ID for cash register items ("c") | +----------+--------------+------------------------------------------------------------------------------------------+ | 12 | int | Stock status coefficient (1 - addition, -1 - decrease (cancellation)) | +----------+--------------+------------------------------------------------------------------------------------------+ | 13 | numeric | Total amount converted to the default currency. For paid items, the amount is at the | | | | payment rate, for the unpaid it is at the current rate at the time of the query. | +----------+--------------+------------------------------------------------------------------------------------------+ | 14 | int | Final accounts ID | +----------+--------------+------------------------------------------------------------------------------------------+ .. http:get:: /api/product_categories List of available product categories **Example response**: .. sourcecode:: json [ { "id": 3, "title": "Minibar" }, { "id": 5, "title": "Tickets" } ] :>json int id: Unique identifier :>json string title: Category title .. http:post:: /api/product_categories Creating/updating categories in complementary sales (the request body contains a list of categories defined by the structure described below). **Example request**: .. sourcecode:: json [ { "id": 3, "title": "Minibar" }, { "id": 5, "title": "Tickets" } ] :json int id: Unique identifier :>json string title: Name of product :>json string unit: Name of quantity unit (e.g. pcs.) :>json int raster_id: Corresponding raster ID :>json numeric purchase_price: Purchase price :>json numeric selling_price: Selling price :>json string product_code: Product code :>json int category_id: Complementary sales category ID :>json int stock: Items in stock :>json boolean service: True when it comes to a service (ignoring the stock quantity) :>json numeric selling_price1: Selling price in second currency :>json numeric selling_price2: Selling price in third currency :>json string catalogue_number: Catalogue number .. http:post:: /api/products Creating/updating products in complementary sales (the request body contains a list of products defined by the structure described below). **Example request**: .. sourcecode:: json [ { "id": 1, "title": "Wine", "unit": "ks", "raster_id": 8, "purchase_price": "11.79", "selling_price": "200.00", "product_code": "", "category_id": 1, "stock": 3, "service": false, "selling_price1": "2.00", "selling_price2": null, "catalogue_number": "abc" } ] :json int id: Unique identifier :>json string code: Raster or package code :>json string name: Raster or package name :>json string currency: Currency code :>json numeric price: Total amount :>json int amount: Quantity :>json date date: Item date :>json string description: Description if available .. http:post:: /api/room_state Set room state **Example request**: .. sourcecode:: json { "room_code": "201", "room_clean": true } :json int id: Unique identifier :>json string code: Target code :>json string name: Target name .. http:get:: /api/traces List of existing traces :query int current_room_id: ID of checked in room :query int traces_target_id: Filter traces for only given traces_target_id, see /tracesTargets :query date action_date_from: Only traces with action_date >= this value will be returned (format: YYYY-MM-DD) :query int reservation_group_id: Reservation ID filter :query int room_id: Room ID filter **Example response**: .. sourcecode:: json [ { "id": 170596, "description": "provide us a quiet room, NOT facing the road. so it is not too loud during at nights.", "action_date": "2017-05-07", "action_time": null, "traces_target_id": null, "traces_target": null, "solved": false, "solution": null, "current_room_id": null, "reservation_group_id: null, "room_id": null, "internal_data": null, "category": null } ] :>json int id: Unique identifier :>json string description: Trace description :>json date action_date: YYYY-MM-DD :>json time action_time: HH:MM :>json int traces_target_id: ID of target (see /tracesTargets) :>json string traces_target: Code of current target :>json boolean solved: True if trace resolved/finished :>json string solution: Solution notes/description :>json int current_room_id: ID of current-room this trace is bound to :>json int reservation_group_id: ID of reservation this trace is bound to :>json int room_id: ID of room this trace is bound to :>json string category: Category of traces from predefined enumeration :>json string internal_data: Text used by external applications for various reasons .. http:post:: /api/traces Updates or creates traces for given checked-in room **Example request**: .. sourcecode:: json [ { "trace_id": 170596, "current_room_id": 34, "description": "provide us a quiet room, NOT facing the road. so it is not too loud during at nights.", "action_date": "2017-05-07", "action_time": null, "traces_target_id": null, "traces_target": null, "solved": false, "solution": null, "reservation_group_id": null, "room_id": null, "internal_data": null, "category": null } ] :json int guest_count: Number of guests for which price is calculated :>json string hores_code: Code of connected HORES pricelist :>json string hores_type: Code of connected HORES pricetype withing that pricelist .. http:get:: /api/cm_room_types Mapping table between internal room-types and channel-manager room-types **Example response**: .. sourcecode:: json [ { "id": 43, "room_type_id": 5, "online_room_type": "TRP", "online_sync": true, "channel_id": "hores_api" }, { "id": 40, "room_type_id": 2, "online_room_type": "DBL", "online_sync": true, "channel_id": "hores_api" } ] :>json int id: Unique identifier of given record :>json int room_type_id: Internal room-type id, see /roomTypes :>json string online_room_type: Room-type code used by external system :>json boolean online_sync: If true, given room-type should be offered via connected online system for reservations :>json string channel_id: Internal ID, currently not usable by connected systems .. http:get:: /api/cm_reservations List basic reservation information :query date ci_date_from: Check-in date from :query date ci_date_to: Check-in date until :query int reservation_id: Reservation id :query datetime modified_since: Return only records modified after given date, format YYYY-MM-DD HH:MM:SS :query boolean technical: If set, return only reservations for technical/non-technical rooms :query boolean confirmed: If set, return only confirmed/unconfirmed reservations **Example response**: .. sourcecode:: json [ { "reservation_number": 170596, "name": "Reservation name", "source_code": "BOOKING", "source_id": 22, "order_email": null, "order_phone_number": null, "order_number": "6547676", "non_refundable": false, "note": "Some text informations...", "total_price": "3000.0", "currency_code": "EUR", "sale_code": null, "guest_code": null, "payment_method": "C", "discount_code": null, "loyalty_card": null, "rows": [ { "id": 855666, "date_from": "2017-01-01", "date_to": "2017-01-10", "room_type_id": 2, "room_type_code": "DBL", "room_count": 2, "guest_count": 4, "pricelist_id": 12, "pricetype_id": 32, "cm_rate_code": "BAR", "cm_room_code": "DBL", "canceled": false, "option": false, "option_date": null, "arrival_time": "14:00", "technical": false, "tentative": false, "services": [ { "id": 44, "raster_id": 3, "package_id": null, "on_room": true, "pay_once": false, "on_group": false, "price": "50.00" } ], "prices": [ { "date_from": "2017-01-01", "date_to": "2017-01-05", "price": "200.00", "package_id": null }, { "date_from": "2017-01-06", "date_to": "2017-01-09", "price": "250.00", "package_id": null } ] } ] } ] :>json int reservation_number: Unique identifier (reservation number) :>json string name: Reservation name (title) :>json string source_code: Booking source code :>json int source_id: Booking source internal identification :>json string note: Note/comments, free textual information field :>json string order_email: Email contact (for whole reservation) :>json string order_phone_number: Phone number (for whole reservation) :>json string order_number: Order number provided by reservation-creator :>json boolean non_refundable: If true, reservation is not refundable when canceled :>json decimal total_price: Total price of reservation including services etc. :>json string currency_code: Reservation accommodation currency (used for total_price for example) :>json string sale_code: Sale code for statistical and other purposes :>json string guest_code: Guest code for statistical and other purposes :>json list rows: Each reservation has at leas one, possibly many rows, each row can have different data :>json string payment_method: Payment method selected for reservation :>json string discount_code: Discount code :>json string loyalty_card: Loyalty card :>json int id: Internal row id :>json date date_from: Checkin date :>json date date_to: Checkout date :>json int room_type_id: Internal id of reserved room-type :>json string room_type_code: Internal room-type code :>json int room_count: Number of reserved rooms :>json int guest_count: Total number of guests for this row, for all rooms, including children :>json int pricelist_id: Internal id of pricelist :>json int pricetype_id: Internal id of pricetype :>json string cm_rate_code: Rate-code used for online/channel-manager purpose :>json string cm_room_code: Room-code used for online/channel-manager purpose :>json boolean canceled: When True, row is canceled. When all rows are canceled, whole reservation is canceled. :>json list prices: Pricing for single room per day :>json boolean option: If true reservation is in option (unconfirmed) state :>json boolean option_date: If option is true, must be confirmed to this date :>json time arrival_time: Time of arrival at checkin, HH:MM :>json boolean technical: If True, room-type is "technical", meaning not phisical room but waiting or other special type of reservation :>json boolean tentative: If True, reservation is in "tentative" state, meaning it's unconfirmed :>json date date_from: Price is valid from this date included :>json date date_to: Price is valid to this date included :>json decimal price: Price value :>json int package_id: Package ID, see :http:get:`/api/packages` :>json int id: Internal row id :>json int raster_id: Raster ID, see :http:get:`/api/rasters` :>json int package_id: Package ID, see :http:get:`/api/packages` :>json boolean on_room: When true, service will be charged per room, when false, service will be charged per guest :>json boolean on_group: Only valid for group-guests, when true, item will be charged to group account :>json boolean pay_once: When true, service will be charge once per stay, when false, service will be charge for each day :>json decimal price: Unit price to charge .. http:get:: /api/reservations List basic reservation information :query date ci_date_from: Check-in date from :query date ci_date_to: Check-in date until :query int reservation_id: Reservation id :query datetime modified_since: Return only records modified after given date, format YYYY-MM-DD HH:MM:SS :query boolean is_group: If present, return only groups (true) or individuals (false) :query boolean technical: If set, return only reservations for technical/non-technical rooms :query boolean confirmed: If set, return only confirmed/unconfirmed reservations **Example response**: .. sourcecode:: json [ { "reservation_number": 170596, "name": "Reservation name", "source_code": "BOOKING", "source_id": 22, "order_email": null, "order_phone_number": null, "order_number": "6547676", "non_refundable": false, "note": "Some text informations...", "total_price": "3000.0", "currency_code": "EUR", "sale_code": null, "guest_code": null, "payment_method": "C", "is_group": False, "discount_code": null, "loyalty_card": null, "rows": [ { "id": 855666, "date_from": "2017-01-01", "date_to": "2017-01-10", "room_type_id": 2, "room_type_code": "DBL", "room_count": 2, "guest_count": 4, "pricelist_id": 12, "pricetype_id": 32, "rate_code": "BAR", "room_code": "DBL", "canceled": false, "country_code": "CZE", "option": false, "option_date": null, "arrival_time": "14:00", "technical": false, "tentative": false, "services": [ { "id": 44, "raster_id": 3, "package_id": null, "on_room": true, "pay_once": false, "on_group": false, "price": "50.00" } ], "prices": [ { "date_from": "2017-01-01", "date_to": "2017-01-05", "price": "200.00", "package_id": null }, { "date_from": "2017-01-06", "date_to": "2017-01-09", "price": "250.00", "package_id": null } ] } ] } ] :>json int reservation_number: Unique identifier (reservation number) :>json string name: Reservation name (title) :>json string source_code: Booking source code :>json int source_id: Booking source internal identification :>json string note: Note/comments, free textual information field :>json string order_email: Email contact (for whole reservation) :>json string order_phone_number: Phone number (for whole reservation) :>json string order_number: Order number provided by reservation-creator :>json boolean non_refundable: If true, reservation is not refundable when canceled :>json decimal total_price: Total price of reservation including services etc. :>json string currency_code: Reservation accommodation currency (used for total_price for example) :>json string sale_code: Sale code for statistical and other purposes :>json string guest_code: Guest code for statistical and other purposes :>json list rows: Each reservation has at leas one, possibly many rows, each row can have different data :>json string payment_method: Payment method selected for reservation :>json boolean is_group: True if group reservation, False if individual :>json string discount_code: Discount code :>json string loyalty_card: Loyalty card :>json int id: Internal row id :>json date date_from: Checkin date :>json date date_to: Checkout date :>json int room_type_id: Internal id of reserved room-type :>json string room_type_code: Internal room-type code :>json int room_count: Number of reserved rooms :>json int guest_count: Total number of guests for this row, for all rooms, including children :>json int pricelist_id: Internal id of pricelist :>json int pricetype_id: Internal id of pricetype :>json string cm_rate_code: Rate-code used for online/channel-manager purpose :>json string cm_room_code: Room-code used for online/channel-manager purpose :>json boolean canceled: When True, row is canceled. When all rows are canceled, whole reservation is canceled. :>json string country_code: Reservation country code :>json list prices: Pricing for single room per day :>json boolean option: If true reservation is in option (unconfirmed) state :>json boolean option_date: If option is true, must be confirmed to this date :>json time arrival_time: Time of arrival at checkin, HH:MM :>json boolean technical: If True, room-type is "technical", meaning not phisical room but waiting or other special type of reservation :>json boolean tentative: If True, reservation is in "tentative" state, meaning it's unconfirmed :>json date date_from: Price is valid from this date included :>json date date_to: Price is valid to this date included :>json decimal price: Price value :>json int package_id: Package ID, see :http:get:`/api/packages` :>json int id: Internal row id :>json int raster_id: Raster ID, see :http:get:`/api/rasters` :>json int package_id: Package ID, see :http:get:`/api/packages` :>json boolean on_room: When true, service will be charged per room, when false, service will be charged per guest :>json boolean on_group: Only valid for group-guests, when true, item will be charged to group account :>json boolean pay_once: When true, service will be charge once per stay, when false, service will be charge for each day :>json decimal price: Unit price to charge .. http:post:: /api/cm_reservation Updates or creates reservation. When multiple parameters for the value are present, for example room_type_id, room_type_code and cm_room_code, only one value needs to be filled in for request to be processed. When multiple values are set, internal id is checked first, internal code second and "cm" related values last. **Example request**: .. sourcecode:: json { "reservation_number": 170596, "name": "Reservation name", "source_code": "BOOKING", "source_id": 22, "order_phone_number": null, "order_email": null, "order_number": "5464864", "note": "Some text informations...", "prepend_note": "Some importent text", "append_note": "Some less important text", "sale_code": null, "guest_code": null, "payment_method": "C", "option": false, "option_date": null, "discount_code": null, "loyalty_card": null, "rows": [ { "id": 855666, "date_from": "2017-01-01", "date_to": "2017-01-10", "room_type_id": 2, "room_type_code": "DBL", "room_count": 2, "guest_count": 4, "pricelist_id": 12, "pricetype_id": 32, "cm_rate_code": "BAR", "cm_room_code": "DBL", "canceled": false, "country_code": "CZE", "option": false, "option_date": null, "arrival_time": "14:00", "services": [ { "raster_id": 3, "package_id": null, "on_room": true, "pay_once": false, "on_group": false, "price": "50.00" } ], "prices": [ { "date_from": "2017-01-01", "date_to": "2017-01-05", "price": "200.00", "package_id": null }, { "date_from": "2017-01-06", "date_to": "2017-01-09", "price": "250.00", "package_id": null } ] } ] } :json int reservation_id: Reservation row ID :>json int reservation_guest_number: Reservation ID of a particular guest, if empty, new guest will be created) :>json string first_name: Guest’s name :>json string last_name: Guest’s surname :>json int guest_card_id: Guest card ID (identical for repeated stays) :>json int reservation_id: Reservation number :>json string a_hn: House number :>json string a_street: Street :>json string a_town: City :>json string a_zip: Zip code :>json string a_country: Country code :>json string citizenship: Citizenship :>json date birth_date: Date of birth :>json string sex: Sex („M“ - male, „F“ - female, „C“ - child) :>json string room: Room number :>json string rg_note: Note (refers to a particular guest in given reservation – is relevant for given reservation only) :>json string gc_note: Note (refers to a particular guest in general - stored in the guest card, independent of the particular stay) :>json string gcs_note: Short note (refers to a particular guest in general - stored in the guest card, independent of the particular stay) :>json string email: Guest e-mail address :>json string phone_number: Guest phone number :>json boolean gdpr_consent: Consent with personal info processing :>json string ic_number: IC/Passport number etc. :>json string ic_type: Option type of ic_number, valid strings are: 'personal_id', 'passport', 'drivers_license', 'other' :>json string licence_plate: Car licnece plate .. http:post:: /api/reservation_guest Create or update reservation-guest information **Example request**: .. sourcecode:: json [ { "reservation_id": 2334, "reservation_guest_id": 65443, "first_name": null, "last_name": "Abc", "guest_card_id": 831223, "a_hn": null, "a_street": null, "a_town": null, "a_zip": null, "a_country": "CZE", "citizenship": null, "birth_date": null, "sex": null, "room": "102", "rg_note": null, "gc_note": null, "gcs_note": null, "email": null, "phone_number": null, "gdpr_consent": true, "ic_number": null, "ic_type": null, "licence_plate". null }, ] :json int id: Unique identifier of receipt :>json int receipt_number: Number of associated receipt :>json date payment_date: Date of payment :>json string receipt_note: Receipt-level note :>json int coi_id: Unique identifier of receipt item :>json int raster_id: Raster ID, see :http:get:`/api/rasters` :>json decimal price: Price :>json int currency_id: Currency ID (returned by :http:get:`/api/currencies`) :>json decimal vat: VAT value in percentage :>json int payment_method_id: Payment method ID, see :http:get:`/api/payment_methods` :>json string description: Item level description (can identify/explain given item) :>json string coi_note: Item level note (internal note about item) :>json date created_at: Date of item creation :>json boolean canceled: True if item is canceled :>json int final_account_id: Final account id number :>json decimal vat_price: Calculated VAT price (local currency) :>json decimal default_currency_price: Price converted to local currency :>json decimal exch_rate: Exchange rate :>json string credit_card: Credit-card number, sanitized :>json int prapayment_currency_id: Currency to use when item is charged to guest-account :>json decimal prepayment_exch_rate: Exchange rate used when item is charged to guest-account :>json decimal prepayment_price: Price used when item is charged to guest-account .. http:post:: /api/prepayment Create prepayment for specific reservation number. If "send_to_emails" is filled, payment confirmation will be send to provided emails. Attached will be PDF with cass-office receipt. More than one item can be written to single receipt using additional_items field when needed. **Example request**: .. sourcecode:: json [ { "reservation_group_id": 4562, "payment_date": "2018-02-22", "receipt_note": null, "raster_id": 34, "price": "400.00", "currency_id": 1, "vat": "20.0", "payment_method_id": 5, "description": null, "coi_note": null, "vat_price": "80.00", "default_currency_price": "400.00", "exch_rate": "1.0000", "prepayment_currency_id": 1, "prepayment_exch_rate": "1.00", "prepayment_price": "400.00", "credit_card": null, "credit_card_type": null, "send_to_emails": "test@domain.com, hotel@domain.com", "additional_items": [ { "raster_id": 34, "price": "400.00", "currency_id": 1, "vat": "20.0", "payment_method_id": 5, "description": null, "coi_note": null, "vat_price": "80.00", "default_currency_price": "400.00", "exch_rate": "1.0000", "prepayment_currency_id": 1, "prepayment_exch_rate": "1.00", "prepayment_price": "400.00", "credit_card": null, "credit_card_type": null } ] } ] :json int user_id: Unique identifier of HORES user :>json dict user_rights: Dictionary of user rights values .. http:get:: /api/get_license Method to get some HORES license information **Example response**: .. sourcecode:: json { "result": 0, "data": { "license": 234, "hotel_name": "Hotel California", "hotel_address": "Palm Springs, CA 92264", "license_number": 234 } } :>json int license_number: Unique license number :>json string hotel_name: Hotel name from settings :>json string hotel-address": Hotel address from settings :>json int license: Same as license_number for compatibility .. http:get:: /api/get_license Undocumented method to get some detailed room-occupancy data for currently occupied rooms .. http:get:: /api/user_messages List messages for user .. http:post:: /api/update_user_message Set user-message status .. http:post:: /api/send_message Send message to user .. http:get:: /api/contacts List contacts .. http:get:: /api/room_service_actions Available room service actions list .. http:get:: /api/users List HORES users .. http:post:: /api/set_room_attr Set attribute parameters for room