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

# Ratenbegrenzungen

> Anfragekontingente für die Living Security Public API, der Vertrag für die 429-Antwort und das erneute Senden von Anfragen mit Retry-After.

Die `/v1`-API erzwingt zwei voneinander unabhängige Anfragekontingente. Eine Anfrage wird
abgelehnt, wenn eines der beiden Kontingente erschöpft ist.

| Kontingent | Gilt für |
| - | - |
| Pro API-Schlüssel | Jede Anfrage, die diesen Schlüssel verwendet, unabhängig von der Adresse |
| Pro Client-IP | Jede Anfrage von dieser Adresse, ob authentifiziert oder nicht |

Das Kontingent pro Schlüssel folgt dem Schlüssel überallhin, wo er verwendet wird. Das Kontingent pro IP-Adresse
ist das einzige Kontingent für nicht authentifizierten Datenverkehr und eine zweite Obergrenze für
authentifizierten Datenverkehr.

<Note>
  Die Begrenzungen werden vor der Authentifizierung durchgesetzt, sodass auch Anfragen mit ungültigen oder
  fehlenden Anmeldedaten auf das Kontingent der Quelle angerechnet werden. Die genauen numerischen
  Kontingente werden vom Betreiber konfiguriert und können sich ändern; der unten beschriebene Antwortvertrag
  ist die stabile Schnittstelle, auf der Sie aufbauen sollten.
</Note>

Authentifizieren Sie sich mit einer der beiden Basic-Anmeldedatenvarianten – siehe
[Quickstart](/de/developers/v1/quickstart) (`apikey:secret` oder `secret:`).
Setzen Sie `BASE` auf den regionalen Host der Organisation – siehe
[Regionen](/de/developers/v1/regions).

## Die 429-Antwort

Wenn ein Kontingent erschöpft ist, gibt die API `429 Too Many Requests` mit einem
`Retry-After`-Header (in Sekunden) und dem standardmäßigen Problem-Details-Body zurück:

```json 429 Too Many Requests theme={null}
{
  "type": "https://docs.livingsecurity.com/developers/v1/errors/rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Rate limit exceeded. Retry after the Retry-After interval.",
  "code": "rate_limited",
  "request_id": "req_...",
  "doc_url": "https://docs.livingsecurity.com/developers/v1/errors/rate_limited",
  "retryable": true
}
```

Die Antwort gibt nicht an, welches Kontingent erschöpft wurde. Behandeln Sie jede `429`
gleich: warten und dann erneut versuchen.

## 429-Antworten behandeln

<Steps>
  <Step title="Retry-After beachten">
    Warten Sie mindestens so viele Sekunden, wie im `Retry-After`-Header angegeben sind, bevor Sie
    es erneut versuchen. Ein früherer erneuter Versuch verbraucht nur erneut Kontingent für Anfragen, die
    abgelehnt werden.
  </Step>

  <Step title="Bei wiederholten Fehlern exponentiell zurückweichen">
    Wird ein erneuter Versuch wieder abgelehnt, verlängern Sie Ihre Wartezeit (Backoff) und fügen Sie zufälligen Jitter hinzu,
    damit parallele Worker nicht im Gleichschritt erneut senden. Kürzen Sie niemals den `Retry-After` des Servers, um ihn an eine lokale
    Obergrenze anzupassen. Wenn der Server Sie auffordert, länger zu warten, als Ihr Kontingent für erneute Versuche erlaubt,
    brechen Sie ab und planen Sie die Aufgabe für einen späteren Zeitpunkt ein.
  </Step>

  <Step title="Anfragerate glätten">
    Bevorzugen Sie eine gleichmäßige Anfragerate gegenüber Lastspitzen. Verwenden Sie bei Massenabfragen die maximale
    Seitengröße (`limit=500`), um die Sammlung mit weniger Anfragen abzudecken – siehe
    [Paginierung](/de/developers/v1/pagination). Wenn mehrere Listenabfragen parallel
    laufen (zum Beispiel Power-BI-Tabellen), halten Sie die Parallelität moderat und beachten Sie
    `Retry-After`, damit eine vorübergehende 429-Antwort nicht die gesamte Aktualisierung scheitern lässt.
  </Step>
