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

# BKV-API: Konventionen

> Paginierung, Fehlerbehandlung, Zeitstempel, Lieferzeiträume und Ratenbegrenzung

<h3 id="pagination">
  Paginierung
</h3>

Alle Listen-Endpunkte unterstützen Cursor-basierte Paginierung mit zwei Parametern:

| Parameter | Typ     | Beschreibung                                                                           |
| --------- | ------- | -------------------------------------------------------------------------------------- |
| `limit`   | integer | Max. Einträge pro Seite (Standard: 10, Max: 100)                                       |
| `after`   | string  | Cursor für die nächste Seite — den `next_cursor`-Wert der vorherigen Antwort übergeben |

Paginierte Antworten enthalten ein `pagination`-Objekt mit einem `next_cursor`-Feld:

```json theme={null}
{
  "contracts": [ ... ],
  "pagination": {
    "limit": 10,
    "has_more": true,
    "next_cursor": "con_a1b2c3d4"
  }
}
```

Wenn `has_more` den Wert `true` hat, übergeben Sie den `next_cursor`-Wert als `after`-Parameter, um die nächste Seite abzurufen. Wenn keine weiteren Seiten vorhanden sind, ist `next_cursor` `null`.

**Beispielablauf:**

1. `GET /v1/transactions?limit=10` — gibt Einträge 1–10 zurück, `"next_cursor": "txn_abc123"`
2. `GET /v1/transactions?limit=10&after=txn_abc123` — gibt Einträge 11–20 zurück, `"next_cursor": "txn_xyz789"`
3. `GET /v1/transactions?limit=10&after=txn_xyz789` — gibt Einträge 21–25 zurück, `"has_more": false`, `"next_cursor": null`

Der Sammlungsschlüssel in der Antwort entspricht dem Ressourcennamen (z.B. `"contracts"`, `"transactions"`, `"nominations"`, `"customers"`).

<h3 id="timestamps">
  Zeitstempel
</h3>

Alle Zeitstempel sind ISO 8601 in UTC:

```
2025-07-15T14:30:00Z
```

<h3 id="delivery-periods">
  Lieferzeiträume
</h3>

Die Energielieferung verwendet die standardmäßige **PTU (Programme Time Unit)**-Konvention mit 15-Minuten-Intervallen:

```json theme={null}
{
  "delivery_date": "2025-07-15",
  "period_from": "2025-07-15T14:00:00Z",
  "period_to": "2025-07-15T14:15:00Z"
}
```

Jeder Liefertag hat in der Regel 96 Viertelstunden-Slots (nummeriert 1–96). An Tagen mit Zeitumstellung können es 92 oder 100 Slots sein. Slot-basierte Filterung ist bei Transaktions- und Nominierungs-Endpunkten über die Parameter `slot_number_from` und `slot_number_to` verfügbar.

<h3 id="error-responses">
  Fehlerantworten
</h3>

Alle Fehler folgen [RFC 9457 — Problem Details for HTTP APIs](https://www.rfc-editor.org/rfc/rfc9457) und werden mit `Content-Type: application/problem+json` zurückgegeben:

```json theme={null}
{
  "type": "https://brp.otark.team/errors/balance_group_tso_not_enabled",
  "title": "Balance Group TSO Not Enabled",
  "status": 400,
  "detail": "The requested TSO is not enabled for this balance group.",
  "instance": "/v1/customers/cust_r8s9t0u1"
}
```

Validierungsfehler enthalten ein `errors`-Array mit feldspezifischen Details:

```json theme={null}
{
  "type": "https://brp.otark.team/errors/validation",
  "title": "Validation Failed",
  "status": 400,
  "instance": "/v1/customers/cust_r8s9t0u1",
  "errors": [
    {
      "field": "balance_group.tso",
      "code": "invalid_enum_value",
      "message": "Invalid enum value. Expected 'DE_AMPRION' | 'DE_TENNET' | 'DE_TRANSNET_BW' | 'DE_50HERTZ'"
    }
  ]
}
```

Feldspezifische Fehlercodes: `unknown_field`, `read_only_field`, `required`, `invalid_type`, `invalid_enum_value`, `invalid_format`, `invalid_literal`, `value_too_small`, `value_too_large`, `validation_failed`.

Es werden Standard-HTTP-Statuscodes verwendet:

| Code  | Beschreibung                                                                   |
| ----- | ------------------------------------------------------------------------------ |
| `400` | Ungültige Anfrage — Validierungsfehler oder Verstoß gegen Geschäftsregeln      |
| `401` | Nicht autorisiert — fehlender oder ungültiger API-Schlüssel                    |
| `403` | Zugriff verweigert — API-Schlüssel hat nicht die erforderlichen Berechtigungen |
| `404` | Nicht gefunden — Ressource existiert nicht oder kein Zugriff                   |
| `409` | Konflikt — Operation kann im aktuellen Zustand nicht ausgeführt werden         |
| `429` | Zu viele Anfragen — Ratenlimit überschritten                                   |
| `500` | Interner Serverfehler                                                          |

<h3 id="rate-limiting">
  Ratenbegrenzung
</h3>

API-Anfragen sind auf **300 Anfragen pro 60-Sekunden-Fenster** begrenzt. Jede Antwort enthält folgende Header:

| Header                  | Beispiel | Beschreibung                                |
| ----------------------- | -------- | ------------------------------------------- |
| `x-ratelimit-limit`     | `300`    | Maximale Anfragen pro Fenster               |
| `x-ratelimit-remaining` | `299`    | Verbleibende Anfragen im aktuellen Fenster  |
| `x-ratelimit-reset`     | `60`     | Sekunden bis das Fenster zurückgesetzt wird |

Bei Überschreitung des Limits gibt die API `429 Too Many Requests` zurück.
