diff --git a/.coveragerc b/.coveragerc
index 6dcd20f6ad6eb1f232ab1eea68c10413d6762cd4..fe5242327dcf0665add61958d1073bd38bc4fad8 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -480,6 +480,7 @@ omit =
     homeassistant/components/nissan_leaf/*
     homeassistant/components/nmap_tracker/device_tracker.py
     homeassistant/components/nmbs/sensor.py
+    homeassistant/components/notion/__init__.py
     homeassistant/components/notion/binary_sensor.py
     homeassistant/components/notion/sensor.py
     homeassistant/components/noaa_tides/sensor.py
diff --git a/homeassistant/components/notion/.translations/en.json b/homeassistant/components/notion/.translations/en.json
index b05f613a73ffa61782e1ef48192258d432c71b98..b729b368c37e81357e709e7261e8dac3ffcca7d3 100644
--- a/homeassistant/components/notion/.translations/en.json
+++ b/homeassistant/components/notion/.translations/en.json
@@ -1,7 +1,9 @@
 {
     "config": {
+        "abort": {
+            "already_configured": "This username is already in use."
+        },
         "error": {
-            "identifier_exists": "Username already registered",
             "invalid_credentials": "Invalid username or password",
             "no_devices": "No devices found in account"
         },
diff --git a/homeassistant/components/notion/__init__.py b/homeassistant/components/notion/__init__.py
index 1e04c4a8e8effa4b8876df9b92b452499816a1c5..f387e82025380d5868c6b3e64c7b98df8565cf17 100644
--- a/homeassistant/components/notion/__init__.py
+++ b/homeassistant/components/notion/__init__.py
@@ -22,7 +22,6 @@ from homeassistant.helpers.dispatcher import (
 from homeassistant.helpers.entity import Entity
 from homeassistant.helpers.event import async_track_time_interval
 
-from .config_flow import configured_instances
 from .const import DATA_CLIENT, DEFAULT_SCAN_INTERVAL, DOMAIN, TOPIC_DATA_UPDATE
 
 _LOGGER = logging.getLogger(__name__)
@@ -84,9 +83,6 @@ async def async_setup(hass, config):
 
     conf = config[DOMAIN]
 
-    if conf[CONF_USERNAME] in configured_instances(hass):
-        return True
-
     hass.async_create_task(
         hass.config_entries.flow.async_init(
             DOMAIN,
@@ -103,6 +99,11 @@ async def async_setup(hass, config):
 
 async def async_setup_entry(hass, config_entry):
     """Set up Notion as a config entry."""
+    if not config_entry.unique_id:
+        hass.config_entries.async_update_entry(
+            config_entry, unique_id=config_entry.data[CONF_USERNAME]
+        )
+
     session = aiohttp_client.async_get_clientsession(hass)
 
     try:
diff --git a/homeassistant/components/notion/config_flow.py b/homeassistant/components/notion/config_flow.py
index 2af231d582e4d8dc61e8fa9b3f09f52fb7808758..58c5c0d44eea626994b2d39fe5c1dc76a1f4de45 100644
--- a/homeassistant/components/notion/config_flow.py
+++ b/homeassistant/components/notion/config_flow.py
@@ -5,35 +5,27 @@ import voluptuous as vol
 
 from homeassistant import config_entries
 from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
-from homeassistant.core import callback
 from homeassistant.helpers import aiohttp_client
 
-from .const import DOMAIN
+from .const import DOMAIN  # pylint: disable=unused-import
 
 
-@callback
-def configured_instances(hass):
-    """Return a set of configured Notion instances."""
-    return set(
-        entry.data[CONF_USERNAME] for entry in hass.config_entries.async_entries(DOMAIN)
-    )
-
-
-@config_entries.HANDLERS.register(DOMAIN)
-class NotionFlowHandler(config_entries.ConfigFlow):
+class NotionFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
     """Handle a Notion config flow."""
 
     VERSION = 1
     CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL
 
-    async def _show_form(self, errors=None):
-        """Show the form to the user."""
-        data_schema = vol.Schema(
+    def __init__(self):
+        """Initialize the config flow."""
+        self.data_schema = vol.Schema(
             {vol.Required(CONF_USERNAME): str, vol.Required(CONF_PASSWORD): str}
         )
 
+    async def _show_form(self, errors=None):
+        """Show the form to the user."""
         return self.async_show_form(
-            step_id="user", data_schema=data_schema, errors=errors or {}
+            step_id="user", data_schema=self.data_schema, errors=errors or {}
         )
 
     async def async_step_import(self, import_config):
@@ -42,12 +34,11 @@ class NotionFlowHandler(config_entries.ConfigFlow):
 
     async def async_step_user(self, user_input=None):
         """Handle the start of the config flow."""
-
         if not user_input:
             return await self._show_form()
 
-        if user_input[CONF_USERNAME] in configured_instances(self.hass):
-            return await self._show_form({CONF_USERNAME: "identifier_exists"})
+        await self.async_set_unique_id(user_input[CONF_USERNAME])
+        self._abort_if_unique_id_configured()
 
         session = aiohttp_client.async_get_clientsession(self.hass)
 
diff --git a/homeassistant/components/notion/strings.json b/homeassistant/components/notion/strings.json
index 8825e25bfe841a394e3cfd55a7d0b2dc29ccc4c1..fa47c2819ba0368f71ae52902be3cd487dae10e8 100644
--- a/homeassistant/components/notion/strings.json
+++ b/homeassistant/components/notion/strings.json
@@ -11,9 +11,11 @@
       }
     },
     "error": {
-      "identifier_exists": "Username already registered",
       "invalid_credentials": "Invalid username or password",
       "no_devices": "No devices found in account"
+    },
+    "abort": {
+      "already_configured": "This username is already in use."
     }
   }
 }
diff --git a/tests/components/notion/test_config_flow.py b/tests/components/notion/test_config_flow.py
index f7651a570cffe796d7b4b2d4662142d1e07a745e..60ca4c07fb5a0193e9397704582dfc0660a7632d 100644
--- a/tests/components/notion/test_config_flow.py
+++ b/tests/components/notion/test_config_flow.py
@@ -6,6 +6,7 @@ import pytest
 
 from homeassistant import data_entry_flow
 from homeassistant.components.notion import DOMAIN, config_flow
+from homeassistant.config_entries import SOURCE_USER
 from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
 
 from tests.common import MockConfigEntry, mock_coro
@@ -29,12 +30,16 @@ async def test_duplicate_error(hass):
     """Test that errors are shown when duplicates are added."""
     conf = {CONF_USERNAME: "user@host.com", CONF_PASSWORD: "password123"}
 
-    MockConfigEntry(domain=DOMAIN, data=conf).add_to_hass(hass)
-    flow = config_flow.NotionFlowHandler()
-    flow.hass = hass
+    MockConfigEntry(domain=DOMAIN, unique_id="user@host.com", data=conf).add_to_hass(
+        hass
+    )
 
-    result = await flow.async_step_user(user_input=conf)
-    assert result["errors"] == {CONF_USERNAME: "identifier_exists"}
+    result = await hass.config_entries.flow.async_init(
+        DOMAIN, context={"source": SOURCE_USER}, data=conf
+    )
+
+    assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
+    assert result["reason"] == "already_configured"
 
 
 @pytest.mark.parametrize(
@@ -46,6 +51,7 @@ async def test_invalid_credentials(hass, mock_aionotion):
 
     flow = config_flow.NotionFlowHandler()
     flow.hass = hass
+    flow.context = {"source": SOURCE_USER}
 
     result = await flow.async_step_user(user_input=conf)
     assert result["errors"] == {"base": "invalid_credentials"}
@@ -55,6 +61,7 @@ async def test_show_form(hass):
     """Test that the form is served with no input."""
     flow = config_flow.NotionFlowHandler()
     flow.hass = hass
+    flow.context = {"source": SOURCE_USER}
 
     result = await flow.async_step_user(user_input=None)
 
@@ -68,6 +75,7 @@ async def test_step_import(hass, mock_aionotion):
 
     flow = config_flow.NotionFlowHandler()
     flow.hass = hass
+    flow.context = {"source": SOURCE_USER}
 
     result = await flow.async_step_import(import_config=conf)
     assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
@@ -84,6 +92,7 @@ async def test_step_user(hass, mock_aionotion):
 
     flow = config_flow.NotionFlowHandler()
     flow.hass = hass
+    flow.context = {"source": SOURCE_USER}
 
     result = await flow.async_step_user(user_input=conf)
     assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY