diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index 0c2a912..897e27e 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -21,6 +21,7 @@
 #include "../lib/redfish_sessions.hpp"
 #include "../lib/roles.hpp"
 #include "../lib/service_root.hpp"
+#include "../lib/chassis.hpp"
 #include "webserver_common.hpp"
 
 namespace redfish {
@@ -45,6 +46,8 @@
     nodes.emplace_back(std::make_unique<NetworkProtocol>(app));
     nodes.emplace_back(std::make_unique<SessionService>(app));
     nodes.emplace_back(std::make_unique<ManagerCollection>(app));
+    nodes.emplace_back(std::make_unique<ChassisCollection>(app));
+    nodes.emplace_back(std::make_unique<Chassis>(app));
 
     for (auto& node : nodes) {
       node->getSubRoutes(nodes);
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
new file mode 100644
index 0000000..8f88eb1
--- /dev/null
+++ b/redfish-core/lib/chassis.hpp
@@ -0,0 +1,278 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#pragma once
+
+#include "node.hpp"
+#include <boost/container/flat_map.hpp>
+
+namespace redfish {
+
+/**
+ * DBus types primitives for several generic DBus interfaces
+ * TODO(Pawel) consider move this to separate file into boost::dbus
+ */
+using ManagedObjectsType = std::vector<
+    std::pair<dbus::object_path,
+              std::vector<std::pair<
+                  std::string,
+                  std::vector<std::pair<std::string, dbus::dbus_variant>>>>>>;
+
+using PropertiesType =
+    boost::container::flat_map<std::string, dbus::dbus_variant>;
+
+/**
+ * OnDemandChassisProvider
+ * Chassis provider class that retrieves data directly from dbus, before seting
+ * it into JSON output. This does not cache any data.
+ *
+ * Class can be a good example on how to scale different data providing
+ * solutions to produce single schema output.
+ *
+ * TODO(Pawel)
+ * This perhaps shall be different file, which has to be chosen on compile time
+ * depending on OEM needs
+ */
+class OnDemandChassisProvider {
+ public:
+  /**
+   * Function that retrieves all properties for given Chassis Object from
+   * EntityManager
+   * @param res_name a chassis resource name to query on DBus
+   * @param callback a function that shall be called to convert Dbus output into
+   * JSON
+   */
+  template <typename CallbackFunc>
+  void get_chassis_data(const std::string &res_name, CallbackFunc &&callback) {
+    crow::connections::system_bus->async_method_call(
+        [callback{std::move(callback)}](
+            const boost::system::error_code error_code,
+            const PropertiesType &properties) {
+          // Callback requires flat_map<string, string> so prepare one.
+          boost::container::flat_map<std::string, std::string> output;
+          if (error_code) {
+            // Something wrong on DBus, the error_code is not important at this
+            // moment, just return success=false, and empty output. Since size
+            // of map may vary depending on Chassis type, an empty output could
+            // not be treated same way as error.
+            callback(false, output);
+            return;
+          }
+          for (const std::pair<const char *, const char *> &p :
+               std::array<std::pair<const char *, const char *>, 5>{
+                   {{"name", "Name"},
+                    {"manufacturer", "Manufacturer"},
+                    {"model", "Model"},
+                    {"part_number", "PartNumber"},
+                    {"serial_number", "SerialNumber"}}}) {
+            PropertiesType::const_iterator it = properties.find(p.first);
+            if (it != properties.end()) {
+              const std::string *s = boost::get<std::string>(&it->second);
+              if (s != nullptr) {
+                output[p.second] = *s;
+              }
+            }
+          }
+          // Callback with success, and hopefully data.
+          callback(true, output);
+        },
+        {"xyz.openbmc_project.EntityManager",
+         "/xyz/openbmc_project/Inventory/Item/Chassis/" + res_name,
+         "org.freedesktop.DBus.Properties", "GetAll"},
+        "xyz.openbmc_project.Configuration.Chassis");
+  }
+
+  /**
+   * Function that retrieves all Chassis available through EntityManager.
+   * @param callback a function that shall be called to convert Dbus output into
+   * JSON.
+   */
+  template <typename CallbackFunc>
+  void get_chassis_list(CallbackFunc &&callback) {
+    crow::connections::system_bus->async_method_call(
+        [callback{std::move(callback)}](
+            const boost::system::error_code error_code,
+            const ManagedObjectsType &resp) {
+          // Callback requires vector<string> to retrieve all available chassis
+          // list.
+          std::vector<std::string> chassis_list;
+          if (error_code) {
+            // Something wrong on DBus, the error_code is not important at this
+            // moment, just return success=false, and empty output. Since size
+            // of vector may vary depending on information from Entity Manager,
+            // and empty output could not be treated same way as error.
+            callback(false, chassis_list);
+            return;
+          }
+
+          // Iterate over all retrieved ObjectPaths.
+          for (auto &objpath : resp) {
+            // And all interfaces available for certain ObjectPath.
+            for (auto &interface : objpath.second) {
+              // If interface is xyz.openbmc_project.Configuration.Chassis, this
+              // is Chassis.
+              if (interface.first ==
+                  "xyz.openbmc_project.Configuration.Chassis") {
+                // Cut out everyting until last "/", ...
+                const std::string &chassis_id = objpath.first.value;
+                std::size_t last_pos = chassis_id.rfind("/");
+                if (last_pos != std::string::npos) {
+                  // and put it into output vector.
+                  chassis_list.emplace_back(chassis_id.substr(last_pos + 1));
+                }
+              }
+            }
+          }
+          // Finally make a callback with usefull data
+          callback(true, chassis_list);
+        },
+        {"xyz.openbmc_project.EntityManager",
+         "/xyz/openbmc_project/Inventory/Item/Chassis",
+         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"});
+  };
+};
+
+/**
+ * ChassisCollection derived class for delivering Chassis Collection Schema
+ */
+class ChassisCollection : public Node {
+ public:
+  template <typename CrowApp>
+  ChassisCollection(CrowApp &app) : Node(app, "/redfish/v1/Chassis/") {
+    Node::json["@odata.type"] = "#ChassisCollection.ChassisCollection";
+    Node::json["@odata.id"] = "/redfish/v1/Chassis";
+    Node::json["@odata.context"] =
+        "/redfish/v1/$metadata#ChassisCollection.ChassisCollection";
+    Node::json["Name"] = "Chassis Collection";
+
+    entityPrivileges = {{crow::HTTPMethod::GET, {{"Login"}}},
+                        {crow::HTTPMethod::HEAD, {{"Login"}}},
+                        {crow::HTTPMethod::PATCH, {{"ConfigureComponents"}}},
+                        {crow::HTTPMethod::PUT, {{"ConfigureComponents"}}},
+                        {crow::HTTPMethod::DELETE, {{"ConfigureComponents"}}},
+                        {crow::HTTPMethod::POST, {{"ConfigureComponents"}}}};
+  }
+
+ private:
+  /**
+   * Functions triggers appropriate requests on DBus
+   */
+  void doGet(crow::response &res, const crow::request &req,
+             const std::vector<std::string> &params) override {
+    // Get chassis list, and call the below callback for JSON preparation
+    chassis_provider.get_chassis_list(
+        [&](const bool &success, const std::vector<std::string> &output) {
+          if (success) {
+            // ... prepare json array with appropriate @odata.id links
+            nlohmann::json chassis_array = nlohmann::json::array();
+            for (const std::string &chassis_item : output) {
+              chassis_array.push_back(
+                  {{"@odata.id", "/redfish/v1/Chassis/" + chassis_item}});
+            }
+            // Then attach members, count size and return,
+            Node::json["Members"] = chassis_array;
+            Node::json["Members@odata.count"] = chassis_array.size();
+            res.json_value = Node::json;
+          } else {
+            // ... otherwise, return INTERNALL ERROR
+            res.code = static_cast<int>(HttpRespCode::INTERNAL_ERROR);
+          }
+          res.end();
+        });
+  }
+
+  // Chassis Provider object
+  // TODO(Pawel) consider move it to singleton
+  OnDemandChassisProvider chassis_provider;
+};
+
+/**
+ * Chassis override class for delivering Chassis Schema
+ */
+class Chassis : public Node {
+ public:
+  /*
+   * Default Constructor
+   */
+  template <typename CrowApp>
+  Chassis(CrowApp &app)
+      : Node(app, "/redfish/v1/Chassis/<str>/", std::string()) {
+    Node::json["@odata.type"] = "#Chassis.v1_4_0.Chassis";
+    Node::json["@odata.id"] = "/redfish/v1/Chassis";
+    Node::json["@odata.context"] = "/redfish/v1/$metadata#Chassis.Chassis";
+    Node::json["Name"] = "Chassis Collection";
+
+    entityPrivileges = {{crow::HTTPMethod::GET, {{"Login"}}},
+                        {crow::HTTPMethod::HEAD, {{"Login"}}},
+                        {crow::HTTPMethod::PATCH, {{"ConfigureComponents"}}},
+                        {crow::HTTPMethod::PUT, {{"ConfigureComponents"}}},
+                        {crow::HTTPMethod::DELETE, {{"ConfigureComponents"}}},
+                        {crow::HTTPMethod::POST, {{"ConfigureComponents"}}}};
+  }
+
+ private:
+  /**
+   * Functions triggers appropriate requests on DBus
+   */
+  void doGet(crow::response &res, const crow::request &req,
+             const std::vector<std::string> &params) override {
+    // Check if there is required param, truly entering this shall be
+    // impossible.
+    if (params.size() != 1) {
+      res.code = static_cast<int>(HttpRespCode::INTERNAL_ERROR);
+      res.end();
+      return;
+    }
+    const std::string &chassis_id = params[0];
+    // Get certain Chassis Data, and call the below callback for JSON
+    // preparation lambda requires everything as reference, and chassis_id,
+    // which is local by copy
+    chassis_provider.get_chassis_data(
+        chassis_id,
+        [&, chassis_id](const bool &success,
+                        const boost::container::flat_map<std::string,
+                                                         std::string> &output) {
+          // Create JSON copy based on Node::json, this is to avoid possible
+          // race condition
+          nlohmann::json json_response(Node::json);
+          // If success...
+          if (success) {
+            // prepare all the schema required fields.
+            json_response["@odata.id"] = "/redfish/v1/Chassis/" + chassis_id;
+            // also the one from dbus
+            for (const std::pair<std::string, std::string> &chassis_item :
+                 output) {
+              json_response[chassis_item.first] = chassis_item.second;
+            }
+            json_response["Id"] = chassis_id;
+
+            // prepare respond, and send
+            res.json_value = json_response;
+          } else {
+            // ... otherwise return error
+            // TODO(Pawel)consider distinguish between non existing object, and
+            // other errors
+            res.code = static_cast<int>(HttpRespCode::NOT_FOUND);
+          }
+          res.end();
+        });
+  }
+
+  // Chassis Provider object
+  // TODO(Pawel) consider move it to singleton
+  OnDemandChassisProvider chassis_provider;
+};
+
+}  // namespace redfish
