diff --git a/bin/send-dsn b/bin/send-dsn
index e3cb49c2e3ec6788bc284f3439ff9f01c56c47d8..6cc6785c493fbf78dfabcad906adbaeb3883d1f6 100755
--- a/bin/send-dsn
+++ b/bin/send-dsn
@@ -2,21 +2,40 @@
 # Tento skript se volá při doručování pošty (například pomocí "execute" v Sieve)
 # a předá mail webové části OSMO přes /api/email-dsn.
 
+import os
+from pathlib import Path
 import requests
 from requests.exceptions import RequestException
 import sys
 
 if len(sys.argv) != 2:
-    print('Arguments: <URL of OSMO root>/', file=sys.stderr)
+    print('Arguments: <URL of OSMO root>', file=sys.stderr)
     sys.exit(1)
 
 osmo_url = sys.argv[1]
 mail = sys.stdin.buffer.read()
 
+key_path = Path.home() / '.config/osmo/dsn-api-key'
 try:
-    reply = requests.post(f'{osmo_url}api/email-dsn', data=mail, timeout=30)
-except RequestException:
+    with key_path.open() as f:
+        key = f.readline().strip()
+        if key == "":
+            print(f'Cannot read key from {key_path}', file=sys.stderr)
+            sys.exit(1)
+except OSError as e:
+    print(f'Cannot read {key_path}: {e}', file=sys.stderr)
+    sys.exit(1)
+
+try:
+    reply = requests.post(
+        os.path.join(osmo_url, 'api/email-dsn'),
+        data=mail,
+        headers={'Authorization': f'Bearer {key}'},
+        timeout=30)
+except RequestException as e:
+    print(f'Error sending DSN: {e}')
     sys.exit(1)
 
 if reply.status_code != 200:
+    print(f'Error sending DSN: HTTP status {reply.status_code}')
     sys.exit(1)
diff --git a/etc/config.py.example b/etc/config.py.example
index 15d6230448b43e6bd81ca60807b76eefbca6d84e..a714932b78127839cda2fd3615ccb0808caba96c 100644
--- a/etc/config.py.example
+++ b/etc/config.py.example
@@ -111,3 +111,7 @@ MAILING_LIST_EXCLUDE = {
 # Maximální počet e-mailových adres, které jsme ochotni ve webovém rozhraní zobrazit
 # uživatelům bez práva unrestricted_email.
 EMAILS_SHOW_MAX = 500
+
+# Klíč k API na zpracování mailových nedoručenek. Měl by být také uložen
+# v ~/.config/osmo/dsn-api-key účtu, který volá bin/send-dsn. Nesmí obsahovat mezery.
+# DSN_API_KEY = "..."
diff --git a/mo/web/api_dsn.py b/mo/web/api_dsn.py
index 99194148f339e5526240fa03d1400914b91f0987..87bb85e061bb9a55849a1c04e23376db1f96a964 100644
--- a/mo/web/api_dsn.py
+++ b/mo/web/api_dsn.py
@@ -112,8 +112,21 @@ def process_dsn_reg(dsn: db.EmailDSN) -> None:
     dsn.reg.dsn_id = dsn.dsn_id
 
 
+def authorize_email_dsn() -> bool:
+    dsn_api_token = getattr(config, 'DSN_API_KEY', None)
+    auth_header = request.headers.get('Authorization')
+    if dsn_api_token is None or auth_header is None:
+        return False
+
+    fields = auth_header.split()
+    return len(fields) == 2 and fields[1] == dsn_api_token
+
+
 @app.route('/api/email-dsn', methods=('POST',))
 def api_email_dsn() -> Response:
+    if not authorize_email_dsn():
+        raise werkzeug.exceptions.Forbidden()
+
     body = request.get_data(cache=False)
 
     try: