diff --git a/homeassistant/components/alexa/__init__.py b/homeassistant/components/alexa/__init__.py
index a5ed4b59628..b683f5cfc7c 100644
--- a/homeassistant/components/alexa/__init__.py
+++ b/homeassistant/components/alexa/__init__.py
@@ -10,17 +10,34 @@ import logging
 import voluptuous as vol
 
 from homeassistant.helpers import config_validation as cv
+from homeassistant.helpers import entityfilter
 
-from . import flash_briefings, intent
+from . import flash_briefings, intent, smart_home
 from .const import (
-    CONF_AUDIO, CONF_DISPLAY_URL, CONF_TEXT, CONF_TITLE, CONF_UID, DOMAIN)
+    CONF_AUDIO, CONF_DISPLAY_URL, CONF_TEXT, CONF_TITLE, CONF_UID, DOMAIN,
+    CONF_FILTER, CONF_ENTITY_CONFIG)
 
 _LOGGER = logging.getLogger(__name__)
 
 CONF_FLASH_BRIEFINGS = 'flash_briefings'
+CONF_SMART_HOME = 'smart_home'
 
 DEPENDENCIES = ['http']
 
+ALEXA_ENTITY_SCHEMA = vol.Schema({
+    vol.Optional(smart_home.CONF_DESCRIPTION): cv.string,
+    vol.Optional(smart_home.CONF_DISPLAY_CATEGORIES): cv.string,
+    vol.Optional(smart_home.CONF_NAME): cv.string,
+})
+
+SMART_HOME_SCHEMA = vol.Schema({
+    vol.Optional(
+        CONF_FILTER,
+        default=lambda: entityfilter.generate_filter([], [], [], [])
+    ): entityfilter.FILTER_SCHEMA,
+    vol.Optional(CONF_ENTITY_CONFIG): {cv.entity_id: ALEXA_ENTITY_SCHEMA}
+})
+
 CONFIG_SCHEMA = vol.Schema({
     DOMAIN: {
         CONF_FLASH_BRIEFINGS: {
@@ -31,7 +48,10 @@ CONFIG_SCHEMA = vol.Schema({
                 vol.Required(CONF_TEXT, default=""): cv.template,
                 vol.Optional(CONF_DISPLAY_URL): cv.template,
             }]),
-        }
+        },
+        # vol.Optional here would mean we couldn't distinguish between an empty
+        # smart_home: and none at all.
+        CONF_SMART_HOME: vol.Any(SMART_HOME_SCHEMA, None),
     }
 }, extra=vol.ALLOW_EXTRA)
 
@@ -47,4 +67,12 @@ def async_setup(hass, config):
     if flash_briefings_config:
         flash_briefings.async_setup(hass, flash_briefings_config)
 
+    try:
+        smart_home_config = config[CONF_SMART_HOME]
+    except KeyError:
+        pass
+    else:
+        smart_home_config = smart_home_config or SMART_HOME_SCHEMA({})
+        smart_home.async_setup(hass, smart_home_config)
+
     return True
diff --git a/homeassistant/components/alexa/const.py b/homeassistant/components/alexa/const.py
index c243fc12d5e..7d6489b535a 100644
--- a/homeassistant/components/alexa/const.py
+++ b/homeassistant/components/alexa/const.py
@@ -8,6 +8,9 @@ CONF_AUDIO = 'audio'
 CONF_TEXT = 'text'
 CONF_DISPLAY_URL = 'display_url'
 
+CONF_FILTER = 'filter'
+CONF_ENTITY_CONFIG = 'entity_config'
+
 ATTR_UID = 'uid'
 ATTR_UPDATE_DATE = 'updateDate'
 ATTR_TITLE_TEXT = 'titleText'
diff --git a/homeassistant/components/alexa/smart_home.py b/homeassistant/components/alexa/smart_home.py
index 7360b22a89f..70b6f3cd9bc 100644
--- a/homeassistant/components/alexa/smart_home.py
+++ b/homeassistant/components/alexa/smart_home.py
@@ -7,16 +7,17 @@ from uuid import uuid4
 
 from homeassistant.components import (
     alert, automation, cover, fan, group, input_boolean, light, lock,
-    media_player, scene, script, switch)
+    media_player, scene, script, switch, http)
+import homeassistant.core as ha
+import homeassistant.util.color as color_util
+from homeassistant.util.decorator import Registry
 from homeassistant.const import (
     ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, CONF_NAME, SERVICE_LOCK,
     SERVICE_MEDIA_NEXT_TRACK, SERVICE_MEDIA_PAUSE, SERVICE_MEDIA_PLAY,
     SERVICE_MEDIA_PREVIOUS_TRACK, SERVICE_MEDIA_STOP,
     SERVICE_SET_COVER_POSITION, SERVICE_TURN_OFF, SERVICE_TURN_ON,
     SERVICE_UNLOCK, SERVICE_VOLUME_SET)
