> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart: Ihren ersten Webhook empfangen

> Wählen Sie zwischen Webhook Tester, registriertem Webhook-Endpunkt und Event Sink — dann einen getunnelten Receiver aufsetzen, die Signatur prüfen und Zustellungen aus der Konsole erneut senden.

## Sprachhinweis

Diese deutsche Variante ist eine gekürzte Übersetzung: Der Abschnitt „Step 6 — Move to an event sink when you outgrow HTTP receivers" existiert nur in der englischen Fassung: [/en/guides/first-webhook-quickstart](https://docs.orbit.devotel.io/en/guides/first-webhook-quickstart). Code-Blöcke, Endpoint-Pfade, API-Feldnamen und Fehlercodes bleiben englisch.

# Quickstart: Ihren ersten Webhook empfangen

Drei Zustellflächen bringen Orbit-Ereignisse von der Plattform; dieses Guide hilft bei der Wahl und geht dann die vollständige Schleife des registrierten Endpunkts durch — Tunnel, Registrierung, Verifikation, Replay.

## Step 1 — Zustellfläche wählen

| Fläche | Was es ist | Wann wählen |
| - | - | - |
| **Webhook Tester** | Dashboard-Werkzeug (**Developer → Webhook Tester**), das ein synthetisches, unsigniertes Ereignis an eine beliebige HTTPS-URL sendet und Status, Header und Body Ihrer Antwort zeigt | Beim Iterieren an Payload-Form oder Antwortbehandlung, bevor Sie einen echten Endpunkt registrieren |
| **Registrierter Webhook-Endpunkt** | Ein dauerhaftes Abo: signiert, mit Retries, dedupliziert und dead-lettered, auf Ihren HTTPS-Receiver zeigend | Für alles, was in Produktion zählt |
| **Event Sink** | Streamt jedes abonnierte Ereignis in Ihr eigenes Kafka-Topic oder einen Batch-HTTP-Collector | High-Volume-Verbrauch in Infrastruktur, die Sie bereits betreiben |

Starten Sie mit dem Tester, solange Sie experimentieren. Wechseln Sie zu einem registrierten Endpunkt, sobald die Integration real wird — der Tester kann Requests nicht signieren und übt Ihre Verifikationslogik nie aus.

## Step 2 — Lokalen Endpunkt mit einem Tunnel erreichbar machen

```bash theme={null}
# any tunnel works — ngrok, localtunnel, cloudflared
ngrok http 3000
```

Kopieren Sie die HTTPS-Forwarding-URL — das ist die Adresse, die Sie im nächsten Schritt registrieren. Lassen Sie den Tunnel laufen, während Sie Registrierung und Replay durchgehen.

## Step 3 — Endpunkt in der Konsole registrieren (oder über die API)

Gehen Sie im Dashboard zu **Developer → Webhooks → Add endpoint**. Fügen Sie Ihre Tunnel-URL ein, abonnieren Sie ein oder zwei Ereignistypen und speichern Sie. Die Konsole zeigt das Klartext-Signing-Secret (`whsec_...`) genau einmal — kopieren Sie es jetzt in eine Umgebungsvariable.

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/webhooks \
  -H "X-API-Key: dv_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-tunnel-url.ngrok.io/webhooks/orbit",
    "events": ["message.delivered"]
  }'
```

Die Antwort trägt Ihre Endpunkt-ID (`wh_...`) und das einmalige Klartext-Secret (`whsec_...`) — persistieren Sie es jetzt, denn jeder spätere `GET` auf den Endpunkt liefert nur noch einen maskierten Wert. Schmale `events`-Listen halten den Testverkehr übersichtlich; `*` ist eine Produktionsentscheidung, keine Entwicklungentscheidung.

## Step 4 — Signatur empfangen und prüfen

Registrierte Zustellungen treffen signiert ein, mit einem `X-Orbit-Signature`-Header im Format `t=<unix>,v1=<hex>`. Ihr Receiver muss `HMAC_SHA256(secret, "<t>.<raw body>")` über die rohen Request-Bytes prüfen — bevor eine JSON-Middleware sie parsed — und Zeitstempel älter als 5 Minuten verwerfen. Ein minimaler Node-Check:

```javascript theme={null}
import crypto from "node:crypto";

function verifySignature(rawBody, header, secret) {
  if (!header) return false;
  let t = null;
  const v1s = [];
  for (const part of header.split(",")) {
    const [key, value] = part.trim().split("=");
    if (key === "t") t = value;
    else if (key === "v1") v1s.push(value);
  }
  if (!t || v1s.length === 0) return false;

  const ageSec = Math.floor(Date.now() / 1000) - Number(t);
  if (!Number.isFinite(ageSec) || ageSec < 0 || ageSec > 5 * 60) return false;

  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${t}.${rawBody.toString("utf8")}`, "utf8")
    .digest("hex");

  return v1s.some((candidate) => {
    const a = Buffer.from(candidate, "hex");
    const b = Buffer.from(expected, "hex");
    return a.length === b.length && crypto.timingSafeEqual(a, b);
  });
}
```

Antworten Sie mit `2xx` innerhalb des 30-Sekunden-Fensters und deduplizieren Sie über die Envelope-`id` — Retries und Replays liefern dieselbe ID erneut. Der vollständige Vertrag (Retry-Zeitplan, Dead-Letter-Queue) steht im [Webhooks overview](https://docs.orbit.devotel.io/webhooks/overview.md).

## Step 5 — Zustellungen aus der Konsole erneut senden

Jeder Zustellversuch ist unter **Developer → Webhooks → Events** einsehbar — wählen Sie eine Zeile, um Payload und die Antwort Ihres Servers zu sehen. Eine fehlgeschlagene Zustellung lässt sich mit **Replay** auf der Zeile erneut senden, damit Sie Ihren Receiver reparieren und dasselbe signierte Ereignis erneut feuern können, ohne neuen Verkehr auszulösen.

Zustellungen, die den Retry-Zeitplan erschöpfen, landen in der Dead-Letter-Queue unter **Developer → Webhooks → Dead-letter queue** und sind 7 Tage lang replaybar.

## Siehe auch

* [Test webhooks with the Webhook Tester](https://docs.orbit.devotel.io/guides/webhook-tester.md) — unsignierte synthetische Sendungen zum Iterieren
* [Build your first webhook receiver](https://docs.orbit.devotel.io/webhooks/first-receiver.md) — vollständiger Receiver-Durchgang in Node und Python
* [Build a durable webhook consumer](https://docs.orbit.devotel.io/guides/webhook-consumer.md) — Produktionsreifer Receiver mit Queued Processing


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.