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

# Verwendung von Webhooks

export const LastUpdatedDe = ({date}) => {
  const label = "Zuletzt aktualisiert:";
  return <>
      <style>{`
        .last-updated-component {
          display: inline-flex;
          align-items: center;
          gap: 8px;
          padding: 10px 16px;
          border-radius: 8px;
          margin-top: 12px;
          margin-bottom: 16px;
          font-size: 14px;
          background-color: rgba(0, 0, 0, 0.05);
          border: 1px solid rgba(0, 0, 0, 0.12);
          color: rgba(0, 0, 0, 0.75);
          line-height: 1;
        }

        .last-updated-component svg {
          flex-shrink: 0;
          vertical-align: middle;
        }

        .last-updated-component span {
          display: inline-flex !important;
          align-items: center !important;
          line-height: 1 !important;
        }

        [data-theme="dark"] .last-updated-component {
          background-color: #3a3a3a;
          border: 2px solid #888888;
          color: #ffffff;
        }

        [data-theme="dark"] .last-updated-component svg {
          stroke: #ffffff;
        }
      `}</style>
      <div className="last-updated-component">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <circle cx="12" cy="12" r="10" />
          <polyline points="12 6 12 12 16 14" />
        </svg>
        <span>
          <strong style={{
    fontWeight: 600
  }}>{label}</strong> 
          <time dateTime={date}>{date}</time>
        </span>
      </div>
    </>;
};

<div style={{textAlign: 'justify', marginBottom: '1.5rem'}}>
  Webhooks bieten Echtzeit-Benachrichtigungen für Ereignisse wie Kampagnenerstellung, -aktualisierung oder -löschung. Um diese Benachrichtigungen zu erhalten, müssen Sie eine öffentlich zugängliche URL angeben, die HTTP POST-Anfragen empfangen kann.
</div>

## Wie es funktioniert

<div style={{textAlign: 'justify', marginBottom: '1.5rem'}}>
  Wenn ein Ereignis eintritt, wird eine HTTP POST-Anfrage mit den Ereignisdetails an Ihre angegebene URL gesendet. Ihre URL muss einen HTTP 2xx-Statuscode für erfolgreiche Anfragen zurückgeben.
</div>

<div style={{textAlign: 'justify', marginBottom: '1.5rem'}}>
  Webhooks werden über die Create Webhook API erstellt, wo Sie das auslösende Ereignis mit dem Kanalfeld definieren. Ein einzelner Webhook ist pro Kanal erlaubt.
</div>

### Wiederholungsversuche und Validierung

<div style={{textAlign: 'justify', marginBottom: '1.5rem'}}>
  Wenn Ihre Webhook-URL nicht erreichbar ist, versuchen wir, die Anfrage bis zu 5 Mal innerhalb von 1 Minute zu wiederholen, wobei wir exponentielles Backoff verwenden. Wiederholungen erfolgen nur bei HTTP 5xx- oder 429-Statuscodes.
</div>

<div style={{textAlign: 'justify', marginBottom: '1.5rem'}}>
  Um die Authentizität und Integrität von Webhook-Zustellungen zu gewährleisten, müssen Sie die Signatur validieren. Topsort generiert eine Signatur unter Verwendung Ihres Webhook-Secrets und der Ereignis-Payload und fügt sie in den HTTP-Header X-TS-Signature-256 ein.
</div>

<div style={{textAlign: 'justify', marginBottom: '1.5rem'}}>
  Sie können Ihr Webhook-Secret bei der Erstellung festlegen; andernfalls wird eines generiert. Bewahren Sie Ihr Secret sicher auf.
</div>

<div style={{textAlign: 'justify', marginBottom: '1.5rem'}}>
  Topsort verwendet den HMAC-Hex-Digest (beginnend mit sha256=), um die Signatur zu berechnen. Sie müssen den Hash auf Ihrem Server neu berechnen und mit dem X-TS-Signature-256-Header vergleichen, um die Signatur zu verifizieren.
</div>

### Beispiel für Signaturverifizierung

```python theme={null}
import hmac
import hashlib

secret = "my-webhook-secret"
request = ... # eingehende Anfrage von Webhook-Zustellung

signature = hmac.new(
    key=secret.encode(),
    msg=await request.body(),
    digestmod=hashlib.sha256,
).hexdigest()

expected_signature = "sha256=" + signature
incoming_signature = request.headers["X-TS-Signature-256"]

if not hmac.compare_digest(incoming_signature, expected_signature):
    # Signatur ist ungültig, Zustellung nicht verarbeiten
else:
    # Signatur ist gültig, Zustellung verarbeiten
```

***

<LastUpdatedDe date="2025-11-18" />
