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

# Audit-Log

> Organisations-Audit-Log über die Management API abfragen

# Audit-Log

Lesen Sie denselben Audit-Trail wie **Einstellungen → Audit-Log** im Admin Tool. Jeder Eintrag ist eine aufgezeichnete Aktion der Organisation, der der API-Schlüssel gehört: ein API-Aufruf, eine Konfigurationsänderung, eine Webhook-Zustellung, ein DSGVO-Export oder ein Bestellimport, sobald das Audit-Logging für Bestellimporte aktiviert ist.

<Note>
  Dieser Endpoint folgt demselben Schalter wie die Aufzeichnung von Management- und Public-API-Anfragen. Solange der Schalter aus ist, antwortet ein authentifizierter Aufruf mit **404** und das Log wird nicht gelesen. Verlassen Sie sich in Produktion nicht auf diesen Endpoint, bevor das Audit-Logging für die Management API Ihrer Organisation eingeschaltet ist.
</Note>

**Berechtigung:** `audit_log:read` (Audit log read). Ein Schlüssel ohne diese Berechtigung erhält 403. Ein fehlender oder ungültiger Schlüssel erhält 401.

## Audit-Log-Einträge auflisten

```bash theme={null}
GET /v1/management/audit-logs
```

```bash theme={null}
curl -G "https://api.rxscale.com/v1/management/audit-logs" \
  -H "X-API-Key: your-api-key-here" \
  --data-urlencode "outcome=success_with_warnings" \
  --data-urlencode "created_from=1757836800" \
  --data-urlencode "created_to=1757923200" \
  --data-urlencode "limit=50" \
  --data-urlencode "page=0"
```

Die Organisation kommt aus dem API-Schlüssel. Es gibt keinen Organisationsparameter. Ein Aufrufer kann das Log einer anderen Organisation nicht lesen.

### Abfrageparameter

Alle Filter sind optional und werden mit UND verknüpft. Ein unbekannter Parameter, einschließlich `organisation_uid`, ergibt 400.

<ParamField query="log_type" type="string">
  Ein Log-Typ: `api_call`, `config_change`, `webhook_delivery`, `gdpr_export` oder `order_import`. Jeder andere Wert ergibt 400.
</ParamField>

<ParamField query="event_type" type="string">
  Ein Ereignistyp, zum Beispiel `api_read`, `api_phi_read`, `api_write` oder `api_auth_failed`. Unbekannte Werte ergeben 400.
</ParamField>

<ParamField query="source" type="string">
  Wo der Eintrag aufgezeichnet wurde, zum Beispiel `management_api_v1`, `public_api_v2` oder `admin_api_v1`.
</ParamField>

<ParamField query="success" type="boolean">
  `true` oder `false`. Entspricht dem gespeicherten Erfolgsflag. Bei einem Bestellimport werden sowohl `success` als auch `success_with_warnings` als `success=true` gespeichert.
</ParamField>

<ParamField query="outcome" type="string">
  `success`, `success_with_warnings` oder `rejected`.

  `success=true` schließt Warnungen ein. `outcome=success` nicht: es passt auf einen erfolgreichen Eintrag, der nicht `success_with_warnings` ist. `outcome=rejected` passt auf einen fehlgeschlagenen Eintrag oder einen Eintrag, dessen Payload-Ergebnis `rejected` ist.

  `success` und `outcome` zusammen ergeben 400, wenn sie sich widersprechen (`success=true` mit `rejected`, oder `success=false` mit `success` oder `success_with_warnings`).

  Warnungen und Ablehnungen aus dem Bestellimport erscheinen erst, wenn das Audit-Logging für Bestellimporte aktiviert ist.
</ParamField>

<ParamField query="created_from" type="integer">
  Inklusiver Beginn als Unix-Sekunden. `created_at` ist größer oder gleich diesem Wert.
</ParamField>

<ParamField query="created_to" type="integer">
  Exklusives Ende als Unix-Sekunden. `created_at` ist kleiner als dieser Wert. Liegt `created_from` nach `created_to`, ist die Antwort 400. Gleiche Werte treffen nichts.
