diff --git a/docs/details/webhooks.mdx b/docs/details/webhooks.mdx
index 41fdb1bce4f8072162b467570634a06ae5d44814..a302cb730332282e45c51dc0bfe054ced066c7d6 100644
--- a/docs/details/webhooks.mdx
+++ b/docs/details/webhooks.mdx
@@ -1,10 +1,9 @@
 ---
-title: Sicherheitsvorgaben für Callbacks
+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.
@@ -13,47 +12,130 @@ Technisch werden Webhooks als HTTP-POST-Request realisiert.
 Im Folgenden verwenden wir die Begriffe *Callback* und *Webhook* synonym.
 
 ## Callback-URL
-Hierzu stellen API-Clients einen HTTP-Endpunkt bereit, an den der Zustelldienst einen HTTP-POST-Request mit übermitteln kann.
+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.
 
-Die URL dieses HTTP-Endpunkts (`callbackUrl`) 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 **MUSS** über HTTPS erreichbar sein.
+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
-TODO: Aushandlung des Callback Secret via API
+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">
+```shell
+$ 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 eines geheimen symmetrischen Schlüssels.
-Der geheime Schlüssel, im Folgenden *Callback Secret* genannt, wird bei der Konfiguration eines Callbacks festgelegt **DARF NICHT** an Dritte weitergegeben werden.
+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.
-
-Durch die Prüfung des Message Authentication Code können API-Clients die Herkunft und Integrität eines Callbacks verifizieren.
+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: HMAC(key={shared-secret}, message={timestamp}.{http-body})
-callback-timestamp: 1631283222821
+callback-authentication: f4eig0ht6hdlsfz6DVqGjXi1j3RAombIQ7vjG1M2TFZx1fGurzg1nOEh00lPfLEulhio1RyTOav1e1aMi69SRg==
+callback-timestamp: 1672527599
 
-{"submissionIds":["..."]}
+{"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).
+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.
 
-Dabei sind die folgenden Implementierungshinweise zwingend zu beachten:
-- 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` erreicht werden.
+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.
-- Callbacks mit ungültigem Message Authentication Code **MÜSSEN** von API-Clients irgnoriert werden.
+  - 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).