diff --git a/homeassistant/components/smartthings/__init__.py b/homeassistant/components/smartthings/__init__.py
index 9b9494dd9c53636eec5ed896f914ec5368130382..f95719a8d0211fbea43c9b7a624ab378e292c799 100644
--- a/homeassistant/components/smartthings/__init__.py
+++ b/homeassistant/components/smartthings/__init__.py
@@ -16,12 +16,18 @@ from pysmartthings import (
     Scene,
     SmartThings,
     SmartThingsAuthenticationFailedError,
+    SmartThingsSinkError,
     Status,
 )
 
 from homeassistant.config_entries import ConfigEntry
-from homeassistant.const import CONF_ACCESS_TOKEN, CONF_TOKEN, Platform
-from homeassistant.core import HomeAssistant
+from homeassistant.const import (
+    CONF_ACCESS_TOKEN,
+    CONF_TOKEN,
+    EVENT_HOMEASSISTANT_STOP,
+    Platform,
+)
+from homeassistant.core import Event, HomeAssistant
 from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
 from homeassistant.helpers import device_registry as dr
 from homeassistant.helpers.aiohttp_client import async_get_clientsession
@@ -33,6 +39,7 @@ from homeassistant.helpers.config_entry_oauth2_flow import (
 from .const import (
     CONF_INSTALLED_APP_ID,
     CONF_LOCATION_ID,
+    CONF_SUBSCRIPTION_ID,
     DOMAIN,
     EVENT_BUTTON,
     MAIN,
@@ -100,6 +107,54 @@ async def async_setup_entry(hass: HomeAssistant, entry: SmartThingsConfigEntry)
 
     client.refresh_token_function = _refresh_token
 
+    def _handle_max_connections() -> None:
+        _LOGGER.debug("We hit the limit of max connections")
+        hass.config_entries.async_schedule_reload(entry.entry_id)
+
+    client.max_connections_reached_callback = _handle_max_connections
+
+    def _handle_new_subscription_identifier(identifier: str | None) -> None:
+        """Handle a new subscription identifier."""
+        hass.config_entries.async_update_entry(
+            entry,
+            data={
+                **entry.data,
+                CONF_SUBSCRIPTION_ID: identifier,
+            },
+        )
+        if identifier is not None:
+            _LOGGER.debug("Updating subscription ID to %s", identifier)
+        else:
+            _LOGGER.debug("Removing subscription ID")
+
+    client.new_subscription_id_callback = _handle_new_subscription_identifier
+
+    if (old_identifier := entry.data.get(CONF_SUBSCRIPTION_ID)) is not None:
+        _LOGGER.debug("Trying to delete old subscription %s", old_identifier)
+        await client.delete_subscription(old_identifier)
+
+    _LOGGER.debug("Trying to create a new subscription")
+    try:
+        subscription = await client.create_subscription(
+            entry.data[CONF_LOCATION_ID],
+            entry.data[CONF_TOKEN][CONF_INSTALLED_APP_ID],
+        )
+    except SmartThingsSinkError as err:
+        _LOGGER.debug("Couldn't create a new subscription: %s", err)
+        raise ConfigEntryNotReady from err
+    subscription_id = subscription.subscription_id
+    _handle_new_subscription_identifier(subscription_id)
+
+    entry.async_create_background_task(
+        hass,
+        client.subscribe(
+            entry.data[CONF_LOCATION_ID],
+            entry.data[CONF_TOKEN][CONF_INSTALLED_APP_ID],
+            subscription,
+        ),
+        "smartthings_socket",
+    )
+
     device_status: dict[str, FullDevice] = {}
     try:
         rooms = {
@@ -171,12 +226,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: SmartThingsConfigEntry)
         client.add_unspecified_device_event_listener(handle_button_press)
     )
 
-    entry.async_create_background_task(
-        hass,
-        client.subscribe(
-            entry.data[CONF_LOCATION_ID], entry.data[CONF_TOKEN][CONF_INSTALLED_APP_ID]
-        ),
-        "smartthings_webhook",
+    async def _handle_shutdown(_: Event) -> None:
+        """Handle shutdown."""
+        await client.delete_subscription(subscription_id)
+
+    entry.async_on_unload(
+        hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _handle_shutdown)
     )
 
     await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
@@ -201,6 +256,9 @@ async def async_unload_entry(
     hass: HomeAssistant, entry: SmartThingsConfigEntry
 ) -> bool:
     """Unload a config entry."""
+    client = entry.runtime_data.client
+    if (subscription_id := entry.data.get(CONF_SUBSCRIPTION_ID)) is not None:
+        await client.delete_subscription(subscription_id)
     return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
 
 
diff --git a/homeassistant/components/smartthings/const.py b/homeassistant/components/smartthings/const.py
index a6d028aed06de6b1bce30aa67cbbd6512166342f..2ba59ade4e8525967231877ee785941b365aecbd 100644
--- a/homeassistant/components/smartthings/const.py
+++ b/homeassistant/components/smartthings/const.py
@@ -33,4 +33,5 @@ CONF_REFRESH_TOKEN = "refresh_token"
 MAIN = "main"
 OLD_DATA = "old_data"
 
+CONF_SUBSCRIPTION_ID = "subscription_id"
 EVENT_BUTTON = "smartthings.button"
diff --git a/homeassistant/components/smartthings/manifest.json b/homeassistant/components/smartthings/manifest.json
index 2a4e79bff58e27eeb7e76d4d8e1fd73f9b06ffcf..74f0e4bae83dac1568d1248b2830f8353fa2b6f7 100644
--- a/homeassistant/components/smartthings/manifest.json
+++ b/homeassistant/components/smartthings/manifest.json
@@ -29,5 +29,5 @@
   "documentation": "https://www.home-assistant.io/integrations/smartthings",
   "iot_class": "cloud_push",
   "loggers": ["pysmartthings"],
-  "requirements": ["pysmartthings==2.7.0"]
+  "requirements": ["pysmartthings==2.7.2"]
 }
