# Idempotenz und Rate Limiting: Keys, 429, Retry-After, RateLimit

> Der Idempotency-Key-Header (IETF-Draft) macht ein wiederholtes POST sicher: der Server speichert das erste Ergebnis pro Key innerhalb eines Dedup-Fensters und spielt es bei jeder Wiederholung erneut ab, was Exactly-once-Einreichung ergibt. Rate Limiting schützt den Dienst: Requests über dem Limit erhalten 429 Too Many Requests mit Retry-After, und RateLimit-Header bewerben das verbleibende Kontingent, sodass Clients sich selbst drosseln.

- Kanonische URL: https://www.broadnet.me/de/reference/idempotency-and-rate-limiting
- Sprache: de
- Zuletzt aktualisiert: 2026-07-19
- Herausgeber: BroadNet (https://www.broadnet.me)

Zwei standardnahe HTTP-Muster für sichere, wohlerzogene Clients: der Idempotency-Key-Header (IETF-Draft) für Exactly-once-Einreichung mit Dedup-Fenster und Response-Replay, und Rate Limiting — 429 mit Retry-After, die RateLimit-/RateLimit-Policy-Header, Token Buckets und Client-Backpressure.

## Der Idempotency-Key-Header

Der Nachrichtenversand ist ein POST, das nicht idempotent ist, und dennoch zwingen Netze Clients zum Retry, wenn eine Response verloren geht — was den klassischen Doppelversand erzeugt. Der Idempotency-Key-Draft der IETF-HTTP-API-Arbeitsgruppe standardisiert die Lösung: der Client erzeugt einen eindeutigen Key (eine UUID) pro logischer Operation und sendet ihn im Idempotency-Key-Request-Header. Der Server verzeichnet den Key mit dem Ergebnis des ersten Requests, und wenn er denselben Key erneut sieht, führt er kein zweites Mal aus — er gibt das gespeicherte Ergebnis zurück. So ist ein Retry nach einem Timeout garantiert harmlos: entweder ist der erste Versuch nie angekommen (und dieser führt aus) oder er ist es (und sein Ergebnis wird erneut abgespielt). Der Key gehört zur Operation, nicht zur Verbindung, daher verwendet der Client denselben Key über jeden Retry dieses einen Versands hinweg.

*Idempotentes POST mit einem clientgenerierten Key*

```http
# Generic IETF-draft example (not the BroadNet API, which takes no
# Idempotency-Key header: see /developers/idempotency)
POST /v1/messages HTTP/1.1
Host: api.example
Idempotency-Key: 8f14e45f-ea7b-4c0f-9b2a-1d2c3e4f5a6b
Content-Type: application/json

{ "to": "+15551234567", "text": "..." }

# first call  -> 202 Accepted, id 01HZY8Q3M6   (executed, stored)
# same key    -> 202 Accepted, id 01HZY8Q3M6   (replayed, not re-sent)
```

## Dedup-Fenster, Response-Replay und Konflikte

Ein Idempotency-Key wird nicht für immer erinnert; der Server hält ihn für ein Dedup-Fenster (üblicherweise 24 Stunden), lang genug, um jeden realistischen Retry abzudecken, und lässt ihn dann ablaufen. Innerhalb dieses Fensters spielt eine Wiederholung des Keys den gespeicherten Statuscode und Body wortgetreu erneut ab — dasselbe 202 und dieselbe Message-ID —, sodass der Client genau das sieht, was er gesehen hätte, wäre die erste Response angekommen. Zwei Randfälle brauchen explizite Behandlung. Wird ein Key mit einem anderen Request-Body wiederverwendet, ist das ein Client-Bug, und der Server gibt 409 Conflict zurück, statt still das Falsche zu senden. Trifft ein Retry ein, während der erste Request noch in Bearbeitung ist, gibt der Server einen Konflikt oder ‚in progress‘ zurück, statt eine zweite Ausführung zu starten, sodass Nebenläufigkeit die Garantie nicht aushebeln kann.

*Idempotency-Key-Ergebnisse*

| Situation | Serververhalten | Status |
|---|---|---|
| Neuer Key | Ausführen, Schlüssel + Ergebnis speichern | Normal (z. B. 202) |
| Gleicher Schlüssel, gleicher Body | Gespeicherte Antwort erneut ausliefern, nicht erneut ausführen | Ursprünglicher Status |
| Gleicher Schlüssel, anderer Body | Ablehnen – Schlüssel ist an die erste Payload gebunden | 409 Conflict |
| Wiederholung, während die erste Anfrage noch läuft | Keine zweite Ausführung starten | 409 / in Bearbeitung |
| Schlüssel abgelaufen (Zeitfenster überschritten) | Als neu behandelt | Normal |

## Rate Limiting und 429

Eine gemeinsam genutzte Messaging-Plattform schützt sich selbst und andere Tenants, indem sie begrenzt, wie schnell ein Client aufrufen darf, und signalisiert eine Überschreitung mit einem bestimmten Status. RFC 9110 und RFC 6585 definieren 429 Too Many Requests genau dafür: der Client hat in einer gegebenen Zeit zu viele Requests gesendet. Ein wohlerzogener Server koppelt das 429 mit einem Retry-After-Header, der dem Client sagt, wie lange er warten soll, bevor er es erneut versucht (entweder eine Verzögerung in Sekunden oder ein HTTP-Datum). Die Pflicht des Clients ist, ihn zu befolgen — anhalten, das angegebene Intervall warten, dann fortfahren — statt sofort erneut zu versuchen, was die Überlast nur vertieft. Ein 429 ist transient und gefahrlos wiederholbar, anders als ein 4xx, das einen fehlerhaften Request anzeigt.

*429 mit Retry-After- und RateLimit-Headern*

```http
HTTP/1.1 429 Too Many Requests
Retry-After: 2
RateLimit: limit=100, remaining=0, reset=2
RateLimit-Policy: 100;w=1
Content-Type: application/problem+json

{ "type": "https://example/problems/rate-limited",
  "title": "Too Many Requests", "status": 429 }
```

## RateLimit- und RateLimit-Policy-Header

Erst nach einem 429 zu reagieren ist verschwenderisch; der IETF-RateLimit-Header-Draft lässt einen Client sein Budget sehen, bevor er es überschreitet. Bei gewöhnlichen Responses bewirbt der Server das aktuelle Kontingent mit einem RateLimit-Header, der das Limit, die verbleibende Zuteilung und die Sekunden bis zum Zurücksetzen des Fensters trägt, sowie mit einem RateLimit-Policy-Header, der die Policy selbst beschreibt (zum Beispiel 100 Requests pro 1-Sekunden-Fenster). Ein Client, der diese liest, kann sich takten — langsamer werden, wenn remaining gegen null geht — und löst nie ein 429 aus. Das verwandelt Rate Limiting von einer strafenden nachträglichen Abweisung in ein kooperatives Signal, was der ganze Sinn der Standardisierung der Header-Namen ist, damit jede Client-Bibliothek sie konsumieren kann.

*Standard-Header zur Rate-Limit-Signalisierung*

| Header | Überträgt | Beispiel |
|---|---|---|
| 429 Too Many Requests | Der Status bei Limitüberschreitung | Statuszeile |
| Retry-After | Wartezeit vor einem erneuten Versuch | Retry-After: 2 |
| RateLimit | Limit / verbleibend / Reset für das Fenster | limit=100, remaining=17, reset=1 |
| RateLimit-Policy | Die geltende Kontingentrichtlinie | 100;w=1 (100 per 1s) |

## Token Bucket und wie Limits durchgesetzt werden

Der Token-Bucket-Algorithmus ist der übliche Mechanismus hinter diesen Headern, weil er die anhaltende Rate deckelt und dabei kurze Bursts toleriert. Ein Bucket hält bis zu einer festen Anzahl Tokens und füllt sich mit einer gleichmäßigen Rate wieder auf; jeder Request entnimmt ein Token, und ein Request, der den Bucket leer vorfindet, wird mit 429 abgewiesen. Die Bucket-Größe bestimmt den Burst, den ein Client auf einmal ausgeben darf, und die Nachfüllrate bestimmt die langfristige Obergrenze, sodass ein Client nach einer Ruhephase einen kurzen Burst senden, den Durchschnitt aber nicht überschreiten kann. Der RateLimit-remaining-Wert ist praktisch der Token-Zählstand und reset ist, wann der Bucket wieder aufgefüllt sein wird — genau die Information, die ein getakteter Client braucht. Diese Flusskontrolle auf HTTP-Ebene ist das REST-Pendant zur SMPP-Window-Größe und zur enquire_link-Drosselung auf der binären Session.

## Client-Backpressure

Die Client-Hälfte guten Rate-Limit-Verhaltens ist Backpressure: die ausgehende Last so zu formen, dass sie innerhalb des beworbenen Budgets bleibt, statt alles abzufeuern und 429er zu absorbieren. In der Praxis heißt das ein clientseitiger Limiter (ein Token Bucket, der den des Servers spiegelt), das Lesen der RateLimit-Header zur Anpassung des Tempos und, bei einem 429, ein Backoff für das Retry-After-Intervall mit Jitter vor der Wiederaufnahme. Bei einem Massenversand bedeutet dies, Einreichungen auf die anhaltende Obergrenze zu dosieren, statt sie abzukippen, sodass die Plattform gesund bleibt und die eigene Latenz des Clients vorhersehbar bleibt. BroadNet dokumentiert sein konkretes Idempotenz- und Rate-Limit-Verhalten für Entwickler.

## Häufige Fragen

### Was macht der Idempotency-Key-Header?

Er macht ein wiederholtes POST sicher. Der Client sendet einen eindeutigen Key pro logischer Operation; der Server führt den ersten Request mit diesem Key aus und speichert das Ergebnis, dann spielt er das gespeicherte Ergebnis bei jeder Wiederholung desselben Keys innerhalb eines Dedup-Fensters erneut ab. So führt ein Retry nach einer verlorenen Response entweder einmal aus oder spielt erneut ab — nie ein Doppelversand. Er ist in einem IETF-HTTP-API-Arbeitsgruppen-Draft spezifiziert.

### Wie lange merkt sich der Server einen Idempotency-Key?

Für ein Dedup-Fenster — üblicherweise rund 24 Stunden —, lang genug, um jeden realistischen Retry abzudecken, danach läuft der Key ab und eine Wiederverwendung wird als neu behandelt. Innerhalb des Fensters spielt eine Wiederholung des Keys den ursprünglichen Statuscode und Body wortgetreu erneut ab, statt neu auszuführen.

### Was passiert, wenn ich einen Idempotency-Key mit einem anderen Body wiederverwende?

Der Server weist ihn mit 409 Conflict ab. Der Key ist an das Payload des ersten Requests gebunden, daher wird eine Wiederverwendung mit einem anderen Body als Client-Fehler behandelt, statt still die falsche Nachricht zu senden. Verwenden Sie denselben Key nur für Retries der identischen Operation.

### Was sollte ein Client tun, wenn er ein 429 erhält?

Anhalten und den Retry-After-Header befolgen — die angegebenen Sekunden warten (oder bis zum angegebenen Datum), dann fortfahren — statt sofort erneut zu versuchen, was die Überlast nur vertieft. Ein 429 ist transient und nach Ablauf der Wartezeit gefahrlos wiederholbar, idealerweise mit etwas Jitter, damit nicht viele Clients im Gleichschritt fortfahren.

### Wofür sind die RateLimit- und RateLimit-Policy-Header?

Sie lassen einen Client sein Kontingent sehen, bevor er es überschreitet. RateLimit trägt das Limit, die verbleibende Zuteilung und die Reset-Zeit für das aktuelle Fenster; RateLimit-Policy beschreibt die Policy (zum Beispiel 100 Requests pro Sekunde). Ein Client, der sie liest, kann sich takten und ein 429 ganz vermeiden. Beide sind in einem IETF-Draft definiert.

### Wie hängt ein Token Bucket mit den RateLimit-Headern zusammen?

Der Token Bucket ist der Durchsetzungsmechanismus: ein Bucket fester Größe füllt sich mit gleichmäßiger Rate wieder auf, jeder Request gibt ein Token aus, und ein leerer Bucket ergibt ein 429. Der RateLimit-remaining-Wert ist im Wesentlichen der aktuelle Token-Zählstand und reset ist, wann der Bucket sich wieder auffüllt — sodass ein Client, der diese Header liest, genau weiß, wie viel Burst und anhaltende Rate ihm bleiben.

## Quellen

- [IETF draft — Idempotency-Key HTTP Header Field](https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-idempotency-key-header)
- [IETF draft — RateLimit header fields for HTTP](https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-ratelimit-headers)

## Verwandte Seiten

- [REST-Messaging-API-Design](https://www.broadnet.me/de/reference/rest-messaging-api-design)
- [Webhook-Zustellung & Zuverlässigkeit](https://www.broadnet.me/de/reference/webhook-delivery-and-reliability)
- [SMPP enquire_link & Drosselung](https://www.broadnet.me/de/reference/smpp-enquire-link-throttling)
- [BroadNet Idempotenz-Leitfaden](https://www.broadnet.me/developers/idempotency)
- [BroadNet Rate Limits](https://www.broadnet.me/de/developers/rate-limits)
