diff --git a/valence/api/route.py b/valence/api/route.py
index be0cecc..eaa7673 100644
--- a/valence/api/route.py
+++ b/valence/api/route.py
@@ -23,10 +23,10 @@ from valence.api import app as flaskapp
 import valence.api.root as api_root
 import valence.api.v1.flavors as v1_flavors
 import valence.api.v1.nodes as v1_nodes
+import valence.api.v1.podmanagers as v1_podmanagers
 import valence.api.v1.storages as v1_storages
 import valence.api.v1.systems as v1_systems
 import valence.api.v1.version as v1_version
-
 from valence.common import exception
 from valence.common import utils
 
@@ -59,7 +59,6 @@ api = ValenceService(app)
 
 """API V1.0 Operations"""
 
-
 # API Root operation
 api.add_resource(api_root.Root, '/', endpoint='root')
 
@@ -88,5 +87,11 @@ api.add_resource(v1_storages.StoragesList, '/v1/storages', endpoint='storages')
 api.add_resource(v1_storages.Storages,
                  '/v1/storages/<string:storageid>', endpoint='storage')
 
+# PodManager(s) operations
+api.add_resource(v1_podmanagers.PodManager,
+                 '/v1/pod_managers/<string:podm_uuid>', endpoint='podmanager')
+api.add_resource(v1_podmanagers.PodManagersList,
+                 '/v1/pod_managers', endpoint='podmanagers')
+
 # Proxy to PODM
 api.add_resource(api_root.PODMProxy, '/<path:url>', endpoint='podmproxy')
diff --git a/valence/api/v1/podmanagers.py b/valence/api/v1/podmanagers.py
new file mode 100644
index 0000000..c969fbb
--- /dev/null
+++ b/valence/api/v1/podmanagers.py
@@ -0,0 +1,54 @@
+# Copyright (c) 2016 Intel, Inc.
+#
+#    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.
+
+import logging
+
+import flask
+import flask_restful
+from six.moves import http_client
+
+from valence.common import exception
+from valence.common import utils
+from valence.controller import podmanagers
+
+
+LOG = logging.getLogger(__name__)
+
+
+class PodManagersList(flask_restful.Resource):
+
+    def get(self):
+        return utils.make_response(http_client.OK, podmanagers.get_podm_list())
+
+    def post(self):
+        values = flask.request.get_json()
+        return utils.make_response(http_client.OK,
+                                   podmanagers.create_podm(values))
+
+
+class PodManager(flask_restful.Resource):
+
+    def get(self, podm_uuid):
+        return utils.make_response(http_client.OK,
+                                   podmanagers.get_podm_by_uuid(podm_uuid))
+
+    def patch(self, podm_uuid):
+        values = flask.request.form.to_dict()
+        return utils.make_response(http_client.OK,
+                                   podmanagers.update_podm(podm_uuid, values))
+
+    def delete(self, podm_uuid):
+        podmanagers.delete_podm_by_uuid(podm_uuid)
+        resp_dict = exception.confirmation(confirm_detail="DELETED")
+        return utils.make_response(http_client.OK, resp_dict)
diff --git a/valence/common/constants.py b/valence/common/constants.py
new file mode 100644
index 0000000..1ad3d67
--- /dev/null
+++ b/valence/common/constants.py
@@ -0,0 +1,19 @@
+# Copyright (c) 2016 Intel, Inc.
+#
+#    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.
+
+PODM_AUTH_BASIC_TYPE = 'basic'
+
+PODM_STATUS_ONLINE = 'Online'
+PODM_STATUS_OFFLINE = 'Offline'
+PODM_STATUS_UNKNOWN = "Unknown"
diff --git a/valence/common/exception.py b/valence/common/exception.py
index 2f586dc..0de3a6e 100644
--- a/valence/common/exception.py
+++ b/valence/common/exception.py
@@ -86,8 +86,24 @@ class RedfishException(ValenceError):
         self.detail = message_detail
 
 
-class NotFound(Exception):
-    status = http_client.NOT_FOUND
+class NotFound(ValenceError):
+
+    def __init__(self, detail='resource not found', request_id=None):
+        self.request_id = request_id
+        self.status_code = http_client.NOT_FOUND
+        self.code = http_client.NOT_FOUND
+        self.title = "resource not found"
+        self.detail = detail
+
+
+class BadRequest(ValenceError):
+
+    def __init__(self, detail='bad request', request_id=None):
+        self.request_id = request_id
+        self.status_code = http_client.BAD_REQUEST
+        self.code = http_client.BAD_REQUEST
+        self.title = "bad request"
+        self.detail = detail
 
 
 def _error(error_code, http_status, error_title, error_detail,
diff --git a/valence/controller/podmanagers.py b/valence/controller/podmanagers.py
new file mode 100644
index 0000000..5cd9697
--- /dev/null
+++ b/valence/controller/podmanagers.py
@@ -0,0 +1,118 @@
+# Copyright (c) 2016 Intel, Inc.
+#
+#    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.
+
+import logging
+
+from valence.common import constants
+from valence.common import exception
+from valence.db import api as db_api
+from valence.redfish import redfish
+
+LOG = logging.getLogger(__name__)
+
+
+def _check_creation(values):
+    """Checking args when creating a new pod manager
+
+        authentication: should follow the format
+        name: can not be duplicated
+        url: can not be duplicated
+
+    :values: The properties for this new pod manager.
+    :returns: improved values that could be inserted to db
+    """
+
+    if not ('name' in values and
+            'url' in values and
+            'authentication' in values):
+        raise exception.BadRequest(detail="Incomplete parameters")
+    # check authentication's format and content
+    try:
+        if not (values['authentication'][0]['type'] and
+                values['authentication'][0]['auth_items']):
+            LOG.error("invalid authentication when creating podmanager")
+            raise exception.BadRequest(detail="invalid "
+                                              "authentication properties")
+    except KeyError:
+        LOG.error("Incomplete parameters when creating podmanager")
+        raise exception.BadRequest(detail="invalid "
+                                          "authentication properties")
+
+    pod_manager_list = get_podm_list()
+    names = [podm['name'] for podm in pod_manager_list]
+    urls = [podm['url'] for podm in pod_manager_list]
+    if values['name'] in names or values['url'] in urls:
+        raise exception.BadRequest('duplicated name or url !')
+
+    # input status
+    values['status'] = get_podm_status(values['url'], values['authentication'])
+
+    return values
+
+
+def _check_updation(values):
+    """Checking args when updating a exist pod manager
+
+    :values: The properties of pod manager to be updated
+    :returns: improved values that could be updated
+    """
+
+    # uuid, url can not be modified
+    if 'uuid' in values:
+        values.pop('uuid')
+    if 'url' in values:
+        values.pop('url')
+    return values
+
+
+def get_podm_list():
+    return map(lambda x: x.as_dict(), db_api.Connection.list_podmanager())
+
+
+def get_podm_by_uuid(uuid):
+    return db_api.Connection.get_podmanager_by_uuid(uuid).as_dict()
+
+
+def create_podm(values):
+    values = _check_creation(values)
+    return db_api.Connection.create_podmanager(values).as_dict()
+
+
+def update_podm(uuid, values):
+    values = _check_updation(values)
+    return db_api.Connection.update_podmanager(uuid, values).as_dict()
+
+
+def delete_podm_by_uuid(uuid):
+    # TODO(hubian) this need to break the links between podm and its Nodes
+    return db_api.Connection.delete_podmanager(uuid)
+
+
+def get_podm_status(url, authentication):
+    """get pod manager running status by its url and auth
+
+    :param url: The url of pod manager.
+    :param authentication: array, The auth(s) info of pod manager.
+
+    :returns: status of the pod manager
+    """
+    for auth in authentication:
+        # TODO(Hubian) Only consider and support basic auth type here.
+        # After decided to support other auth type this would be improved.
+        if auth['type'] == constants.PODM_AUTH_BASIC_TYPE:
+            username = auth['auth_items']['username']
+            password = auth['auth_items']['password']
+            return redfish.pod_status(url, username, password)
+
+    return constants.PODM_STATUS_UNKNOWN
diff --git a/valence/redfish/redfish.py b/valence/redfish/redfish.py
index 5eb27d5..635c09c 100644
--- a/valence/redfish/redfish.py
+++ b/valence/redfish/redfish.py
@@ -18,8 +18,10 @@ import logging
 import os
 
 import requests
+from requests import auth
 from six.moves import http_client
 
+from valence.common import constants
 from valence.common import exception
 from valence.common import utils
 from valence import config as cfg
@@ -106,6 +108,18 @@ def pods():
     return json.dumps(pods)
 
 
+def pod_status(pod_url, username, password):
+    try:
+        resp = requests.get(pod_url,
+                            auth=auth.HTTPBasicAuth(username, password))
+        if resp.status_code == http_client.OK:
+            return constants.PODM_STATUS_ONLINE
+        else:
+            return constants.PODM_STATUS_OFFLINE
+    except requests.RequestException:
+        return constants.PODM_STATUS_OFFLINE
+
+
 def urls2list(url):
     # This will extract the url values from @odata.id inside Members
     resp = send_request(url)
@@ -272,7 +286,7 @@ def get_systembyid(systemid):
 def get_nodebyid(nodeid):
     node = nodes_list({"Id": nodeid})
     if not node:
-        raise exception.NotFound()
+        raise exception.NotFound(detail='Node: %s not found' % nodeid)
     return node[0]
 
 
diff --git a/valence/tests/unit/controller/test_podmanagers.py b/valence/tests/unit/controller/test_podmanagers.py
new file mode 100644
index 0000000..db22464
--- /dev/null
+++ b/valence/tests/unit/controller/test_podmanagers.py
@@ -0,0 +1,165 @@
+#    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.
+
+import copy
+import mock
+import unittest
+
+from valence.common import constants
+from valence.common.exception import BadRequest
+from valence.controller import podmanagers
+
+
+class TestPodManagers(unittest.TestCase):
+
+    @mock.patch('valence.controller.podmanagers.get_podm_list')
+    @mock.patch('valence.controller.podmanagers.get_podm_status')
+    def test_check_creation(self, mock_get_podm_status, mock_get_podm_list):
+        mock_get_podm_list.return_value = [
+            {"name": "test1",
+             "url": "https://10.0.0.1"},
+            {"name": "test2",
+             "url": "https://10.0.0.2"}
+        ]
+        mock_get_podm_status.return_value = constants.PODM_STATUS_ONLINE
+
+        values = {"name": "podm_name",
+                  "url": "https://10.240.212.123",
+                  "authentication": [
+                      {
+                          "type": "basic",
+                          "auth_items": {
+                              "username": "xxxxxxx",
+                              "password": "xxxxxxx"
+                          }
+                      }
+                  ]}
+
+        result_values = copy.deepcopy(values)
+        result_values['status'] = constants.PODM_STATUS_ONLINE
+
+        self.assertEqual(podmanagers._check_creation(values), result_values)
+        mock_get_podm_status.assert_called_once_with(values['url'],
+                                                     values['authentication'])
+        mock_get_podm_list.assert_called_once_with()
+
+    def test_check_creation_incomplete_parameters(self):
+        incomplete_values = {
+            'name': 'name',
+            'url': 'url'
+        }
+        self.assertRaises(BadRequest,
+                          podmanagers._check_creation,
+                          incomplete_values)
+
+    def test_check_creation_invalid_authentication(self):
+        invalid_authentication_values = {
+            "name": "podm_name",
+            "url": "https://10.0.0.2",
+            'authentication': {
+                "username": "username",
+                "password": "password"
+            }
+        }
+        self.assertRaises(BadRequest,
+                          podmanagers._check_creation,
+                          invalid_authentication_values)
+
+    @mock.patch('valence.controller.podmanagers.get_podm_list')
+    def test_check_creation_duplicate_Exception(self, mock_get_podm_list):
+        mock_get_podm_list.return_value = [
+            {"name": "test1",
+             "url": "https://10.0.0.1",
+             'authentication': "authentication"},
+            {"name": "test2",
+             "url": "https://10.0.0.2",
+             'authentication': "authentication"
+             }
+        ]
+
+        name_duplicate_values = {"name": "test1",
+                                 "url": "https://10.240.212.123",
+                                 'authentication': [
+                                     {
+                                         "type": "basic",
+                                         "auth_items": {
+                                             "username": "username",
+                                             "password": "password"
+                                         }
+                                     }
+                                 ]}
+        url_duplicate_values = {"name": "podm_name",
+                                "url": "https://10.0.0.2",
+                                'authentication': [
+                                    {
+                                        "type": "basic",
+                                        "auth_items": {
+                                            "username": "username",
+                                            "password": "password"
+                                        }
+                                    }
+                                ]}
+
+        self.assertRaises(BadRequest,
+                          podmanagers._check_creation,
+                          name_duplicate_values)
+        self.assertRaises(BadRequest,
+                          podmanagers._check_creation,
+                          url_duplicate_values)
+        self.assertEqual(mock_get_podm_list.call_count, 2)
+
+    def test_check_updation_ignore_url_uuid(self):
+        values = {
+            "uuid": "uuid",
+            "url": "url",
+            "name": "name"
+        }
+        result_values = copy.deepcopy(values)
+        result_values.pop('url')
+        result_values.pop('uuid')
+
+        self.assertEqual(podmanagers._check_updation(values), result_values)
+
+    @mock.patch('valence.redfish.redfish.pod_status')
+    def test_get_podm_status(self, mock_pod_status):
+        mock_pod_status.return_value = constants.PODM_STATUS_ONLINE
+        authentication = [
+            {
+                "type": "basic",
+                "auth_items": {
+                    "username": "username",
+                    "password": "password"
+                }
+            }
+        ]
+        self.assertEqual(podmanagers.get_podm_status('url', authentication),
+                         constants.PODM_STATUS_ONLINE)
+        mock_pod_status.asset_called_once_with('url', "username", "password")
+
+    def test_get_podm_status_unknown(self):
+        """not basic type authentication podm status set value to be unknown"""
+        authentication = [
+            {
+                "type": "CertificateAuthority",
+                "auth_items": {
+                    "public_key": "xxxxxxx"
+                }
+            },
+            {
+                "type": "DynamicCode",
+                "auth_items": {
+                    "code": "xxxxxxx"
+                }
+            }
+        ]
+        self.assertEqual(podmanagers.get_podm_status('url', authentication),
+                         constants.PODM_STATUS_UNKNOWN)
diff --git a/valence/tests/unit/redfish/test_redfish.py b/valence/tests/unit/redfish/test_redfish.py
index 5cc48ea..8da5ac2 100644
--- a/valence/tests/unit/redfish/test_redfish.py
+++ b/valence/tests/unit/redfish/test_redfish.py
@@ -13,9 +13,12 @@
 from unittest import TestCase
 
 import mock
+import requests
+from requests import auth
 from requests.compat import urljoin
 from six.moves import http_client
 
+from valence.common import constants
 from valence.common import exception
 from valence import config as cfg
 from valence.redfish import redfish
@@ -193,9 +196,9 @@ class TestRedfish(TestCase):
                                     mock_make_response):
         mock_get_url.return_value = '/redfish/v1/Nodes'
         delete_result = fakes.fake_delete_composednode_ok()