diff --git a/requirements_all.txt b/requirements_all.txt
index f22db6ffd7bf26bb03c244a51b7300dcd47c5071..10e305cc47e079880ffa0dd33d66755f0f4dbeee 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -2310,7 +2310,7 @@ pysma==0.7.5
 pysmappee==0.2.29
 
 # homeassistant.components.smartthings
-pysmartthings==2.7.0
+pysmartthings==2.7.2
 
 # homeassistant.components.smarty
 pysmarty2==0.10.2
diff --git a/requirements_test_all.txt b/requirements_test_all.txt
index e8e9c477fffe5382de4972e29f63adeccbd52ba1..c2043684a80cdf832a08accf100413c35c3ed90d 100644
--- a/requirements_test_all.txt
+++ b/requirements_test_all.txt
@@ -1882,7 +1882,7 @@ pysma==0.7.5
 pysmappee==0.2.29
 
 # homeassistant.components.smartthings
-pysmartthings==2.7.0
+pysmartthings==2.7.2
 
 # homeassistant.components.smarty
 pysmarty2==0.10.2
diff --git a/tests/components/smartthings/conftest.py b/tests/components/smartthings/conftest.py
index 6de472a59a8c54204528d6e8bb74c0bf3038a825..2deef344b5e99198d9b1dfe25ce056cfd3628661 100644
--- a/tests/components/smartthings/conftest.py
+++ b/tests/components/smartthings/conftest.py
@@ -10,6 +10,7 @@ from pysmartthings.models import (
     LocationResponse,
     RoomResponse,
     SceneResponse,
+    Subscription,
 )
 import pytest
 
@@ -82,6 +83,9 @@ def mock_smartthings() -> Generator[AsyncMock]:
         client.get_rooms.return_value = RoomResponse.from_json(
             load_fixture("rooms.json", DOMAIN)
         ).items
+        client.create_subscription.return_value = Subscription.from_json(
+            load_fixture("subscription.json", DOMAIN)
+        )
         yield client
 
 