</Steps>

Dieses Beispiel wiederholt nur `429`-Antworten bei einer **GET**-Anfrage, mit höchstens
fünf Versuchen und höchstens 60 Sekunden Wartezeit zwischen den Versuchen. Bei anderen Fehlern bricht es
sofort ab. Netzwerk-Timeouts werden an den Aufrufer weitergegeben. Konfigurieren Sie
Timeouts und Kontingente für erneute Versuche passend zu Ihrer Arbeitslast. `requests` interpretiert das Lese-Timeout
als maximale Leerlaufzeit beim Empfang von Daten, nicht als Gesamtfrist.

Laden Sie `LIVING_SECURITY_API_KEY` aus Ihrem Secret Manager. Installieren Sie `requests`,
bevor Sie dieses Beispiel ausführen. Rufen Sie `get_with_retry("/organization")` auf, um es zu verwenden.

```python Python theme={null}
import os
import random
import time
import requests

# US: BASE = "https://api.us-east-1.livingsecurity.ai/v1"
BASE = "https://api.eu-west-1.livingsecurity.ai/v1"
AUTH = ("apikey", os.environ["LIVING_SECURITY_API_KEY"])

def get_with_retry(path, params=None, max_attempts=5):
    if not 1 <= max_attempts <= 5:
        raise ValueError("max_attempts must be between 1 and 5")
    for attempt in range(max_attempts):
        response = requests.get(
            f"{BASE}{path}", auth=AUTH, params=params,
            headers={"Living-Security-Version": "2026-07-01"},
            timeout=(5, 30), allow_redirects=False,
        )
        if response.status_code != 429:
            response.raise_for_status()
            if not 200 <= response.status_code < 300:
                raise RuntimeError("Unexpected redirect; check your regional API URL")
            return response

        # The API returns Retry-After as a whole number of seconds.
        raw_wait = response.headers.get("Retry-After", "")
        request_id = response.headers.get("Request-Id", "unknown")
        response.close()
        if attempt == max_attempts - 1:
            raise RuntimeError(f"Retry budget exhausted; request_id={request_id}")
        if not raw_wait.isascii() or not raw_wait.isdigit() or len(raw_wait) > 6:
            raise RuntimeError(f"Invalid Retry-After; request_id={request_id}")

        wait = max(int(raw_wait), min(2 ** attempt, 30))
        delay = wait + random.uniform(0, 1)
        if delay > 60:
            raise RuntimeError(f"Retry-After exceeds wait budget; request_id={request_id}")
        time.sleep(delay)
```

Kopieren Sie diese Schleife nicht um einen Schreibvorgang herum. Ein Timeout nach einem Schreibvorgang kann
bedeuten, dass der Server ihn festgeschrieben hat, bevor die Verbindung fehlschlug. Wiederholen Sie einen Schreibvorgang nur dann,
wenn die Referenz dieses Vorgangs ausdrücklich Idempotenz dokumentiert, und verwenden Sie denselben
Schlüssel und dieselbe Nutzlast. Gleichen Sie andernfalls den Zustand der Ressource ab, bevor Sie es erneut versuchen.

## Empfohlener Aktualisierungsplan

Dimensionieren Sie die Aktualisierungshäufigkeit anhand Ihres Schlüsselkontingents und der Seitengröße. Ein vollständiger historischer
Ladevorgang einer großen Sammlung ist ein einmaliger Aufwand; bevorzugen Sie für regelmäßige Aktualisierungen im laufenden Betrieb inkrementelle Zeitfenster, damit jeder Lauf deutlich unter dem Kontingent bleibt. Legen Sie
`limit=500` immer explizit fest – der Standardwert von 25 vervielfacht die Anzahl der Anfragen.


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