-        fake_delete_resopnse = fakes.mock_request_get(delete_result,
+        fake_delete_response = fakes.mock_request_get(delete_result,
                                                       http_client.NO_CONTENT)
-        mock_request.return_value = fake_delete_resopnse
+        mock_request.return_value = fake_delete_response
         redfish.delete_composednode(101)
         mock_request.assert_called_with('/redfish/v1/Nodes/101', 'DELETE')
         expected_content = {
@@ -218,3 +221,42 @@ class TestRedfish(TestCase):
         self.assertRaises(exception.RedfishException,
                           redfish.delete_composednode, 101)
         self.assertFalse(mock_make_response.called)
+
+    @mock.patch('requests.get')
+    def test_get_podm_status_Offline_by_wrong_auth(self, mock_get):
+        fake_resp = fakes.mock_request_get({}, 401)
+        mock_get.return_value = fake_resp
+        self.assertEqual(redfish.pod_status('url', 'username', 'password'),
+                         constants.PODM_STATUS_OFFLINE)
+        mock_get.asset_called_once_with('url',
+                                        auth=auth.HTTPBasicAuth('username',
+                                                                'password'))
+
+    @mock.patch('requests.get')
+    def test_get_podm_status_Offline_by_http_exception(self, mock_get):
+        mock_get.side_effect = requests.ConnectionError
+        self.assertEqual(redfish.pod_status('url', 'username', 'password'),
+                         constants.PODM_STATUS_OFFLINE)
+        mock_get.asset_called_once_with('url',
+                                        auth=auth.HTTPBasicAuth('username',
+                                                                'password'))
+        # SSL Error
+        mock_get.side_effect = requests.exceptions.SSLError
+        self.assertEqual(redfish.pod_status('url', 'username', 'password'),
+                         constants.PODM_STATUS_OFFLINE)
+        self.assertEqual(mock_get.call_count, 2)
+        # Timeout
+        mock_get.side_effect = requests.Timeout
+        self.assertEqual(redfish.pod_status('url', 'username', 'password'),
+                         constants.PODM_STATUS_OFFLINE)
+        self.assertEqual(mock_get.call_count, 3)
+
+    @mock.patch('requests.get')
+    def test_get_podm_status_Online(self, mock_get):
+        fake_resp = fakes.mock_request_get({}, http_client.OK)
+        mock_get.return_value = fake_resp
+        self.assertEqual(redfish.pod_status('url', 'username', 'password'),
+                         constants.PODM_STATUS_ONLINE)
+        mock_get.asset_called_once_with('url',
+                                        auth=auth.HTTPBasicAuth('username',
+                                                                'password'))