diff --git a/docs/details/callbacks.mdx b/docs/details/callbacks.mdx
new file mode 100644
index 0000000000000000000000000000000000000000..e9bac650c9c247e79b199450e7a7fcf382997cf7
--- /dev/null
+++ b/docs/details/callbacks.mdx
@@ -0,0 +1,143 @@
+---
+title: Verwendung von Callbacks
+---
+
+import ApiLink from '@site/src/components/ApiLink'
+
+Der FIT-Connect Zustelldienst informiert sendende und empfangende Systeme (API-Clients) aktiv über [neue Einreichungen](../getting-started/receiving/query.mdx) oder [Statusupdates](../getting-started/sending/query-status.mdx).
+Hierzu werden HTTP-Callbacks genutzt, die auch als [Webhooks](https://de.wikipedia.org/wiki/WebHooks) bezeichnet werden.
+Webhooks ermöglichen es, API-Clients aktiv über diese Ereignisse zu informieren ohne dass eine regelmäßige Abfrage ([Polling](https://de.wikipedia.org/wiki/Polling_(Informatik))) nötig wäre.
+Technisch werden Webhooks als HTTP-POST-Request realisiert.
+
+Im Folgenden verwenden wir die Begriffe *Callback* und *Webhook* synonym.
+
+## Callback-URL
+API-Clients stellen zum Empfang von Callbacks einen HTTP-Endpunkt bereit, an den der Zustelldienst einen HTTP-POST-Request übermitteln kann.
+API-Clients müssen auf eingehende Callbacks mit einer HTTP-Response mit Status Code `200 OK` antworten.
+Die URL dieses HTTP-Endpunkts bezeichnen wir als Callback-URL (`callbackUrl`).
+Sie wird von dem an FIT-Connect angebundenen System festgelegt.
+
+Eine solche Callback-URL kann z.B. wie folgt aussehen:
+```
+https://fachverfahren.beispielstadt.example.org/callbacks/fit-connect
+```
+
+Die Callback-URL **DARF NUR** über HTTPS erreichbar sein.
+Der Zustelldienst wird Callbacks nur über eine via HTTPS verschlüsselte Verbindung auslösen.
+
+## Konfiguration von Callbacks
+Eine Konfiguration von Callbacks ist [über das Self-Service-Portal](../getting-started/receiving/destination.mdx) und über die API-Endpunkte <ApiLink to="/destinations/{destinationId}" withMethod="put" /> bzw. <ApiLink to="/destinations/{destinationId}" withMethod="patch" /> möglich.
+Bei der Konfiguration werden die *Callback-URL* und ein *Callback-Secret* vom API-Client festgelegt.
+Das *Callback-Secret* dient der Überprüfung der Echtheit (Authentizität) von eingehenden Callbacks (siehe nächster Abschnitt).
+Das angegebene *Callback-Secret* kann über die API nur geschrieben und aktualisiert, aber nicht gelesen werden und **DARF NICHT** an Dritte weitergegeben werden.
+
+Ein sicheres *Callback-Secret* kann über die folgenden Aufrufe erzeugt werden:
+- Python: `python -c 'import secrets; print(secrets.token_urlsafe(32))'`
+- Ruby: `ruby -rsecurerandom -e 'puts SecureRandom.hex(32)'`
+- pwgen: `pwgen --secure 64 1`
+
+Die Einrichtung von Callbacks im Self-Service-Portal wird im Artikel `TODO: Link einfügen` näher beschrieben.
+
+### Konfiguration von Callbacks für Zustellpunkte
+Über die API können Callbacks für Zustellpunkte wie folgt konfiguriert werden:
+<Tabs
+defaultValue="curl"
+values={[
+  {label: 'curl', value: 'curl',},
+  {label: 'Java', value: 'java',},
+  {label: 'JavaScript', value: 'javascript',},
+]}>
+<TabItem value="curl" label="curl">
+
+```bash
+$ SERVICE_URL=...
+$ JWT_TOKEN=...
+$ DESTINATION_ID=...
+$ CALLBACK_URL=https://fachverfahren.beispielstadt.example.org/callbacks/fit-connect
+$ CALLBACK_SECRET=insecure_unsafe_qHScgrg_kP-R31jHUwp3GkVkGJolvBchz65b74Lzue0
+$ curl -X PATCH \
+    -H "Content-Type: application/json" \
+    -H "Authorization: Bearer $JWT_TOKEN" \
+    --data "{ \"callback\": { \"url\": \"$CALLBACK_URL\", \"secret\": \"$CALLBACK_SECRET\" }}" \
+    "$SERVICE_URL/destinations/$DESTINATION_ID"
+```
+
+</TabItem>
+<TabItem value="java" label="Java">
+:::caution TODO
+TODO: Codebeispiel ergänzen
+:::
+</TabItem>
+<TabItem value="JavaScript" label="JavaScript">
+:::caution TODO
+TODO: Codebeispiel ergänzen
+:::
+</TabItem>
+</Tabs>
+
+## Prüfung von Callbacks
+API-Clients, die Callbacks empfangen, **MÜSSEN** zwingend sicherstellen, dass ausgelöste Callbacks von einem vertrauenswürdigen Zustelldienst stammen.
+Hierzu enthalten Callbacks einen Message Authentication Code (HMAC) gemäß [RFC 2104](https://datatracker.ietf.org/doc/html/rfc2104) auf Basis des angegebenen *Callback-Secrets*.
+Ein Message Athentication Code kann als „symmetrische Signatur“ verstanden werden und ermöglicht die Prüfung der Herkunft und Integrität eines eingehende Callbacks.
+
+Der Message Authentication Code wird im HTTP-Header `callback-authentication` übertragen.
+Um [Replay-Angriffe](https://de.wikipedia.org/wiki/Replay-Angriff) zu vermeiden, enthält der Message Authentication Code einen aktuellen Timestamp.
+Dieser Timestamp wird im HTTP-Header `callback-timestamp` übertragen.
+Bei der Prüfung der Echtheit des ausgelösten Callbacks **MÜSSEN** API-Clients prüfen, dass der angegebene Timestamp nicht älter als **5 Minuten** ist.
+
+Das folgende Beispiel zeigt die Verwendung der HTTP-Header `callback-authentication` und `callback-timestamp`:
+```http
+POST /callbacks/fit-connect
+callback-authentication: f4eig0ht6hdlsfz6DVqGjXi1j3RAombIQ7vjG1M2TFZx1fGurzg1nOEh00lPfLEulhio1RyTOav1e1aMi69SRg==
+callback-timestamp: 1672527599
+
+{"type":"https://schema.fitko.de/fit-connect/callbacks/new-submissions","submissionIds":["f39ab143-d91a-474a-b69f-b00f1a1873c2"]}
+```
+
+Der HMAC wird gebildet aus dem im HTTP-Header `callback-timestamp` übertragenen Zeitstempel und dem im HTTP-Body übertragenen Payload, getrennt durch das Zeichen `.` (Punkt), jeweils UTF-8-kodiert.
+Als Hash-Algorithmus wird SHA-512 verwendet.
+```
+callback-authentication = BASE64(HMAC(key={callback-secret}, message={timestamp}.{http-body}))
+```
+
+Um den Message Authentication Code (HMAC) zu verifizieren, bildet der API-Client mit Hilfe des *Callback Secret* den HMAC nach und vergleicht diesen mit dem im HTTP-Header `callback-authentication` übertragenen HMAC.
+
+Bei der Prüfung **MÜSSEN** die folgenden Implementierungshinweise zwingend zu beachten:
+- Das Callback Secret **MUSS** in API-Clients konfigurierbar sein und **DARF NICHT** fest im Quellcode eines API-Clients einprogrammiert sein.
+  - Dies kann beispielsweise durch die Konfiguration des Callback Secret in einer Konfigurationsdatei oder über eine Umgebungsvariable (`$ export CALLBACK_SECRET=your_secret`) erreicht werden.
+- Bei der Erzeugung des HMAC **MUSS** der Hash-Algorithmus `SHA-512` verwendet werden.
+- Es **MUSS** geprüft werden, dass der angegebene Zeitstempel nicht älter als **5 Minuten** ist.
+- Beim Vergleich des übertragenen HMAC und des vom API-Client gebildeteten HMAC **MUSS** ein zeitlich konstanter Zeichenfolgenvergleich (*constant time string comparison*) verwendet werden.
+  - In Python kann dies über die Verwendung der Methode [`hmac.compare_digest`](https://docs.python.org/2/library/hmac.html#hmac.compare_digest) erreicht werden.
+  - In Ruby kann dies über die Verwendung der Methode [`secure_compare`](https://rubydoc.info/github/rack/rack/master/Rack/Utils:secure_compare) erreicht werden.
+- Callbacks mit ungültigem Message Authentication Code **MÜSSEN** von API-Clients ignoriert/verworfen werden.
+
+Dabei ist zunächst der Zeitstempel (`callback-timestamp`-Header) und anschließend der HMAC (`callback-authentication`-Header) zu prüfen:
+
+```python
+# 1. Timestamp überprüfen
+current_time_epoch = int(time.time())
+seconds_five_minutes = 60 * 5
+if current_time_epoch - request['headers']['callback-timestamp'] > seconds_five_minutes:
+    print('Error: timestamp too old')
+    sys.exit(1)
+else:
+    print('timestamp ok')
+
+# 2. HMAC berechnen
+payload = str(request['headers']['callback-timestamp']) + '.' + request['body']
+
+expected_hmac = hmac.digest(CALLBACK_SECRET.encode("utf-8"), payload.encode("utf-8"), digest=sha512)
+expected_hmac_base64 = base64.b64encode(expected_hmac).decode()
+
+print('hmac', expected_hmac_base64)
+
+# 3. Berechneten HMAC mit HMAC aus HTTP-Header vergleichen
+if not hmac.compare_digest(request['headers']['callback-authentication'], expected_hmac_base64):
+    print('Error: invalid hmac')
+    sys.exit(2)
+else:
+    print('hmac ok')
+```
+
+Das dargestellte Script findet sich auch zur freien Verwendung im [FIT-Connect-Tools-Repository](https://git.fitko.de/fit-connect/fit-connect-tools/-/blob/main/validate-callback.py).
diff --git a/docs/getting-started/receiving/query.mdx b/docs/getting-started/receiving/query.mdx
index dc184a6a18f763453dd8373c94b4533b9a87ba78..b56c19fb4c46f045c0303a12fa3845613d098092 100644
--- a/docs/getting-started/receiving/query.mdx
+++ b/docs/getting-started/receiving/query.mdx
@@ -5,31 +5,27 @@ title: Vorhandensein neuer Einreichungen prüfen
 
 import ApiLink from '@site/src/components/ApiLink'
 
-Neue Einreichungen können über zwei Wege erhalten werden. Entweder können neue Einreichungen über Polling abgefragt werden oder der Zustellpunkt wird über einen Callback vom Zustelldienst benachrichtigt.
-Letzteres wäre die präferierte Variante, da dadurch unnötige Anfragen vermieden werden können und die Kommunikation so auf ein notwendiges Mindestmaß reduziert wäre.
+Empfangende Systeme können sich über den Eingang neuer Einreichungen entweder durch periodische Anfragen informieren (Polling) oder vom Zustelldienst über Callbacks aktiv benachrichtigen lassen.
+Letzteres stellt die empfohle Umsetzungsvariante dar, da hierdurch unnötige Anfragen vermieden werden können, was zu einer insgesamt besseren Performance und zu einer schnelleren Benachrichtung empfangnder Systeme führt.
 
 ## Callback
+Wenn eine Callback-URL im Zustellpunkt hinterlegt ist, kann der Zustelldienst den Zustellpunkt aktiv via Callback über neue Einriechungen informieren.
+Das Format, in welchem der Callback übertragen wird, ist im Endpunkt <ApiLink to="/destinations/{destinationId}" withMethod="put" /> definiert.
+Die Konfiguration und Prüfung von Callbacks ist im Aritkel [Verwendung von Callbacks](../../details/callbacks.mdx) beschrieben.
 
-Wenn eine neue Einreichung im Zustelldienst bereitsteht und eine Callback-URL im Zustellpunkt hinterlegt ist, kann der Zustelldienst den Zustellpunkt direkt informieren.
-Das Format, in welchem der Callback übertragen wird, im Endpunkt <ApiLink to="/destinations" withMethod="post" /> beschrieben.
-Im Endeffekt, ist es jedoch ein Array mit UUIDs für jede bereitstehende Einreichung, wie im Beispiel unten.
+Callbacks zur Benachrichtigung über neue Einriechungen haben das folgende Format:
 
-```json
-[
-  "17b64151-fc80-4000-8fb7-6ddd08115780"
-]
-```
-
-:::caution Hinweis
-Der Mechanismus zum Konfigurieren und Entgegennehmen von Callbacks wird sich bis zur Veröffentlichung der finalen API-Spezifikation noch einmal ändern.
-:::
+```http
+POST /callbacks/fit-connect
+callback-authentication: f4eig0ht6hdlsfz6DVqGjXi1j3RAombIQ7vjG1M2TFZx1fGurzg1nOEh00lPfLEulhio1RyTOav1e1aMi69SRg==
+callback-timestamp: 1672527599
 
+{"type":"https://schema.fitko.de/fit-connect/callbacks/new-submissions","submissionIds":["f39ab143-d91a-474a-b69f-b00f1a1873c2"]}
+```
 
-Wenn der Zustellpunkt benachrichtigt wird, dann kann dieser über mehrere Befehle die Einreichung mit allen verbundenen Ressourcen herunterladen.
-Mehrere Befehle dahingehend, da erst alle allgemeinen Informationen zur Einreichung heruntergeladen werden müssen und dann, falls notwendig alle mit ihr verbundenen Anlagen.
+Wenn das empfangende System über den Eingang neuer Einreichungen benachrichtigt wurde, dann kann es diese wie im Artikel [Einreichung herunterladen](./download-submission.mdx) beschrieben herunterladen.
 
 ## Polling
-
 Über Polling, d.h. regelmäßiges Abfragen des Endpuntes <ApiLink to="/submissions" /> , können alle Einreichungen abgefragt werden, die zum Abholen bereitstehen.
 Dies wird aus Performancegründen jedoch nicht empfohlen.
 
diff --git a/docs/sidebar.js b/docs/sidebar.js
index 7701752a3f6d6ea75bc2ec9d83de218457c7b707..799822474902f8180991998de24fa7e400de0b21 100644
--- a/docs/sidebar.js
+++ b/docs/sidebar.js
@@ -79,6 +79,7 @@ module.exports = {
         'details/crypto',
         'details/destination-management',
         'details/jwk-creation',
+        'details/callbacks',
         'details/schema-reference',
         'details/pgp-export',
         {