</ParamField>

<ParamField query="entity_uid" type="string">
  Exakte Übereinstimmung, höchstens 255 Zeichen. Bei einem übernommenen Bestellimport ist das die interne Bestell-ID. Ein abgelehnter Import hat keine Entity-ID und passt nicht auf diesen Filter.
</ParamField>

<ParamField query="actor_user_uid" type="string">
  Exakte Übereinstimmung des Benutzers, der eine Konfigurationsänderung, einen DSGVO-Export oder eine Änderung am Telemedizin-Anbieter vorgenommen hat. Höchstens 36 Zeichen. API-Aufrufe und Bestellimporte lassen dieses Feld leer und passen nicht.
</ParamField>

<ParamField query="api_key_identifier" type="string">
  Exakte Übereinstimmung der API-Schlüssel-Kennung. Das ist nicht das Geheimnis und ein eigener Filter neben `actor_user_uid`.
</ParamField>

<ParamField query="page" type="integer" default="0">
  Seitennummer, beginnend bei 0.
</ParamField>

<ParamField query="limit" type="integer" default="50">
  Seitengröße. Minimum 1, Maximum 200.
</ParamField>

Einträge kommen neueste zuerst. Teilen sich zwei Einträge einen Zeitstempel, kommt die höhere ID zuerst.

Es gibt kein Standard-Zeitfenster. Lassen Sie beide Zeitstempel weg, um die neuesten Einträge zu blättern, begrenzt durch die Obergrenze unten.

### Paginierung

Die Standardseitengröße ist 50, das Maximum 200. Es werden höchstens 10.000 passende Einträge gezählt. Passen mehr, ist `totalRegistries` `10000`, `totalCapped` ist `true`, und `totalPages` bezieht sich auf diese Obergrenze. Seiten hinter diesem Fenster sind leer. Grenzen Sie `created_from` und `created_to` oder die anderen Filter ein, um ältere Einträge zu erreichen.

### Ratenlimit

10 Anfragen pro Sekunde pro IP-Adresse, gemeinsam mit dem Rest der Management API. Eine 429 ist eine HTML-Seite mit dem Text `Too Many Requests`, kein JSON, und ohne `Retry-After`. Siehe [Ratenlimits](/de/rate-limits).

### Beispiel: Bestellimport mit Warnungen

```json theme={null}
{
  "data": [
    {
      "uid": "3f1c2a10-9b8e-4d7c-a6f5-111111111111",
      "organisation_uid": "org_acme",
      "created_at": 1757836800,
      "log_type": "order_import",
      "event_type": "order_import",
      "source": "shopify_webhook",
      "success": true,
      "outcome": "success_with_warnings",
      "actor_user_uid": null,
      "api_key_identifier": null,
      "http_method": null,
      "route": null,
      "request_path": null,
      "client_ip": null,
      "user_agent": null,
      "duration_ms": null,
      "execution_id": "pubsub-msg-1001",
      "target_url": null,
      "response_status_code": null,
      "response_body": null,
      "error_message": "SKU is not in the shop catalogue (sku: sku_uid)",
      "entity_uid": "ord_1001",
      "notification_subscription_uid": null,
      "payload_version": null,
      "attempt_number": null,
      "permanent_failure": null,
      "payload": {
        "outcome": "success_with_warnings",
        "shop_identifier": "example.myshopify.com",
        "external_order_id": "5234567890",
        "external_fulfillment_id": "6123456789",
        "shopify_topic": "orders/updated",
        "triggered_at": "2026-10-06T12:00:00+00:00",
        "codes": [
          {
            "code": "items_missing",
            "message": "SKU is not in the shop catalogue (sku: sku_uid)",
            "external_line_id": "998877",
            "sku_uid": "sku_uid"
          }
        ]
      }
    }
  ],
  "totalRegistries": 1,
  "totalPages": 1,
  "totalCapped": false
}
```

Einträge mit `order_import` gibt es erst, wenn das Audit-Logging für Bestellimporte aktiviert ist.

### Beispiel: abgelehnter API-Aufruf

```json theme={null}
{
  "uid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "organisation_uid": "org_acme",
  "created_at": 1757836900,
  "log_type": "api_call",
  "event_type": "api_auth_failed",
  "source": "management_api_v1",
  "success": false,
  "outcome": "rejected",
  "actor_user_uid": null,
  "api_key_identifier": "acme_live",
  "http_method": "GET",
  "route": "/v1/management/patients/<patient_uid>",
  "request_path": "/v1/management/patients/pat_1",
  "client_ip": "203.0.113.7",
  "user_agent": "partner-integration/2.1",
  "duration_ms": 12,
  "execution_id": "11111111-2222-3333-4444-555555555555",
  "target_url": null,
  "response_status_code": 403,
  "response_body": "{\"code\": \"permission_denied\", \"description\": \"API key lacks required permission: patient:read\"}",
  "error_message": "permission_denied: patient:read",
  "entity_uid": null,
  "notification_subscription_uid": null,
  "payload_version": null,
  "attempt_number": null,
  "permanent_failure": null,
  "payload": null
}
```

`outcome` ist `rejected`, weil `success` false ist, auch wenn `payload` null ist.

## Was enthalten ist

Jeder Eintrag hat dieselben Felder. Ein Feld ist null, wenn nichts gespeichert wurde.

Enthalten: Ereignistyp, Ergebnis, IP-Adresse, User-Agent, API-Schlüssel-Kennung (nie das Geheimnis), Routenvorlage, Anfragepfad mit bereits geschwärzten Zugangsdaten und nur den Namen der Query-Parameter, der Fehlertext bei Fehlschlag (höchstens 2.000 Zeichen), die Fehlermeldung, die zugehörige Entity-ID und die Ereignis-Payload, wie sie gespeichert wurde.

## Was nie enthalten ist

Anfragekörper, Werte von Query-Parametern, erfolgreiche Antwortkörper, API-Schlüssel-Geheimnisse, Name oder Adresse von Kunden und die alte `meta_data`-Sammlung.

Die Antwort lässt außerdem die internen Spalten `expires_at`, `deleted_at` und `updated_at` weg.

## Fehler

| Status | Wann | Body |
| - | - | - |
| 200 | Die Abfrage ist gültig. Eine leere Seite ist ebenfalls 200. | `data`, `totalRegistries`, `totalPages`, `totalCapped` |
| 400 | Ungültige Abfrage, unbekannter Parameter, unbekanntes Enum, `created_from` nach `created_to`, oder `success` widerspricht `outcome` | `{"error": {"<field>": ["<message>"]}}` |
| 401 | `X-API-Key` fehlt | `{"code": "api_key_missing", "description": "API key header is expected"}` |
| 401 | Unbekannter Schlüssel oder falsches Geheimnis | `{"code": "invalid_api_key", "description": "Invalid API key"}` |
| 403 | Dem Schlüssel fehlt `audit_log:read` | `{"code": "permission_denied", "description": "..."}`. Verzweigen Sie über `code`. |
| 404 | Audit-Logging ist ausgeschaltet | `{"code": "not_found", "description": "Not found"}` |
| 405 | Jede Methode außer `GET` | `{"error": "Method not allowed"}` |
| 429 | Mehr als 10 Anfragen pro Sekunde von der Client-IP | HTML `Too Many Requests`. Kein JSON. |

## Aufbewahrung

Dieser Endpoint ändert nicht, wie lange Einträge aufbewahrt werden. Erfolgreiche API-Lesezugriffe ohne Patientendaten werden 90 Tage aufbewahrt. Lesezugriffe auf Patientendaten, Schreibzugriffe, fehlgeschlagene Anfragen und dieser Audit-Log-Lesezugriff selbst werden 1 Jahr aufbewahrt. Siehe [Audit-Log](/de/for-telemedicine-providers/audit-log).


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