diff --git a/tests/components/smartthings/fixtures/subscription.json b/tests/components/smartthings/fixtures/subscription.json
new file mode 100644
index 0000000000000000000000000000000000000000..80f37445524952b25e0074809b1684d59a6f45fa
--- /dev/null
+++ b/tests/components/smartthings/fixtures/subscription.json
@@ -0,0 +1,16 @@
+{
+  "subscriptionId": "f5768ce8-c9e5-4507-9020-912c0c60e0ab",
+  "registrationUrl": "https://spigot-regional.api.smartthings.com/filters/f5768ce8-c9e5-4507-9020-912c0c60e0ab/activate?filterRegion=eu-west-1",
+  "name": "My Home Assistant sub",
+  "version": 20250122,
+  "subscriptionFilters": [
+    {
+      "type": "LOCATIONIDS",
+      "value": ["88a3a314-f0c8-40b4-bb44-44ba06c9c42e"],
+      "eventType": ["DEVICE_EVENT"],
+      "attribute": null,
+      "capability": null,
+      "component": null
+    }
+  ]
+}
diff --git a/tests/components/smartthings/test_config_flow.py b/tests/components/smartthings/test_config_flow.py
index 7472d7d6b71c25af61333b7dab3365ba11f3d651..4069c201225ed09ce04fd11d35b0deb3daa2b9d0 100644
--- a/tests/components/smartthings/test_config_flow.py
+++ b/tests/components/smartthings/test_config_flow.py
@@ -10,6 +10,7 @@ from homeassistant.components.smartthings.const import (
     CONF_INSTALLED_APP_ID,
     CONF_LOCATION_ID,
     CONF_REFRESH_TOKEN,
+    CONF_SUBSCRIPTION_ID,
     DOMAIN,
 )
 from homeassistant.config_entries import SOURCE_USER, ConfigEntryState
@@ -508,6 +509,7 @@ async def test_migration(
             "installed_app_id": "123123123-2be1-4e40-b257-e4ef59083324",
         },
         CONF_LOCATION_ID: "397678e5-9995-4a39-9d9f-ae6ba310236c",
+        CONF_SUBSCRIPTION_ID: "f5768ce8-c9e5-4507-9020-912c0c60e0ab",
     }
     assert mock_old_config_entry.unique_id == "397678e5-9995-4a39-9d9f-ae6ba310236c"
     assert mock_old_config_entry.version == 3
diff --git a/tests/components/smartthings/test_init.py b/tests/components/smartthings/test_init.py
index e3d865fc5c848415e25ae49a04739db407d71e3b..2083bb7ea24d3cd05a11dfe797b32d2fbb20395e 100644
--- a/tests/components/smartthings/test_init.py
+++ b/tests/components/smartthings/test_init.py
@@ -2,12 +2,21 @@
 
 from unittest.mock import AsyncMock
 
-from pysmartthings import Attribute, Capability, DeviceResponse, DeviceStatus
+from pysmartthings import (
+    Attribute,
+    Capability,
+    DeviceResponse,
+    DeviceStatus,
+    SmartThingsSinkError,
+)
+from pysmartthings.models import Subscription
 import pytest
 from syrupy import SnapshotAssertion
 
 from homeassistant.components.smartthings import EVENT_BUTTON
-from homeassistant.components.smartthings.const import DOMAIN
+from homeassistant.components.smartthings.const import CONF_SUBSCRIPTION_ID, DOMAIN
+from homeassistant.config_entries import ConfigEntryState
+from homeassistant.const import EVENT_HOMEASSISTANT_STOP
 from homeassistant.core import Event, HomeAssistant
 from homeassistant.helpers import device_registry as dr
 
