
# Aktualisiere eine API

`PATCH /v1/apis/{api_id}` · Berechtigung `apis:write`

Aktualisiert eine API mit einem JSON-Merge-Patch (RFC 7396, `application/merge-patch+json`): Felder, die du sendest, ändern sich, Felder, die du auslässt, bleiben. `If-Match` ist erforderlich. `key` und `identifier` können nach der Erstellung nicht geändert werden, und die System-API kann nicht geändert werden. Ein Patch, der nichts ändert, schreibt nichts und behält die Version.

## Anfrage

| Parameter | In | Beschreibung |
|---|---|---|
| `api_id` | path | Die API-ID. |
| `If-Match` | header | Das `ETag` aus dem letzten Lesen (erforderlich). |

Body: Beliebige der unten aufgeführten beschreibbaren Felder (alle optional). Ein Feld kann nicht mit `null` entfernt werden.

| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| `key` | string | nein | Stabiler Konfigurationsschlüssel, `^[a-z0-9_-]{1,64}$`. Unveränderbar. |
| `identifier` | string | nein | Token-Zielgruppe: eine https-URL (keine Abfrage oder Fragment) oder `urn:<nid>:<nss>`; in kanonischer Form gespeichert. Unveränderbar. Der Namespace `urn:idp:` ist reserviert. |
| `name` | string | nein | 1–128 Zeichen. |
| `access_token_lifetime_s` | integer | nein | 60–86400. Standard 3600 (600 mit `mcp_profile`). |
| `token_format` | string | nein | `jwt` (Standard) oder `opaque`. |
| `rbac_mode` | string | nein | Wie Rollen und Berechtigungen das Token erreichen: `claims` (Standard) fügt `permissions` und `org_permissions` hinzu; `off` fügt keines von beiden hinzu (`org_roles` wird weiterhin hinzugefügt); `enforce` fügt sie hinzu und begrenzt außerdem die gewährten Scopes auf die effektiven Berechtigungen des Benutzers. |
| `allow_offline_access` | boolean | nein | Standard `true`. |
| `require_resource_indicator` | boolean | nein | Standard `false` (`true` mit `mcp_profile`). |
| `dpop_required` | boolean | nein | Standard `false`. |
| `mcp_profile` | boolean | nein | Erfordert eine https `identifier` und `require_resource_indicator: true`. |
| `first_party_access` | string | nein | `all` (Standard) oder `granted_only`. |
| `introspection_applications` | array | nein | Anwendungen (`app_…`), die die Token dieser API introspektieren dürfen, höchstens 50, keine Duplikate. Nur `web` und `m2m` Anwendungen der gleichen Umgebung. Die Liste wird als Ganzes ersetzt; `[]` leert sie, `null` wird abgelehnt. |

### Introspektionsanwendungen

Der Introspektions-Endpunkt (`POST <issuer>/oauth2/introspect`, RFC 7662) antwortet mit `active: true` für ein Zugriffstoken nur an zwei Aufrufer: die Anwendung, der das Token ausgestellt wurde, oder eine Anwendung in der `introspection_applications`-Liste der im Token-`aud` benannten API. Alle anderen Aufrufer erhalten `active: false`, daher können APIs die Token der anderen nicht lesen. Nur vertrauliche Anwendungen (`web`, `m2m`) der gleichen Umgebung können gelistet werden; die Liste wird als Menge gespeichert und in ID-Reihenfolge zurückgegeben. Eine suspendierte Anwendung bleibt auf der Liste, kann aber nicht introspektieren. Die Liste der System-API kann nicht geschrieben werden.

## Antwort

`200 OK` mit dem neuen `ETag`:

```json
{
  "id": "api_01h455vb4pex5vsknk084sn02q",
  "key": "orders",
  "identifier": "https://api.example.com/orders",
  "name": "Orders API",
  "is_system": false,
  "access_token_lifetime_s": 3600,
  "token_format": "jwt",
  "rbac_mode": "off",
  "allow_offline_access": true,
  "require_resource_indicator": false,
  "dpop_required": false,
  "mcp_profile": false,
  "first_party_access": "all",
  "introspection_applications": ["app_01h455vb4pex5vsknk084sn02r"],
  "created_at": "2026-10-05T12:00:00Z",
  "updated_at": "2026-10-05T12:00:00Z"
}
```

## Fehler

| HTTP | Code | Wann |
|---|---|---|
| 400 | `unknown_field` | Der Patch enthält ein schreibgeschütztes oder unbekanntes Feld. |
| 404 | `not_found` | Keine solche API in dieser Umgebung. |
| 409 | `conflict` | Die API ist die System-API. |
| 412 | `precondition_failed` | `If-Match` stimmt nicht mit der aktuellen Version überein. |
| 415 | `unsupported_media_type` | Der Content-Type ist nicht `application/merge-patch+json`. |
| 422 | `validation_failed` | Ein Wert ist ungültig, ein Feld wurde auf `null` gesetzt, oder `key` / `identifier` wurde geändert. |
| 422 | `validation_failed` | Ein `introspection_applications`-Element existiert nicht in dieser Umgebung (`unknown_application`), ist nicht vertraulich (`not_confidential`), ist ein Duplikat (`duplicate`) oder ist keine `app_…`-ID (`invalid_value`); der Zeiger benennt den Index in der Anfrage. |
| 428 | `precondition_required` | Der `If-Match`-Header fehlt. |

## Beispiel

```bash
curl -X PATCH https://api.eu.keenauth.com/v1/apis/api_01h455vb4pex5vsknk084sn02q \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/merge-patch+json" \
  -H 'If-Match: "1"' \
  -d '{"access_token_lifetime_s":900}'
```
