diff --git a/.env b/.env
index fba9a1f4389c4a8593b3a8adca627acf438afc29..00c4a532427036fa7956104783e39e6f580a7a6c 100644
--- a/.env
+++ b/.env
@@ -15,3 +15,10 @@ DEFAULT_DAILY_FEED_TIME=13:00
 
 CERN_OIDC_CLIENT_ID=notifications-dev
 CERN_OIDC_CLIENT_SECRET=fill-me
+
+# Auditing
+# ETCD_HOST=localhost
+# ETCD_PORT=2379
+# AUDITING=true
+# ETCD_USER=audituser
+# ETCD_PASSWORD=fill-me
diff --git a/.isort.cfg b/.isort.cfg
index a05ae595fe43b6724964b71320837cb73016a486..3c7785a099cb0fd12dcb388bcc032017d9e02e35 100644
--- a/.isort.cfg
+++ b/.isort.cfg
@@ -4,4 +4,4 @@ multi_line_output=3
 include_trailing_comma=True
 lines_after_imports=2
 not_skip=__init__.py
-known_third_party=dateutil,megabus,psycopg2,pytest,requests,sqlalchemy,stomp,yaml
+known_third_party=dateutil,etcd3,megabus,psycopg2,pytest,requests,sqlalchemy,stomp,yaml
diff --git a/Makefile b/Makefile
index adb6692fb7306c2009b54eb33671d83a5ad4afc2..99e756358ae067353f28bab608382a1d6c312001 100644
--- a/Makefile
+++ b/Makefile
@@ -42,6 +42,7 @@ docker-rebuild-env:
 .PHONY: docker-build-env
 
 docker-build-env-local:
+	docker-compose -f docker-compose.local.yml build
 	docker-compose -f docker-compose.local.yml up --remove-orphans
 .PHONY: docker-build-env-local
 
diff --git a/docker-compose.full.yml b/docker-compose.full.yml
index e129dc5488483dd058e9e81fa2d2d77cc0edae59..90d68c2dc14db5c0c51220b0a458c95f2e951bcf 100644
--- a/docker-compose.full.yml
+++ b/docker-compose.full.yml
@@ -56,8 +56,24 @@ services:
       timeout: 5s
       retries: 5
 
+  etcd:
+    image: bitnami/etcd:3.5.1
+    volumes:
+      - etcd-data:/bitnami/etcd/data:rw
+    entrypoint: /opt/bitnami/etcd/bin/etcd
+    command:
+      - '--listen-client-urls=http://0.0.0.0:2379'
+      - '--advertise-client-urls=http://etcd:2379'
+      - '--data-dir=/bitnami/etcd/data'
+    networks:
+      - default
+    ports:
+      - 2379:2379
+      - 2380:2380
+
 networks:
   default:
 
 volumes:
   pgsql-data:
+  etcd-data:
diff --git a/docker-compose.job.yml b/docker-compose.job.yml
index 6dfe1e14a2e24e3e79fc5dfc3536c55497375394..dc5a47d7b1bc13b4a5a7da8db296040832781884 100644
--- a/docker-compose.job.yml
+++ b/docker-compose.job.yml
@@ -62,8 +62,24 @@ services:
       timeout: 5s
       retries: 5
 
+  etcd:
+    image: bitnami/etcd:3.5.1
+    volumes:
+      - etcd-data:/bitnami/etcd/data:rw
+    entrypoint: /opt/bitnami/etcd/bin/etcd
+    command:
+      - '--listen-client-urls=http://0.0.0.0:2379'
+      - '--advertise-client-urls=http://etcd:2379'
+      - '--data-dir=/bitnami/etcd/data'
+    networks:
+      - default
+    ports:
+      - 2379:2379
+      - 2380:2380
+
 networks:
   default:
 
 volumes:
   pgsql-data:
+  etcd-data:
diff --git a/docker-compose.local.yml b/docker-compose.local.yml
index 53f34b23855d9ea335c399f89de17a11f7f385c0..9e4f5540b24884156089ccec4980b9fd2a5dde15 100644
--- a/docker-compose.local.yml
+++ b/docker-compose.local.yml
@@ -19,5 +19,6 @@ services:
     extra_hosts:
       - "activemq:127.0.0.1"
       - "pg_db:127.0.0.1"