-import homeassistant.core as ha
-import homeassistant.util.color as color_util
-from homeassistant.util.decorator import Registry
+from .const import CONF_FILTER, CONF_ENTITY_CONFIG
 
 _LOGGER = logging.getLogger(__name__)
 
@@ -26,6 +27,8 @@ API_EVENT = 'event'
 API_HEADER = 'header'
 API_PAYLOAD = 'payload'
 
+SMART_HOME_HTTP_ENDPOINT = '/api/alexa/smart_home'
+
 CONF_DESCRIPTION = 'description'
 CONF_DISPLAY_CATEGORIES = 'display_categories'
 
@@ -113,6 +116,51 @@ class Config:
         self.entity_config = entity_config or {}
 
 
+@ha.callback
+def async_setup(hass, config):
+    """Activate Smart Home functionality of Alexa component.
+
+    This is optional, triggered by having a `smart_home:` sub-section in the
+    alexa configuration.
+
+    Even if that's disabled, the functionality in this module may still be used
+    by the cloud component which will call async_handle_message directly.
+    """
+    smart_home_config = Config(
+        should_expose=config[CONF_FILTER],
+        entity_config=config.get(CONF_ENTITY_CONFIG),
+    )
+    hass.http.register_view(SmartHomeView(smart_home_config))
+
+
+class SmartHomeView(http.HomeAssistantView):
+    """Expose Smart Home v3 payload interface via HTTP POST."""
+
+    url = SMART_HOME_HTTP_ENDPOINT
+    name = 'api:alexa:smart_home'
+
+    def __init__(self, smart_home_config):
+        """Initialize."""
+        self.smart_home_config = smart_home_config
+
+    @asyncio.coroutine
+    def post(self, request):
+        """Handle Alexa Smart Home requests.
+
+        The Smart Home API requires the endpoint to be implemented in AWS
+        Lambda, which will need to forward the requests to here and pass back
+        the response.
+        """
+        hass = request.app['hass']
+        message = yield from request.json()
+
+        _LOGGER.debug("Received Alexa Smart Home request: %s", message)
+
+        response = yield from async_handle_message(
+            hass, self.smart_home_config, message)
+        return b'' if response is None else self.json(response)
+
+
 @asyncio.coroutine
 def async_handle_message(hass, config, message):
     """Handle incoming API messages."""
diff --git a/tests/components/alexa/test_smart_home.py b/tests/components/alexa/test_smart_home.py
index 1d98b87b960..330f2c254bb 100644
--- a/tests/components/alexa/test_smart_home.py
+++ b/tests/components/alexa/test_smart_home.py
@@ -1,9 +1,12 @@
 """Test for smart home alexa support."""
 import asyncio
+import json
 from uuid import uuid4
 
 import pytest
 
+from homeassistant.setup import async_setup_component
+from homeassistant.components import alexa
 from homeassistant.components.alexa import smart_home
 from homeassistant.helpers import entityfilter
 
@@ -1155,3 +1158,45 @@ def test_entity_config(hass):
     assert len(appliance['capabilities']) == 1
     assert appliance['capabilities'][-1]['interface'] == \
         'Alexa.PowerController'
+
+
+@asyncio.coroutine
+def do_http_discovery(config, hass, test_client):
+    """Submit a request to the Smart Home HTTP API."""
+    yield from async_setup_component(hass, alexa.DOMAIN, config)
+    http_client = yield from test_client(hass.http.app)
+
+    request = get_new_request('Alexa.Discovery', 'Discover')
+    response = yield from http_client.post(
+        smart_home.SMART_HOME_HTTP_ENDPOINT,
+        data=json.dumps(request),
+        headers={'content-type': 'application/json'})
+    return response
+
+
+@asyncio.coroutine
+def test_http_api(hass, test_client):
+    """With `smart_home:` HTTP API is exposed."""
+    config = {
+        'alexa': {
+            'smart_home': None
+        }
+    }
+
+    response = yield from do_http_discovery(config, hass, test_client)
+    response_data = yield from response.json()
+
+    # Here we're testing just the HTTP view glue -- details of discovery are
+    # covered in other tests.
+    assert response_data['event']['header']['name'] == 'Discover.Response'
+
+
+@asyncio.coroutine
+def test_http_api_disabled(hass, test_client):
+    """Without `smart_home:`, the HTTP API is disabled."""
+    config = {
+        'alexa': {}
+    }
+    response = yield from do_http_discovery(config, hass, test_client)
+
+    assert response.status == 404