@@ -63,6 +72,178 @@ async def test_button_event(
     assert events[0] == snapshot
 
 
+@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
+async def test_create_subscription(
+    hass: HomeAssistant,
+    devices: AsyncMock,
+    mock_config_entry: MockConfigEntry,
+) -> None:
+    """Test creating a subscription."""
+    assert CONF_SUBSCRIPTION_ID not in mock_config_entry.data
+
+    await setup_integration(hass, mock_config_entry)
+
+    devices.create_subscription.assert_called_once()
+
+    assert (
+        mock_config_entry.data[CONF_SUBSCRIPTION_ID]
+        == "f5768ce8-c9e5-4507-9020-912c0c60e0ab"
+    )
+
+    devices.subscribe.assert_called_once_with(
+        "397678e5-9995-4a39-9d9f-ae6ba310236c",
+        "5aaaa925-2be1-4e40-b257-e4ef59083324",
+        Subscription.from_json(load_fixture("subscription.json", DOMAIN)),
+    )
+
+
+@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
+async def test_create_subscription_sink_error(
+    hass: HomeAssistant,
+    devices: AsyncMock,
+    mock_config_entry: MockConfigEntry,
+    snapshot: SnapshotAssertion,
+) -> None:
+    """Test handling an error when creating a subscription."""
+    assert CONF_SUBSCRIPTION_ID not in mock_config_entry.data
+
+    devices.create_subscription.side_effect = SmartThingsSinkError("Sink error")
+
+    await setup_integration(hass, mock_config_entry)
+
+    devices.subscribe.assert_not_called()
+
+    assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
+    assert CONF_SUBSCRIPTION_ID not in mock_config_entry.data
+
+
+@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
+async def test_update_subscription_identifier(
+    hass: HomeAssistant,
+    devices: AsyncMock,
+    mock_config_entry: MockConfigEntry,
+) -> None:
+    """Test updating the subscription identifier."""
+    await setup_integration(hass, mock_config_entry)
+
+    assert (
+        mock_config_entry.data[CONF_SUBSCRIPTION_ID]
+        == "f5768ce8-c9e5-4507-9020-912c0c60e0ab"
+    )
+
+    devices.new_subscription_id_callback("abc")
+
+    await hass.async_block_till_done()
+
+    assert mock_config_entry.data[CONF_SUBSCRIPTION_ID] == "abc"
+
+
+@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
+async def test_stale_subscription_id(
+    hass: HomeAssistant,
+    devices: AsyncMock,
+    mock_config_entry: MockConfigEntry,
+) -> None:
+    """Test updating the subscription identifier."""
+    mock_config_entry.add_to_hass(hass)
+
+    hass.config_entries.async_update_entry(
+        mock_config_entry,
+        data={**mock_config_entry.data, CONF_SUBSCRIPTION_ID: "test"},
+    )
+
+    await hass.config_entries.async_setup(mock_config_entry.entry_id)
+    await hass.async_block_till_done()
+
+    assert (
+        mock_config_entry.data[CONF_SUBSCRIPTION_ID]
+        == "f5768ce8-c9e5-4507-9020-912c0c60e0ab"
+    )
+    devices.delete_subscription.assert_called_once_with("test")
+
+
+@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
+async def test_remove_subscription_identifier(
+    hass: HomeAssistant,
+    devices: AsyncMock,
+    mock_config_entry: MockConfigEntry,
+) -> None:
+    """Test removing the subscription identifier."""
+    await setup_integration(hass, mock_config_entry)
+
+    assert (
+        mock_config_entry.data[CONF_SUBSCRIPTION_ID]
+        == "f5768ce8-c9e5-4507-9020-912c0c60e0ab"
+    )
+
+    devices.new_subscription_id_callback(None)
+
+    await hass.async_block_till_done()
+
+    assert mock_config_entry.data[CONF_SUBSCRIPTION_ID] is None
+
+
+@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
+async def test_max_connections_handling(
+    hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry
+) -> None:
+    """Test handling reaching max connections."""
+    await setup_integration(hass, mock_config_entry)
+
+    assert (
+        mock_config_entry.data[CONF_SUBSCRIPTION_ID]
+        == "f5768ce8-c9e5-4507-9020-912c0c60e0ab"
+    )
+
+    devices.create_subscription.side_effect = SmartThingsSinkError("Sink error")
+
+    devices.max_connections_reached_callback()
+
+    await hass.async_block_till_done()
+
+    assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
+
+
+@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
+async def test_unloading(
+    hass: HomeAssistant,
+    devices: AsyncMock,
+    mock_config_entry: MockConfigEntry,
+) -> None:
+    """Test unloading the integration."""
+    await setup_integration(hass, mock_config_entry)
+
+    await hass.config_entries.async_unload(mock_config_entry.entry_id)
+    devices.delete_subscription.assert_called_once_with(
+        "f5768ce8-c9e5-4507-9020-912c0c60e0ab"
+    )
+    # Deleting the subscription automatically deletes the subscription ID
+    devices.new_subscription_id_callback(None)
+
+    assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
+    assert mock_config_entry.data[CONF_SUBSCRIPTION_ID] is None
+
+
+@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
+async def test_shutdown(
+    hass: HomeAssistant,
+    devices: AsyncMock,
+    mock_config_entry: MockConfigEntry,
+) -> None:
+    """Test shutting down Home Assistant."""
+    await setup_integration(hass, mock_config_entry)
+
+    hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
+    devices.delete_subscription.assert_called_once_with(
+        "f5768ce8-c9e5-4507-9020-912c0c60e0ab"
+    )
+    # Deleting the subscription automatically deletes the subscription ID
+    devices.new_subscription_id_callback(None)
+
+    assert mock_config_entry.state is ConfigEntryState.LOADED
+    assert mock_config_entry.data[CONF_SUBSCRIPTION_ID] is None
+
+
 @pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
 async def test_removing_stale_devices(
     hass: HomeAssistant,