+      - "etcd:127.0.0.1"
 networks:
   default:
diff --git a/docker-compose.test.yml b/docker-compose.test.yml
index 7641ceec297998c3c8ee4fa1c7f91f4f103fced9..47cfe0c55ce33636ad4ead51cdf6b9617005652b 100644
--- a/docker-compose.test.yml
+++ b/docker-compose.test.yml
@@ -55,8 +55,24 @@ services:
       timeout: 5s
       retries: 5
 
+  etcd:
+    image: bitnami/etcd:3.5.1
+    volumes:
+      - etcd-data:/bitnami/etcd/data:rw
+    entrypoint: /opt/bitnami/etcd/bin/etcd
+    command:
+      - '--listen-client-urls=http://0.0.0.0:2379'
+      - '--advertise-client-urls=http://etcd:2379'
+      - '--data-dir=/bitnami/etcd/data'
+    networks:
+      - default
+    ports:
+      - 2379:2379
+      - 2380:2380
+
 networks:
   default:
 
 volumes:
   pgsql-data:
+  etcd-data:
diff --git a/notifications_routing/auditing.py b/notifications_routing/auditing.py
new file mode 100644
index 0000000000000000000000000000000000000000..51eac8f08e19b0bc43156d243d74df69f70fcff2
--- /dev/null
+++ b/notifications_routing/auditing.py
@@ -0,0 +1,52 @@
+"""Auditing Router definition."""
+import json
+import logging
+import uuid
+from datetime import datetime
+
+import etcd3
+
+from notifications_routing.config import Config
+
+
+client = etcd3.client(
+    host=Config.ETCD_HOST, port=Config.ETCD_PORT, user=Config.ETCD_USER, password=Config.ETCD_PASSWORD
+)
+
+
+def audit_notification(notification_id, value, user_id=None, key=None):
+    """Put audit notification information into audit DB."""
+    if Config.AUDITING is False:
+        logging.info("Audit disabled")
+        return
+
+    if not key:
+        key = uuid.uuid4()
+    try:
+        client.put(
+            (
+                f"/notifications/{notification_id}/{Config.AUDIT_ID}"
+                f"/{'target_users/' + user_id + '/' if user_id else ''}{key}"
+            ),
+            json.dumps({"date": datetime.now().strftime("%d/%m/%Y %H:%M:%S"), **value}),
+        )
+    except Exception:
+        logging.exception("Error auditing to etcd3:")
+
+
+def get_audit_notification(notification_id, key, user_id=None):
+    """Get audit notification information from audit DB."""
+    if Config.AUDITING is False:
+        logging.info("Audit disabled")
+        return
+
+    try:
+        return client.get(
+            (
+                f"/notifications/{notification_id}/{Config.AUDIT_ID}"
+                f"/{'target_users/' + user_id + '/' if user_id else ''}{key}"
+            )
+        )[0]
+    except Exception:
+        logging.exception("Error getting from etcd")
+        return None
diff --git a/notifications_routing/config.py b/notifications_routing/config.py
index 0c3ee9d5399525c6a4e44b12ca1b05adc9ec3ae4..5a518846e75530df6d9af81bc003e11a39aab945 100644
--- a/notifications_routing/config.py
+++ b/notifications_routing/config.py
@@ -61,6 +61,14 @@ class Config:
     FREQUENCY_TYPE = os.getenv("FREQUENCY_TYPE", "DAILY")
     FEED_QUEUE = os.getenv("FEED_QUEUE", "email-daily")
 
+    # Etcd auditing
+    ETCD_HOST = os.getenv("ETCD_HOST", "localhost")
+    ETCD_PORT = os.getenv("ETCD_PORT", 2379)
+    AUDITING = os.getenv("AUDITING", False)
+    ETCD_USER = os.getenv("ETCD_USER", None)
+    ETCD_PASSWORD = os.getenv("ETCD_PASSWORD", None)
+    AUDIT_ID = os.getenv("AUDIT_ID", "router")
+
 
 class DevelopmentConfig(Config):
     """Development configuration overrides."""
