################# GraphQL HORES API ################# .. toctree:: :hidden: :glob: self_service_workflows lock_system_keys HORES application API is based on GraphQL design, see https://graphql.org/ for details about this API query language. Communication is based on HTTPS protocol. HTTP protocol can be enabled for development/debugging only, never should be used in production! GraphQL endpoint is available on **/graphql** url. GraphiQL interactive client with syntax highlighting etc. for api testing and documentation/object browser is available on **/graphiql** url. ************** Authentication ************** Authentication is necessary to access any method of API. When authenticated, all actions performed through API are registered as actions of given authenticated user defined in HORES database. There are no anonymous actions or actions performed by "interface" or "robot". You can use interactive or non-interactive login based on situation (physical person vs automated software), see later, but every connected system should have corresponding user with certain user rights defined in HORES system (this user can be defined such it prevents interactive login if desired, so it can be used only for defined api calls) Several authentication mechanisms 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 POST /graphql HTTP/1.1 Host: example.com Accept: application/json Authorization: Token 65sad4f64df6sd6f4sdffassdfa Session token ============= When interactive login is needed (to identify user currently using software or to enable logout option), session token authentication method is available. You can request session-token with http GET request to /login url, providing username and password through standard Basic authentication method. Only users with enabled API access can be logged in directly: .. sourcecode:: http GET /login HTTP/1.1 Host: example.com Accept: application/json Authorization: Basic s5df4h8n4cv5cvv4ert4654h== If you need to enable regular HORES users to login (for example for HORES mobile client, room-service application etc.), you need to authenticate your login request with valid credentials of user with API access enabled and specify regular HORES user credentials in custom X-HoresLogin header (format is same as Authorization header). This is to ensure only selected accounts with strong password or tokens can access API. .. sourcecode:: http GET /login HTTP/1.1 Host: example.com Accept: application/json Authorization: Token 65sad4f64df6sd6f4sdffassdfa X-HoresLogin: Basic s5df4h8n4cv5cvv4ert4654h== On success, HTTP 200 and JSON with user info and session token is returned: .. sourcecode:: json { "data": { "token": "54654h6r4g6d4f6g46sdf46easda4asd", "realname": "Jack O'Neill", "valid_to": "2030-01-01" } } On bad login credentials, expired login or other standard login failure, HTTP 401 with corresponding error details in JSON body is returned: .. sourcecode:: json { "data": null, "errors": [ { "message": "Invalid credentials" } ] { When needed to log-out, simply send http GET request to /logout url with corresponding session token in header: .. sourcecode:: http GET /logout HTTP/1.1 Host: example.com Accept: application/json Authorization: Token 8744j8ui74k8io4km654h5f4g65fggfg When logout is successful, HTTP 200 with some logout data should return: .. sourcecode:: json { "data": { "message": "Logout successful" } } There is no standard situation when logout should fail, only program/server/network error should cause this to happen. In that case some corresponding generic error message and HTTP status will be returned. When session-token is correctly generated, usage is same as permanent token mentioned in previous chapter. HouseKeeping token ================== Special login method for HouseKeeping module tokens. Use "Authorization" header with "HKToken" keyword such as: .. sourcecode:: http POST /graphql HTTP/1.1 Host: example.com Accept: application/json Authorization: HKToken 65sad4f64df6sd6f4sdffassdfa *************** Images handling *************** Image resources are handled through separate endpoints. To download image, use: .. sourcecode:: http GET /image?image_id=123 You will get image_id values from GraphQL results (for example images attached to Traces) To upload image, use: .. sourcecode:: http POST /upload_image?trace_id=123 Currently HORES supports images only for Traces. Use trace_id of existing trace returned from GraphQL result. Image should be send as binary data in request body. ************ PDF accounts ************ When account is created using CreateAccountPayment() method, returned account.id can be used to access generated PDF receipt using: .. sourcecode:: http GET /account_pdf?account_id=12345 ************* Notifications ************* Notifications about events/changes in HORES (for exammple when reservation is created/updated and so on) can be received via WebSocket protocol on url /ws. No authentication is required. To test connection, you can send any message throug this websocket, server will reply and repeat your message back. *************** Basic workflows *************** Reservations ============ Use listReservations() and getReservation() to find and inspect existing reservations, use createUpdateReservation() to create new or modify existing reservation Check in ======== Use checkIn() mutation to checkin reservation or walk-in. For walk-in, you need to left reservation_number empty and provide current_guest_group header data. For reservation checkin, minimum you need to provide is: - reservation_number or current_guest_group object with reservation_number value - at least one CurrentRoom object with room_id and CurrentGuests linked to reservation rows via CurrentGuests.reservation_id You can fill in any other supported items, if you don't, values will be automatically filled from existing reservation data when available. If reservation-rooming is not prepared in advance, you can use getAvailableRooms() method to get free rooms for reservation to check-in When checking-in guest from reservation-rooming, do not forget to peroperly use CurrentGuest.reservation_guests_id to linked checked-in guest to specific reservation-guest, so reservation-guest is properly marked as checked-in. CheckIn method serves only for room-checkin. When room is already checked-in and you need to add another person to it, use createUpdateCurrentRoom() method. After checkin, when something is wrong, payment not made etc., you can call cancelCheckIn() to undo this operation. You can only cancel checkin when there are no payed items on account, final-account has not yet run and room is not checked out already. Checked-in guests ================= After checkin, you can list guests via listCurrentRooms() and modify guests via createUpdateCurrentRooms(), createUpdateCurrentguestGroup() Accounts ======== Use createUpdateAccountItem to charge items to selected account and listAccountItems() to list existing items on selected account Use chargeRestOfStay() to charge all remaining items to the end of stay to selected account. Account is automatically marked "accomodation_prepayed", so no automatic charges will be make to this accout later. You can than use all those account items to charge the guest and accept payment for whole stay. Only unplanned expenses like minibar could be added later. Use createAccountPayment() to acually pay selected items from given account. Check out ========= Use checkOutRoom() method to checkout room with all guests :doc:`self_service_workflows`