
# Bericht über inaktive Mitglieder

`GET /v1/reports/inactive-members` · Berechtigung `reports:read`

Listet die aktiven Mitglieder einer Organisation auf, die seit `days` Tagen keine erfolgreiche Anmeldung in dieser Organisation hatten. Verwenden Sie den Bericht, um Konten zu finden, die entfernt werden sollen, wenn eine Verbindung keine SCIM-Bereitstellung hat: Prüfen Sie die Liste und sperren Sie danach die ausgewählten Mitgliedschaften mit `POST /v1/organizations/{org_id}/memberships/{membership_id}:suspend`.

Die Umgebung stammt immer aus dem API-Schlüssel; es gibt keinen Umgebungsparameter. Die Zeilen enthalten nur Kennungen und Zeitstempel, weder Namen, E-Mail-Adresse, IP-Adresse noch `User-Agent`. Da Benutzerkennungen personenbezogene Daten sind, ist der Bericht auf Schlüssel mit `reports:read` beschränkt.

## Was als Anmeldung zählt

Eine erfolgreiche Authentifizierung zählt, wenn sie im Kontext dieser Organisation abgeschlossen wurde. Eine Anmeldung ohne ausgewählte Organisation zählt nicht. Eine Mitgliedschaft, deren Aktivierung (`activated_at` oder, falls sie nie aktiviert wurde, ihr Erstellungszeitpunkt) neuer als der Schwellenwert ist, wird nicht aufgeführt; ein Mitglied, das gestern beigetreten ist, erscheint daher in einem 30-Tage-Bericht nie.

## Anfrage

| Parameter | In | Erforderlich | Beschreibung |
|---|---|---|---|
| `organization_id` | query | ja | Die Organisation (`org_…`). |
| `days` | query | nein | Schwellenwert für Inaktivität in Tagen, 7 bis 365. Standard 30. |
| `limit` | query | nein | Seitengröße, 1 bis 100. Standard 50. |
| `cursor` | query | nein | `next_cursor` der vorherigen Seite. Nur gültig für die Umgebung, `organization_id` und `days`, für die er ausgestellt wurde. |

Die Zeilen folgen der Reihenfolge, in der die Mitgliedschaften zuletzt aktualisiert wurden. Der Schwellenwert (`inactive_since`) wird einmal auf der ersten Seite berechnet und im Cursor übernommen, sodass jede Seite eines Berichts denselben Zeitpunkt verwendet.

Eine Seite durchsucht höchstens 500 Mitgliedschaften und kann weniger Zeilen als `limit` zurückgeben, auch keine. Folgen Sie `next_cursor` so lange, bis er `null` ist.

## Antwort

Erfolgreiche Antwort: `200 OK`.

| Feld | Beschreibung |
|---|---|
| `organization_id` | Die Organisation des Berichts. |
| `days` | Der verwendete Schwellenwert. |
| `inactive_since` | Der Schwellenzeitpunkt (Anfragezeit minus `days`, RFC 3339, UTC). Mitglieder ohne Anmeldung seitdem werden aufgeführt. |
| `data_since` | Zeitpunkt der ersten erfolgreichen Authentifizierung, die für die Umgebung erfasst wurde; Anmeldungen davor sind unbekannt. `null`, wenn die Umgebung noch keinen Eintrag hat. |
| `complete` | `true`, wenn `data_since` nicht nach `inactive_since` liegt, sodass die Liste das gesamte Schwellenfenster abdeckt. |
| `data` | Die Zeilen dieser Seite (siehe unten). |
| `next_cursor` | Cursor für die nächste Seite, `null` auf der letzten Seite. |

Jede Zeile in `data`:

| Feld | Beschreibung |
|---|---|
| `membership_id` | Kennung: `mem_…`. |
| `user_id` | Kennung: `usr_…`. |
| `activated_at` | Zeitpunkt, zu dem die Mitgliedschaft aktiv wurde (ihr Erstellungszeitpunkt, falls sie nie aktiviert wurde). |
| `last_authenticated_at` | Letzte erfolgreiche Authentifizierung in dieser Organisation oder `null`, wenn seit `data_since` keine erfasst wurde. |

Wenn `complete` `false` ist, kann ein aufgeführtes Mitglied vor `data_since` angemeldet gewesen sein; betrachten Sie die Liste daher nicht als endgültig. Wenn `data_since` `null` ist, wurde für die Umgebung noch keine Anmeldung erfasst, und jedes ausreichend alte Mitglied ist aufgeführt.

```json
{
  "organization_id": "org_01j9xk3m7q8r2s4t6v8w0y2z4d",
  "days": 30,
  "inactive_since": "2027-02-03T09:30:00Z",
  "data_since": "2026-12-01T08:00:00Z",
  "complete": true,
  "data": [
    {
      "membership_id": "mem_01j9xk3m7q8r2s4t6v8w0y2z4e",
      "user_id": "usr_01j9xk3m7q8r2s4t6v8w0y2z4f",
      "activated_at": "2026-12-10T10:00:00Z",
      "last_authenticated_at": "2027-01-05T17:45:00Z"
    }
  ],
  "next_cursor": null
}
```

## Fehler

Jeder Fehler liefert einen `application/problem+json`-Antwortkörper mit einem stabilen `code`.

| HTTP | `code` | Wann |
|---|---|---|
| 400 | `invalid_cursor` | Der Cursor ist fehlerhaft oder wurde für eine andere Umgebung, Organisation oder `days` ausgestellt. |
| 404 | `not_found` | Die Organisation existiert nicht oder gehört zu einer anderen Umgebung. |
| 422 | `validation_failed` | `organization_id` fehlt oder ist fehlerhaft, `days` oder `limit` liegt außerhalb des gültigen Bereichs, oder ein Parameter wurde wiederholt. |
| 401 | `unauthenticated` | Der API-Schlüssel fehlt, ist ungültig oder wurde widerrufen. |
| 403 | `insufficient_permissions` | Dem Schlüssel fehlt `reports:read`. |
| 429 | `rate_limited` | Das Ratenlimit wurde überschritten; beachten Sie `Retry-After`. |
| 503 | `service_unavailable` | Der Berichtsdienst ist vorübergehend nicht verfügbar; versuchen Sie es später erneut. |

## Beispiel

```bash
curl "https://api.eu.keenauth.com/v1/reports/inactive-members?organization_id=org_01j9xk3m7q8r2s4t6v8w0y2z4d&days=60" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY"
```

```bash
keenauth reports inactive-members org_01j9xk3m7q8r2s4t6v8w0y2z4d --days 60
```

## Personenbezogene Daten

Dieser Endpunkt verarbeitet personenbezogene Daten: Organisationsmitgliedschaften und Einladungen (Benutzer- und Mitgliedschaftskennungen mit Anmeldezeiten). [Personenbezogene Daten in den KeenAuth-APIs](/docs/policies/personal-data) beschreibt, was gespeichert wird, wie lange es aufbewahrt wird und wie es gelöscht wird. Übermitteln Sie keine besonderen Kategorien personenbezogener Daten (Gesundheit, biometrische Daten, Religion, politische Meinungen, sexuelle Orientierung) in irgendeinem Feld.