diff --git a/notifications_routing/preferences.py b/notifications_routing/preferences.py
index 7ce9cf950a20c06f907e45248dcca50d7addf3a0..a8fad14fdafa9efb818c28127c8e30e0eaf740e6 100644
--- a/notifications_routing/preferences.py
+++ b/notifications_routing/preferences.py
@@ -6,6 +6,7 @@ from typing import Dict, List, Set
 import megabus
 from megabus import Publisher
 
+from notifications_routing.auditing import audit_notification
 from notifications_routing.config import Config
 from notifications_routing.data_source.data_source import DataSource
 from notifications_routing.data_source.postgres.postgres_data_source import UserFeedNotification
@@ -118,11 +119,27 @@ def apply_user_preferences(
             create_feed_notification(
                 data_source, message, user, preference.method, preference.scheduledTime, preference.scheduledDay
             )
+            audit_notification(
+                message[OutputMessageKeys.ID],
+                {"event": "Preference added to feed", "method": preference.method},
+                user_id=user[data_source.EMAIL],
+            )
             continue
 
         if preference.method == "LIVE":
             for device in preference.devices:
                 send_to_device(publisher, message, device)
+                audit_notification(
+                    message[OutputMessageKeys.ID],
+                    {
+                        "event": "Sent to consumer",
+                        "method": preference.method,
+                        "device": device.type,
+                        "subtype": device.subtype,
+                        "token": device.token,
+                    },
+                    user_id=user[data_source.EMAIL],
+                )
             continue
 
         logging.error("Invalid delivery method: %s", preference.method)
@@ -185,7 +202,7 @@ def apply_all(
     email: str,
     user_devices: Dict[str, List[str]],
 ):
-    """Specific implementation of apply default preferences.
+    """Specific implementation to send to all devices for Critical notifications.
 
     :param publisher: Publisher object used to publish messages
     :param message: message object
@@ -194,7 +211,17 @@ def apply_all(
     """
     logging.debug("Applying to all types/devices")
     for device in user_devices[DataSource.DEVICES]:
-        send_to_device(publisher, message, email, device)
+        send_to_device(publisher, message, device)
+        audit_notification(
+            message[OutputMessageKeys.ID],
+            {
+                "event": "Critical sent to consumer",
+                "device": device.type,
+                "subtype": device.subtype,
+                "token": device.token,
+            },
+            user_id=email,
+        )
 
 
 def apply_default_preferences(publisher: megabus.Publisher, message: Dict, email: str):
@@ -207,6 +234,11 @@ def apply_default_preferences(publisher: megabus.Publisher, message: Dict, email
     """
     logging.debug("Applying default preference")
     send_live_email(publisher, message, email)
+    audit_notification(
+        message[OutputMessageKeys.ID],
+        {"event": "Default sent to consumer", "device": "MAIL", "token": email},
+        user_id=email,
+    )
 
 
 def send_live_email(publisher: Publisher, message: Dict, email: str):
diff --git a/notifications_routing/router.py b/notifications_routing/router.py
index d5523d6ceff56c06b4a07de7761a4ff5506b0f48..ff21379f24f84e0b0d2717827286f90c4ca88264 100644
--- a/notifications_routing/router.py
+++ b/notifications_routing/router.py
@@ -5,6 +5,7 @@ from typing import Dict, List
 
 import megabus
 
+from notifications_routing.auditing import audit_notification
 from notifications_routing.config import Config
 from notifications_routing.data_source.data_source import DataSource
 from notifications_routing.exceptions import NotFoundDataSourceError
@@ -136,6 +137,7 @@ class Router(megabus.Listener):
     def process_target_users(self, message):
         """Process unique users list, if targeted, intersection or standard post."""
         if OutputMessageKeys.PRIVATE in message and message[OutputMessageKeys.PRIVATE]:
+            audit_notification(message[OutputMessageKeys.ID], {"event": "Start processing targeted notification"})
             logging.debug("Processing direct notification %s", message[OutputMessageKeys.ID])
             target_users = self.get_target_users(
                 message[OutputMessageKeys.CHANNEL_ID],
@@ -157,6 +159,7 @@ class Router(megabus.Listener):
 
             return target_users
         else:
+            audit_notification(message[OutputMessageKeys.ID], {"event": "Start processing"})
             logging.debug("Processing general notification %s", message[OutputMessageKeys.ID])
             target_users = self.get_channel_users(message[OutputMessageKeys.CHANNEL_ID])
             if not target_users:
@@ -171,6 +174,10 @@ class Router(megabus.Listener):
         if not target_users:
             return
 
+        audit_notification(
+            message[OutputMessageKeys.ID],
+            {"event": "Expanded recipients", "total": len(target_users), "targets": target_users},
+        )
         for user in target_users:
             # Never logged in users, apply default preferences
             has_logged_in = self.data_source.LAST_LOGIN in user and user.get(self.data_source.LAST_LOGIN)
@@ -189,6 +196,11 @@ class Router(megabus.Listener):
             if self.data_source.is_user_mute_active(
                 user[self.data_source.USER_ID], message[OutputMessageKeys.CHANNEL_ID]
             ):
+                audit_notification(
+                    message[OutputMessageKeys.ID],
+                    {"event": "Mute active, skipped user"},
+                    user_id=user[self.data_source.EMAIL],
+                )
                 logging.info(
                     "MUTE enabled for user %s for channel %s, skipping",
                     user[self.data_source.USER_ID],
diff --git a/poetry.lock b/poetry.lock
index 098237b81b1131b63bd24725cf28786c810a75e9..299ef968fba3f372529f03e85ce39512de4ec9c2 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -76,6 +76,20 @@ category = "main"
 optional = false
 python-versions = "*"
 
+[[package]]
+name = "etcd3"
+version = "0.12.0"
+description = "Python client for the etcd3 API"
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+grpcio = ">=1.27.1"
+protobuf = ">=3.6.1"
+six = ">=1.12.0"
+tenacity = ">=6.1.0"
+
 [[package]]
 name = "filelock"
 version = "3.0.12"
@@ -129,6 +143,20 @@ python-versions = ">=3.5"
 [package.dependencies]
 python-dateutil = ">=2.7"
 
+[[package]]
+name = "grpcio"
+version = "1.43.0"
+description = "HTTP/2-based RPC framework"
+category = "main"
+optional = false
+python-versions = ">=3.6"
+
+[package.dependencies]
+six = ">=1.5.2"
+
+[package.extras]
+protobuf = ["grpcio-tools (>=1.43.0)"]
+
 [[package]]
 name = "identify"
 version = "1.5.13"
@@ -259,6 +287,14 @@ pyyaml = ">=5.1"
 toml = "*"
 virtualenv = ">=20.0.8"
 
+[[package]]
+name = "protobuf"
+version = "3.19.1"
+description = "Protocol Buffers"
+category = "main"
+optional = false
+python-versions = ">=3.5"
+
 [[package]]
 name = "psycopg2-binary"
 version = "2.8.6"
@@ -444,6 +480,17 @@ python-versions = ">=3.6,<4.0"
 [package.dependencies]
 docopt = ">=0.6.2,<0.7.0"
 
+[[package]]
+name = "tenacity"
+version = "8.0.1"
+description = "Retry code until it succeeds"
+category = "main"
+optional = false
+python-versions = ">=3.6"
+
+[package.extras]
+doc = ["reno", "sphinx", "tornado (>=4.5)"]
+
 [[package]]
 name = "toml"
 version = "0.10.2"
@@ -508,7 +555,7 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake
 [metadata]
 lock-version = "1.1"
 python-versions = "^3.6.1"
-content-hash = "085e85979548b6fe588d4d23b17d33e006cfc68da2e354f5029b1263a8b76681"
+content-hash = "933a7b5055a264bb68623147be5d5b07314c1d3b6412b08a13b3410f573d2697"
 
 [metadata.files]
 appdirs = [
@@ -546,6 +593,9 @@ distlib = [
 docopt = [
     {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"},
 ]
+etcd3 = [
+    {file = "etcd3-0.12.0.tar.gz", hash = "sha256:89a704cb389bf0a010a1fa050ce19342d23bf6371ebda1c21cfe8ff3ed488726"},
+]
 filelock = [
     {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"},
     {file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"},
@@ -565,6 +615,52 @@ freezegun = [
     {file = "freezegun-1.1.0-py2.py3-none-any.whl", hash = "sha256:2ae695f7eb96c62529f03a038461afe3c692db3465e215355e1bb4b0ab408712"},
     {file = "freezegun-1.1.0.tar.gz", hash = "sha256:177f9dd59861d871e27a484c3332f35a6e3f5d14626f2bf91be37891f18927f3"},
 ]
+grpcio = [
+    {file = "grpcio-1.43.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:a4e786a8ee8b30b25d70ee52cda6d1dbba2a8ca2f1208d8e20ed8280774f15c8"},
+    {file = "grpcio-1.43.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:af9c3742f6c13575c0d4147a8454da0ff5308c4d9469462ff18402c6416942fe"},
+    {file = "grpcio-1.43.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:fdac966699707b5554b815acc272d81e619dd0999f187cd52a61aef075f870ee"},
+    {file = "grpcio-1.43.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e463b4aa0a6b31cf2e57c4abc1a1b53531a18a570baeed39d8d7b65deb16b7e"},
+    {file = "grpcio-1.43.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f11d05402e0ac3a284443d8a432d3dfc76a6bd3f7b5858cddd75617af2d7bd9b"},
+    {file = "grpcio-1.43.0-cp310-cp310-win32.whl", hash = "sha256:c36f418c925a41fccada8f7ae9a3d3e227bfa837ddbfddd3d8b0ac252d12dda9"},
+    {file = "grpcio-1.43.0-cp310-cp310-win_amd64.whl", hash = "sha256:772b943f34374744f70236bbbe0afe413ed80f9ae6303503f85e2b421d4bca92"},
+    {file = "grpcio-1.43.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:cbc9b83211d905859dcf234ad39d7193ff0f05bfc3269c364fb0d114ee71de59"},
+    {file = "grpcio-1.43.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:fb7229fa2a201a0c377ff3283174ec966da8f9fd7ffcc9a92f162d2e7fc9025b"},
+    {file = "grpcio-1.43.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:17b75f220ee6923338155b4fcef4c38802b9a57bc57d112c9599a13a03e99f8d"},
+    {file = "grpcio-1.43.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:6620a5b751b099b3b25553cfc03dfcd873cda06f9bb2ff7e9948ac7090e20f05"},
+    {file = "grpcio-1.43.0-cp36-cp36m-manylinux_2_17_aarch64.whl", hash = "sha256:1898f999383baac5fcdbdef8ea5b1ef204f38dc211014eb6977ac6e55944d738"},
+    {file = "grpcio-1.43.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47b6821238d8978014d23b1132713dac6c2d72cbb561cf257608b1673894f90a"},
+    {file = "grpcio-1.43.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80398e9fb598060fa41050d1220f5a2440fe74ff082c36dda41ac3215ebb5ddd"},
+    {file = "grpcio-1.43.0-cp36-cp36m-win32.whl", hash = "sha256:0110310eff07bb69782f53b7a947490268c4645de559034c43c0a635612e250f"},
+    {file = "grpcio-1.43.0-cp36-cp36m-win_amd64.whl", hash = "sha256:45401d00f2ee46bde75618bf33e9df960daa7980e6e0e7328047191918c98504"},
+    {file = "grpcio-1.43.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:af78ac55933811e6a25141336b1f2d5e0659c2f568d44d20539b273792563ca7"},
+    {file = "grpcio-1.43.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:8b2b9dc4d7897566723b77422e11c009a0ebd397966b165b21b89a62891a9fdf"},
+    {file = "grpcio-1.43.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:77ef653f966934b3bfdd00e4f2064b68880eb40cf09b0b99edfa5ee22a44f559"},
+    {file = "grpcio-1.43.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e95b5d62ec26d0cd0b90c202d73e7cb927c369c3358e027225239a4e354967dc"},
+    {file = "grpcio-1.43.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:04239e8f71db832c26bbbedb4537b37550a39d77681d748ab4678e58dd6455d6"},
+    {file = "grpcio-1.43.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b4a7152187a49767a47d1413edde2304c96f41f7bc92cc512e230dfd0fba095"},
+    {file = "grpcio-1.43.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8cc936a29c65ab39714e1ba67a694c41218f98b6e2a64efb83f04d9abc4386b"},
+    {file = "grpcio-1.43.0-cp37-cp37m-win32.whl", hash = "sha256:577e024c8dd5f27cd98ba850bc4e890f07d4b5942e5bc059a3d88843a2f48f66"},
+    {file = "grpcio-1.43.0-cp37-cp37m-win_amd64.whl", hash = "sha256:138f57e3445d4a48d9a8a5af1538fdaafaa50a0a3c243f281d8df0edf221dc02"},
+    {file = "grpcio-1.43.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:08cf25f2936629db062aeddbb594bd76b3383ab0ede75ef0461a3b0bc3a2c150"},
+    {file = "grpcio-1.43.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:01f4b887ed703fe82ebe613e1d2dadea517891725e17e7a6134dcd00352bd28c"},
+    {file = "grpcio-1.43.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:0aa8285f284338eb68962fe1a830291db06f366ea12f213399b520c062b01f65"},
+    {file = "grpcio-1.43.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:0edbfeb6729aa9da33ce7e28fb7703b3754934115454ae45e8cc1db601756fd3"},
+    {file = "grpcio-1.43.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:c354017819201053d65212befd1dcb65c2d91b704d8977e696bae79c47cd2f82"},
+    {file = "grpcio-1.43.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50cfb7e1067ee5e00b8ab100a6b7ea322d37ec6672c0455106520b5891c4b5f5"},
+    {file = "grpcio-1.43.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57f1aeb65ed17dfb2f6cd717cc109910fe395133af7257a9c729c0b9604eac10"},
+    {file = "grpcio-1.43.0-cp38-cp38-win32.whl", hash = "sha256:fa26a8bbb3fe57845acb1329ff700d5c7eaf06414c3e15f4cb8923f3a466ef64"},
+    {file = "grpcio-1.43.0-cp38-cp38-win_amd64.whl", hash = "sha256:ade8b79a6b6aea68adb9d4bfeba5d647667d842202c5d8f3ba37ac1dc8e5c09c"},
+    {file = "grpcio-1.43.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:124e718faf96fe44c98b05f3f475076be8b5198bb4c52a13208acf88a8548ba9"},
+    {file = "grpcio-1.43.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2f96142d0abc91290a63ba203f01649e498302b1b6007c67bad17f823ecde0cf"},
+    {file = "grpcio-1.43.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:31e6e489ccd8f08884b9349a39610982df48535881ec34f05a11c6e6b6ebf9d0"},
+    {file = "grpcio-1.43.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:0e731f660e1e68238f56f4ce11156f02fd06dc58bc7834778d42c0081d4ef5ad"},
+    {file = "grpcio-1.43.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:1f16725a320460435a8a5339d8b06c4e00d307ab5ad56746af2e22b5f9c50932"},
+    {file = "grpcio-1.43.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4b4543e13acb4806917d883d0f70f21ba93b29672ea81f4aaba14821aaf9bb0"},
+    {file = "grpcio-1.43.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:594aaa0469f4fca7773e80d8c27bf1298e7bbce5f6da0f084b07489a708f16ab"},
+    {file = "grpcio-1.43.0-cp39-cp39-win32.whl", hash = "sha256:5449ae564349e7a738b8c38583c0aad954b0d5d1dd3cea68953bfc32eaee11e3"},
+    {file = "grpcio-1.43.0-cp39-cp39-win_amd64.whl", hash = "sha256:bdf41550815a831384d21a498b20597417fd31bd084deb17d31ceb39ad9acc79"},
+    {file = "grpcio-1.43.0.tar.gz", hash = "sha256:735d9a437c262ab039d02defddcb9f8f545d7009ae61c0114e19dda3843febe5"},
+]
 identify = [
     {file = "identify-1.5.13-py2.py3-none-any.whl", hash = "sha256:9dfb63a2e871b807e3ba62f029813552a24b5289504f5b071dea9b041aee9fe4"},
     {file = "identify-1.5.13.tar.gz", hash = "sha256:70b638cf4743f33042bebb3b51e25261a0a10e80f978739f17e7fd4837664a66"},
@@ -609,6 +705,32 @@ pre-commit = [
     {file = "pre_commit-2.9.3-py2.py3-none-any.whl", hash = "sha256:6c86d977d00ddc8a60d68eec19f51ef212d9462937acf3ea37c7adec32284ac0"},
     {file = "pre_commit-2.9.3.tar.gz", hash = "sha256:ee784c11953e6d8badb97d19bc46b997a3a9eded849881ec587accd8608d74a4"},
 ]
+protobuf = [
+    {file = "protobuf-3.19.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d80f80eb175bf5f1169139c2e0c5ada98b1c098e2b3c3736667f28cbbea39fc8"},
+    {file = "protobuf-3.19.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:a529e7df52204565bcd33738a7a5f288f3d2d37d86caa5d78c458fa5fabbd54d"},
+    {file = "protobuf-3.19.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28ccea56d4dc38d35cd70c43c2da2f40ac0be0a355ef882242e8586c6d66666f"},
+    {file = "protobuf-3.19.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8b30a7de128c46b5ecb343917d9fa737612a6e8280f440874e5cc2ba0d79b8f6"},
+    {file = "protobuf-3.19.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5935c8ce02e3d89c7900140a8a42b35bc037ec07a6aeb61cc108be8d3c9438a6"},
+    {file = "protobuf-3.19.1-cp36-cp36m-win32.whl", hash = "sha256:74f33edeb4f3b7ed13d567881da8e5a92a72b36495d57d696c2ea1ae0cfee80c"},
+    {file = "protobuf-3.19.1-cp36-cp36m-win_amd64.whl", hash = "sha256:038daf4fa38a7e818dd61f51f22588d61755160a98db087a046f80d66b855942"},
+    {file = "protobuf-3.19.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e51561d72efd5bd5c91490af1f13e32bcba8dab4643761eb7de3ce18e64a853"},
+    {file = "protobuf-3.19.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:6e8ea9173403219239cdfd8d946ed101f2ab6ecc025b0fda0c6c713c35c9981d"},
+    {file = "protobuf-3.19.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db3532d9f7a6ebbe2392041350437953b6d7a792de10e629c1e4f5a6b1fe1ac6"},
+    {file = "protobuf-3.19.1-cp37-cp37m-win32.whl", hash = "sha256:615b426a177780ce381ecd212edc1e0f70db8557ed72560b82096bd36b01bc04"},
+    {file = "protobuf-3.19.1-cp37-cp37m-win_amd64.whl", hash = "sha256:d8919368410110633717c406ab5c97e8df5ce93020cfcf3012834f28b1fab1ea"},
+    {file = "protobuf-3.19.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:71b0250b0cfb738442d60cab68abc166de43411f2a4f791d31378590bfb71bd7"},
+    {file = "protobuf-3.19.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:3cd0458870ea7d1c58e948ac8078f6ba8a7ecc44a57e03032ed066c5bb318089"},
+    {file = "protobuf-3.19.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:655264ed0d0efe47a523e2255fc1106a22f6faab7cc46cfe99b5bae085c2a13e"},
+    {file = "protobuf-3.19.1-cp38-cp38-win32.whl", hash = "sha256:b691d996c6d0984947c4cf8b7ae2fe372d99b32821d0584f0b90277aa36982d3"},
+    {file = "protobuf-3.19.1-cp38-cp38-win_amd64.whl", hash = "sha256:e7e8d2c20921f8da0dea277dfefc6abac05903ceac8e72839b2da519db69206b"},
+    {file = "protobuf-3.19.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fd390367fc211cc0ffcf3a9e149dfeca78fecc62adb911371db0cec5c8b7472d"},
+    {file = "protobuf-3.19.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d83e1ef8cb74009bebee3e61cc84b1c9cd04935b72bca0cbc83217d140424995"},
+    {file = "protobuf-3.19.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36d90676d6f426718463fe382ec6274909337ca6319d375eebd2044e6c6ac560"},
+    {file = "protobuf-3.19.1-cp39-cp39-win32.whl", hash = "sha256:e7b24c11df36ee8e0c085e5b0dc560289e4b58804746fb487287dda51410f1e2"},
+    {file = "protobuf-3.19.1-cp39-cp39-win_amd64.whl", hash = "sha256:77d2fadcf369b3f22859ab25bd12bb8e98fb11e05d9ff9b7cd45b711c719c002"},
+    {file = "protobuf-3.19.1-py2.py3-none-any.whl", hash = "sha256:e813b1c9006b6399308e917ac5d298f345d95bb31f46f02b60cd92970a9afa17"},
+    {file = "protobuf-3.19.1.tar.gz", hash = "sha256:62a8e4baa9cb9e064eb62d1002eca820857ab2138440cb4b3ea4243830f94ca7"},
+]
 psycopg2-binary = [
     {file = "psycopg2-binary-2.8.6.tar.gz", hash = "sha256:11b9c0ebce097180129e422379b824ae21c8f2a6596b159c7659e2e5a00e1aa0"},
     {file = "psycopg2_binary-2.8.6-cp27-cp27m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:d14b140a4439d816e3b1229a4a525df917d6ea22a0771a2a78332273fd9528a4"},
@@ -765,6 +887,10 @@ sqlalchemy = [
     {file = "stomp.py-6.1.0-py3-none-any.whl", hash = "sha256:8a1ed68cd8b12f41ba56a8dfeff995e7866d1d47ed7f53aaa78da3bea44696b8"},
     {file = "stomp.py-6.1.0.tar.gz", hash = "sha256:1f6c7e1e5089b1d8a75161e66533cabb9895de5121cc3900cb7e12c41c1bda18"},
 ]
+tenacity = [
+    {file = "tenacity-8.0.1-py3-none-any.whl", hash = "sha256:f78f4ea81b0fabc06728c11dc2a8c01277bfc5181b321a4770471902e3eb844a"},
+    {file = "tenacity-8.0.1.tar.gz", hash = "sha256:43242a20e3e73291a28bcbcacfd6e000b02d3857a9a9fff56b297a27afdc932f"},
+]
 toml = [
     {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
     {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
diff --git a/pyproject.toml b/pyproject.toml
index 7bd870453a5bdecb35d10304a2840a4dd6a6e6ee..861134262090ca6aec8a6816f5d71e104789fa90 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -32,6 +32,7 @@ pyyaml = "^5.3.1"
 sentry-sdk = "^0.19.2"
 SQLAlchemy = "1.3.20"
 python-dateutil = "^2.8.1"
+etcd3 = "^0.12.0"
 
 [tool.poetry.dev-dependencies]
 pre-commit = "~2.9.2"
diff --git a/scripts/send.py b/scripts/send.py
index c27e23983abcf405ef52dd312e115d5dc9272766..71ca0863c7b1ecd67156e37a7c1a40837e36e87c 100644
--- a/scripts/send.py
+++ b/scripts/send.py
@@ -17,6 +17,7 @@ message_body = r"""{"id":1,"target":{"primaryKey":1,"id":"The Best Notifications
 "users":[],"summary":"sub test EO","tags":null,
 "link":"http://cds.cern.ch/record/2687667",
 "contentType":null,
+"private":false,
 "imgUrl":"http://cds.cern.ch/record/2687667/files/CLICtd.png?subformat=icon-640",
 "priority":"NORMAL"} """
 conn.send(body=message_body, destination="/queue/np.routing", headers={"persistent": "true"})