# Fehlerbehandlung

Plattformweite HTTP-Fehler bei SkyLink — Auth- vs. API-Formate, Validierung, Wiederholungsversuche und Kontingent-Header.



Wenn eine Anfrage fehlschlägt, ist der Antwort-Body JSON — **sein Aufbau hängt jedoch davon ab, welche Schicht den Aufruf abgelehnt hat**. Ihr Client sollte zuerst nach dem HTTP-Status verzweigen und den Body anschließend nach den folgenden Regeln auswerten. Diese Seite ist die maßgebliche Referenz für die plattformweite Fehlerbehandlung über alle API-Versionen (`/v2`, `/v3`, `/v3.1`) und alle Endpoints hinweg.

Authentifizierungsfehler unterscheiden sich zwischen den beiden Kanälen — <ApiProviderToggle />

| Schicht                      | Feld auf oberster Ebene        | Typische Statuscodes              |
| ---------------------------- | ------------------------------ | --------------------------------- |
| **Auth-/Kontingent-Schicht** | `message` oder `code` (String) | `401`, `403`, `429`               |
| **SkyLink API**              | `detail` (String oder Array)   | `404`, `422`, `500`, `502`, `504` |

Lesen Sie immer `Content-Type: application/json`. Gehen Sie nicht davon aus, dass jeder Statuscode dasselbe Fehlerformat hat.

Die Referenzseiten der Endpoints dokumentieren **nur** Fehler, deren Bedeutung oder `detail`-Text für die jeweilige Ressource spezifisch ist (zum Beispiel fehlende [METAR](https://en.wikipedia.org/wiki/METAR)-Station vs. nicht herausgegebene [TAF](https://en.wikipedia.org/wiki/Terminal_aerodrome_forecast)). Für Authentifizierung, Validierung, Rate Limits und Serverfehler verweisen sie auf diese Seite.

***

## Authentifizierungs- und Kontingentfehler [#auth-and-quota-errors]

Diese Fehler treten auf, bevor die Datenschicht erreicht wird oder anstatt sie zu erreichen. Der Body verwendet &#x2A;*`message`*&#x2A; oder &#x2A;*`code`**, nicht `detail`.

<ForProvider only="direct">
  **401 — fehlender oder ungültiger API-Schlüssel**

  ```json
  {
    "code": "missing_api_key",
    "message": "Provide your key in the x-api-key header."
  }
  ```

  Der Schlüssel wird ausschließlich aus dem Header `x-api-key` gelesen — die Übergabe als Query-Parameter wird nicht akzeptiert und liefert ebenfalls `401`.

  **403 — Endpoint nicht in Ihrem Tarif enthalten**

  ```json
  {
    "code": "plan_forbidden",
    "message": "This endpoint is not included in your plan."
  }
  ```

  **429 — Missbrauchsgrenze erreicht**

  ```json
  {
    "message": "Too many requests"
  }
  ```

  Siehe [Rate Limits](/docs/rate-limits#quota-headers) — bei der direkten API ist dies die tägliche Obergrenze zum Schutz vor Missbrauch, nicht Ihr monatliches Kontingent.
</ForProvider>

<ForProvider only="rapidapi">
  **401 — ungültiger oder fehlender API-Schlüssel**

  ```json
  {
    "message": "Invalid API key. Go to https://docs.rapidapi.com/docs/keys for more info."
  }
  ```

  **403 — kein Abonnement**

  ```json
  {
    "message": "You are not subscribed to this API."
  }
  ```

  **429 — Rate Limit**

  ```json
  {
    "message": "Too many requests"
  }
  ```
</ForProvider>

<DocDetails title="JSON Schema — Gateway-Fehler (401, 403, 429)">
  ```json
  {
    "type": "object",
    "required": ["message"],
    "properties": {
      "message": { "type": "string" }
    },
    "additionalProperties": true
  }
  ```
</DocDetails>

Korrigieren Sie den Schlüssel oder das Abonnement — **wiederholen Sie** `401` oder `403` **nicht**. Bei `429` warten Sie ab und wiederholen die Anfrage; siehe [Regeln für Wiederholungsversuche](#retry-rules) und [Rate Limits](/docs/rate-limits) zu den Kontingent-Headern.

Die Einrichtung der Header ist unter [Erste Schritte](/docs/getting-started) beschrieben.

***

## Validierungsfehler (422) [#validation-errors-422]

Erreicht die Anfrage SkyLink, besteht aber die Eingabevalidierung nicht, ist `detail` ein **Array** von Objekten:

```json
{
  "detail": [
    {
      "type": "string_too_short",
      "loc": ["path", "icao"],
      "msg": "String should have at least 4 characters",
      "input": "KF",
      "ctx": { "min_length": 4 }
    }
  ]
}
```

| Feld             | Beschreibung                                                                    |
| ---------------- | ------------------------------------------------------------------------------- |
| `detail[].type`  | Validator-ID, z. B. `string_too_short`                                          |
| `detail[].loc`   | Pfad zum fehlerhaften Feld, z. B. `["path", "icao"]` oder `["query", "parsed"]` |
| `detail[].msg`   | Menschenlesbare Erläuterung                                                     |
| `detail[].input` | Abgelehnter Wert                                                                |
| `detail[].ctx`   | Optionale Einschränkungen                                                       |

<DocDetails title="JSON Schema — 422 (detail-Array)">
  ```json
  {
    "type": "object",
    "required": ["detail"],
    "properties": {
      "detail": {
        "type": "array",
        "items": {
          "type": "object",
          "required": ["type", "loc", "msg", "input"],
          "properties": {
            "type": { "type": "string" },
            "loc": { "type": "array", "items": { "type": "string" } },
            "msg": { "type": "string" },
            "input": { "type": "string" },
            "ctx": { "type": "object" }
          },
          "additionalProperties": true
        }
      }
    },
    "additionalProperties": false
  }
  ```
</DocDetails>

**Nicht wiederholen** — korrigieren Sie die Anfrageparameter und senden Sie die Anfrage erneut.

***

## Server- und Upstream-Fehler (5xx) [#server-and-upstream-errors-5xx]

Wenn SkyLink oder ein vorgelagerter Datendienst ausfällt:

```json
{
  "detail": "Internal Server Error"
}
```

<DocDetails title="JSON Schema — 5xx (detail-String)">
  Gleicher Aufbau wie fachliche `detail`-Strings (auch `404` verwendet diese Form):

  ```json
  {
    "type": "object",
    "required": ["detail"],
    "properties": {
      "detail": { "type": "string" }
    },
    "additionalProperties": false
  }
  ```
</DocDetails>

| Status | Bedeutung                                    |
| ------ | -------------------------------------------- |
| `500`  | Interner Serverfehler                        |
| `502`  | Vorgelagerter Datendienst nicht verfügbar    |
| `504`  | Zeitüberschreitung beim vorgelagerten Dienst |

**Wiederholen** Sie die Anfrage mit exponentiellem Backoff (max. 3 Versuche). Siehe [Regeln für Wiederholungsversuche](#retry-rules).

***

## Nicht gefunden (404) [#not-found-404]

`404`-Antworten verwenden die String-Form von `detail` bei SkyLink, aber **Meldung und Bedeutung sind endpointspezifisch** — ein [METAR](https://en.wikipedia.org/wiki/METAR) ohne Station, eine [TAF](https://en.wikipedia.org/wiki/Terminal_aerodrome_forecast) ohne Vorhersage, ein unbekannter Flughafen-ICAO-Code und ein fehlender historischer Flug haben jeweils eine andere Semantik. Dokumentieren Sie `404` auf jeder **Referenzseite** (oder im Integrationsleitfaden des Abschnitts, wenn sich das Muster über mehrere Endpoints erstreckt). Duplizieren Sie hier nicht jede Variante; verlinken Sie aus Ihrem Handler auf die Seite, die zum aufgerufenen Endpoint passt.

| Abschnitt                | Wo `404` dokumentiert ist                                                                                                                                                                                                    |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Wetter — METAR / TAF     | [METAR](/docs/v31/weather-metar#error-responses) · [TAF](/docs/v31/weather-taf#error-responses) · [Wenn Wetterdaten fehlen](/docs/v31/weather-integration-errors#when-weather-data-is-missing)                               |
| Wetter — auf der Strecke | [Höhenwinde](/docs/v31/winds-aloft#error-responses) · [PIREPs](/docs/v31/pireps#error-responses) · [AIRMET/SIGMET](/docs/v31/airsigmet#error-responses)                                                                      |
| Flughafendaten           | [Flughäfen](/docs/v31/airports#error-responses) · [Flughafensuche](/docs/v31/airport-search#error-responses)                                                                                                                 |
| Referenzdaten            | [Länder](/docs/v31/countries#error-responses) · [Regionen](/docs/v31/regions#error-responses)                                                                                                                                |
| Live-ADS-B               | [ADS-B-Tracking](/docs/v31/adsb#error-responses)                                                                                                                                                                             |
| Historisches ADS-B       | [Übersicht historisches ADS-B](/docs/v31/historical-adsb#error-responses) · [Flugdetails](/docs/v31/historical-adsb-flight-detail#error-responses) · [Positionsverlauf](/docs/v31/historical-adsb-positions#error-responses) |
| Karten                   | [Flugplatzkarten](/docs/v31/charts#error-responses)                                                                                                                                                                          |
| Flugbetrieb              | [Flugstatus](/docs/v31/flight-status#error-responses)                                                                                                                                                                        |
| Webhooks                 | [Abonnements](/docs/v31/webhooks-subscriptions#error-responses)                                                                                                                                                              |

**Wichtig:** Einige Endpoints liefern statt `404` ein leeres Ergebnis mit HTTP `200` (zum Beispiel die [Luftfahrzeugsuche](/docs/v31/aircraft-lookup), wenn kein Kennzeichen passt). Prüfen Sie die Referenzseite, bevor Sie alle „nicht gefunden“-Fälle auf `404` abbilden.

Tarifbedingte `401`/`403`-Fehler beim historischen [ADS-B](https://www.faa.gov/air_traffic/technology/adsb) (Abonnement zu niedrig für das Pfadpräfix) sind auf der [Übersichtsseite zu historischem ADS-B](/docs/v31/historical-adsb#error-responses) dokumentiert, nicht hier.

***

## Regeln für Wiederholungsversuche [#retry-rules]

| Status              | Wiederholen? | Maßnahme                                                                            |
| ------------------- | ------------ | ----------------------------------------------------------------------------------- |
| `401`, `403`        | Nein         | [API-Schlüssel / Abonnement](/docs/getting-started#key-security) korrigieren        |
| `404`               | Nein         | Endpointspezifischer Fallback — siehe Referenzseite                                 |
| `422`               | Nein         | Eingabe korrigieren                                                                 |
| `429`               | Ja           | Exponentielles Backoff; [Kontingent-Header](/docs/rate-limits#quota-headers) prüfen |
| `500`, `502`, `504` | Ja           | Exponentielles Backoff (max. 3 Versuche)                                            |

```python
import time
import requests

RETRYABLE = {429, 500, 502, 504}


def fetch_with_retry(url: str, headers: dict, params: dict | None = None, max_retries: int = 3) -> requests.Response:
    delay = 1.0
    for attempt in range(max_retries + 1):
        r = requests.get(url, headers=headers, params=params, timeout=(10, 15))
        if r.status_code not in RETRYABLE or attempt == max_retries:
            return r
        time.sleep(delay)
        delay *= 2
    return r
```

Zu Tarifkontingenten, Preisen für Mehrverbrauch und den Pfadstufen beim historischen [ADS-B](https://www.faa.gov/air_traffic/technology/adsb) siehe [Rate Limits](/docs/rate-limits).
