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

# API-Antwortformat und JSON-Antwortbeispiele

> Lesen Sie LogBrew-API-Antworten für Telemetrielisten, Cursor-Seiten, Live-Ereignisse, Änderungen sowie Erfolgs- und Fehlerzustände.

Diese Seite zeigt ein Beispiel für jede Antwortfamilie der
[Telemetrie-API](/de/reference/telemetry-api). Alle Werte sind synthetisch.
Fehlercodes und Wiederherstellung finden Sie unter
[API-Fehler](/de/reference/api-errors).

## Eine Antwort lesen

Lesen Sie jede Antwort in dieser Reihenfolge:

1. Lesen Sie den HTTP-Status.
2. Prüfen Sie, dass der Antwort-Body die Struktur der Route hat.
3. Prüfen Sie, dass jede `project_id` im angefragten Projektbereich liegt.
4. Lassen Sie kanonische Enum-Werte und Kennungen unverändert.
5. Folgen Sie `next_action` nur, wenn der Client dessen `code` und `target`
   unterstützt.
6. Behandeln Sie `null`, ein ausgelassenes Feld und eine leere Liste als
   unterschiedliche Zustände.

Ein `200 OK` kann eine leere Liste enthalten. Eine leere Log-Liste bedeutet,
dass kein Log zur Anfrage passte. Sie bedeutet nicht, dass auch Issues, Traces
oder Aktionen leer sind. Verbinden Sie Signale nicht, nur weil ihre Zeitstempel
nah beieinander liegen. Folgen Sie einem Trace nur, wenn die Antwort seine
genaue `trace_id` enthält.

Ein `404` und eine leere Liste sind verschiedene Ergebnisse. Eine Listenroute
gibt `[]` zurück, wenn kein Datensatz passt. Eine Detailroute gibt `404` mit
`code: not_found` zurück, wenn sie keinen lesbaren Datensatz findet. Keines
der beiden Ergebnisse beweist, dass die Signalaufnahme fehlgeschlagen ist.

## Was Sie senden sollten

Antworten sind nur so nützlich wie die Telemetrie, die Sie senden. Senden Sie
diese Werte mit jedem Umschlag oder in jeder SDK-Einrichtung:

* `release` und `environment`.
* Stabile Namen für Dienste, Aktionen und Metriken.
* Trace-Kontext, wenn Logs, Spans, Aktionen und Issues zur selben Anfrage
  gehören.
* Kanonische Schweregrade: `info`, `warning`, `error` und `critical`.
* Attribute, die beim Debuggen helfen, ohne Geheimnisse oder unnötige
  personenbezogene Daten.

Siehe [SDK-Integration](/de/guides/sdk-ingestion) und
[Erfasste Daten steuern](/de/guides/safe-capture).

## Antwort der Signalaufnahme

Öffentliche SDKs lesen die Antwort von `POST /v1/events` für Sie. Ihr
Anwendungscode muss sie nicht verarbeiten.

### Antwort auf einen SDK-Batch

Ein erfolgreicher SDK-Batch gibt `200 OK` mit der Zahl der angenommenen
Ereignisse pro Stream zurück:

```json theme={null}
{
  "issues": 1,
  "logs": 2,
  "trace_spans": 3,
  "actions": 1,
  "metrics": 1,
  "already_accepted": 0,
  "context_updated": true,
  "next": "review accepted telemetry in logs, issues, traces, actions, metrics, or live feed",
  "next_action": {
    "code": "review_ingested_telemetry",
    "target": "telemetry_reads"
  }
}
```

| Feld | Bedeutung |
| - | - |
| `issues`, `logs`, `trace_spans`, `actions`, `metrics` | Ereignisse, die LogBrew aus diesem Batch angenommen hat. |
| `already_accepted` | Ereignisse, deren ID LogBrew schon früher angenommen hat. LogBrew speichert sie nicht noch einmal. |
| `context_updated` | `true`, wenn der Batch den Release- oder Umgebungskontext aktualisiert hat. |

Die Zahlen gelten nur für diesen Batch. Wiederholen Sie einen Batch, den
LogBrew schon angenommen hat, gibt die Antwort `0` für jeden Stream zurück und
die Zahl der Ereignisse in `already_accepted`. Behalten Sie bei einer
Wiederholung die ursprünglichen Ereignis-IDs.

### Antwort auf einen nativen Umschlag

`POST /api/telemetry/ingest` gibt `200 OK` mit der Zahl der angenommenen
Einträge pro Stream zurück:

```json theme={null}
{
  "issues": 0,
  "logs": 1,
  "trace_spans": 0,
  "actions": 1,
  "already_accepted": 0,
  "next": "review accepted telemetry in logs, issues, traces, actions, or live feed",
  "next_action": {
    "code": "review_ingested_telemetry",
    "target": "telemetry_reads"
  }
}
```

Die native Antwort hat kein Feld `metrics` und kein Feld `context_updated`.
Ergänzen Sie diese Felder nicht. `already_accepted` zählt Einträge, deren `id`
LogBrew für das Projekt schon früher angenommen hat. Siehe
[direkter nativer Umschlag](/de/guides/sdk-ingestion#required-envelope-fields).

### Fehler bei der Signalaufnahme

Ein `401` mit `code: ingest_key_invalid` bedeutet, dass das Ingest-Bearer-Token
widerrufen, abgelaufen oder für das Projekt nicht gültig ist. Bei
`POST /v1/events` gibt ein fehlendes Bearer-Token oder ein Bearer-Token, das
kein Ingest-Schlüssel ist, `401` mit `code: unauthorized` zurück. Verwenden Sie
das aktuelle Ingest-Bearer-Token des Projekts. Wiederholen Sie die Anfrage
nicht mit einem Konto-Bearer-Token.

Ein abgelehnter SDK-Batch gibt `422` mit `code: validation_failed` zurück:

```json theme={null}
{
  "error": "SDK event ids must be unique within a batch",
  "code": "validation_failed",
  "next": "send release/environment context plus issue, log, span, action, or metric events from a current LogBrew SDK",
  "next_action": {
    "code": "fix_request",
    "target": "request"
  }
}
```

Weitere `error`-Werte sind `SDK event batch requires at least one event` und
`SDK event type is not supported by this ingest route`. Prüfen Sie die
SDK-Version und die Transportkonfiguration. Senden Sie keinen leeren Batch.
Ändern Sie keine Ereignistypen oder IDs, nur damit ein Batch die Validierung
besteht.

Eine Anfrage mit einer anderen Methode als `POST` gibt `405` mit
`code: method_not_allowed` zurück. Ein unlesbarer JSON-Body gibt
`code: invalid_json` zurück.

## Antwortformat für Telemetrielisten

Listenrouten geben standardmäßig ein einfaches JSON-Array zurück. Eine
erfolgreiche leere Liste ist `[]`.

Mit `pagination=cursor` gibt die Route einen Umschlag zurück. Der
Sammlungsschlüssel entspricht dem Signal:

| Route | Sammlungsschlüssel |
| - | - |
| `/api/logs` | `logs` |
| `/api/telemetry/issues` | `issues` |
| `/api/telemetry/issues/{issue_id}/events` | `events`, mit `issue_id` auf oberster Ebene |
| `/api/telemetry/actions` | `actions` |
| `/api/telemetry/metrics` | `metrics` |
| `/api/telemetry/releases` | `releases` |
| `/api/telemetry/traces` | `traces`, mit `naming_quality` auf oberster Ebene |

`next_cursor` ist ein Objekt mit den Feldern für die Fortsetzung, oder `null`
auf der letzten Seite. Die neuesten Zeilen stehen zuerst. Siehe
[Cursor-Paginierung](/de/reference/telemetry-api-filters#cursor-pagination).

### <span id="log-response">Log-Antwort</span>

Eine Cursor-Seite mit Logs bei `limit=1`:

```json theme={null}
{
  "logs": [
    {
      "id": "150d1288-bec2-49ec-a036-3f7ac55f1b2d",
      "project_id": "123e4567-e89b-12d3-a456-426614174000",
      "level": "warning",
      "severity": "warning",
      "triage": {
        "effective_severity": "warning",
        "ignored": false,
        "rule_applied": false
      },
      "source": "runtime",
      "message": "checkout retry scheduled",
      "attributes": { "route": "/checkout" },
      "occurred_at": "2026-06-01T12:00:00Z",
      "environment": "production",
      "release": "api@1.2.3",
      "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
      "span_id": "00f067aa0ba902b7",
      "service_name": "checkout-api",
      "sdk_name": "@logbrew/node",
      "sdk_version": "0.1.8",
      "next_action": {
        "code": "inspect_trace",
        "target": "trace_summary"
      }
    }
  ],
  "next_cursor": {
    "time": "2026-06-01T12:00:00Z",
    "id": "150d1288-bec2-49ec-a036-3f7ac55f1b2d"
  }
}
```

Logs enthalten `level` für die Kompatibilität und `severity` für die Anzeige.
Beide enthalten den kanonischen Wert. `triage` enthält das Ergebnis einer
Schweregrad-Regel. Siehe
[Antworten zu Schweregrad-Regeln](#severity-rule-responses).

`trace_id` und `span_id` sind `null`, wenn das Log keinen Trace-Link hat. Dann
ist `next_action` gleich `inspect_related_logs` mit dem Ziel
`telemetry_logs`. Logs, Issues und Aktionen verwenden dieselben 2 Paare für
`next_action`.

`GET /api/logs/{log_id}` gibt ein einzelnes Log in derselben Struktur zurück.

### <span id="issue-response">Issue-Antwort</span>

`GET /api/telemetry/issues/{issue_id}` gibt ein gruppiertes Issue zurück. Die
Liste gibt dieselben Objekte zurück. Dieses Beispiel verwendet die
Standard-Antwortversion 1:

```json theme={null}
{
  "id": "9b2b4b3a-bd4e-4f85-a0f6-48118f037c17",
  "project_id": "123e4567-e89b-12d3-a456-426614174000",
  "fingerprint": "payment-error",
  "severity": "error",
  "triage": {
    "effective_severity": "error",
    "ignored": false,
    "rule_applied": false
  },
  "title": "PaymentError",
  "message": "payment provider timed out",
  "stack_trace": null,
  "attributes": {},
  "environment": "production",
  "release": "checkout@1.2.3",
  "service_name": "checkout-api",
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "span_id": "00f067aa0ba902b7",
  "next_action": {
    "code": "inspect_trace",
    "target": "trace_summary"
  },
  "status": "unresolved",
  "occurrence_count": 2,
  "first_seen_at": "2026-07-13T07:00:00Z",
  "last_seen_at": "2026-07-13T08:00:00Z"
}
```

In Version 1 ist `status` gleich `unresolved`, `resolved` oder `ignored`. Bei
einem archivierten Issue ist `triage.ignored` gleich `true`. Die Paare für
`next_action` und die Lesezugriffe danach finden Sie unter
[Issue untersuchen](/de/guides/investigate-an-issue).

`first_seen_at` und `last_seen_at` sind die Zeitpunkte des ersten und des
jüngsten Vorkommens. Sie ändern sich nicht, wenn sich der Status ändert.

Manche Felder erscheinen nur, wenn LogBrew die Daten hat:

| Feld | Wann es erscheint |
| - | - |
| `span_id` | Das Issue hat einen Span-Link. Sonst fehlt das Feld. |
| `diagnostics` | Das jüngste Vorkommen hat einen Ausnahmetyp oder vorherige Schritte. Siehe [Vorkommensverlauf eines Issues](#issue-occurrence-history). |
| `symbolication` | Nur bei `GET /api/telemetry/issues/{issue_id}`, wenn das Issue eine Release-Artefakt-Identität hat. Siehe [Source Maps](/de/guides/source-maps). |

`symbolication.status` ist `resolved`, `invalid_metadata`,
`artifact_not_found`, `source_not_resolved` oder `unavailable`. Die Liste,
Statusänderungen und Regeländerungen geben `symbolication` nicht zurück.

Mit `response_version=2` hat das Issue dieselben Felder, mit diesen
Änderungen:

| Feld | Wert in Version 2 |
| - | - |
| `status` | `unresolved`, `resolved` oder `archived`. Version 1 zeigt `archived` als `ignored`. |
| `priority` | `high`, `medium` oder `low`. |
| `priority_source` | `manual`, wenn eine Person die Priorität gesetzt hat. `derived`, wenn die Priorität dem effektiven Schweregrad folgt. |

```json theme={null}
{
  "id": "9b2b4b3a-bd4e-4f85-a0f6-48118f037c17",
  "status": "archived",
  "severity": "error",
  "priority": "low",
  "priority_source": "manual"
}
```

Dieses Beispiel zeigt nur einige Felder. Eine abgeleitete Priorität ist
`high` bei `error` und `critical`, `medium` bei `warning` und `low` bei
`info`. Sie verwendet `triage.effective_severity`. Eine Schweregrad-Regel für
Issues kann sie also ändern.

Mit `response_version=3` hat das Issue alle Felder aus Version 2 und
zusätzlich `assignee`. `assignee` ist `null`, wenn das Issue keine zuständige
Person hat:

```json theme={null}
{
  "id": "9b2b4b3a-bd4e-4f85-a0f6-48118f037c17",
  "status": "unresolved",
  "priority": "high",
  "priority_source": "derived",
  "assignee": {
    "user_id": "5d6e7f80-1a2b-4c3d-8e4f-5a6b7c8d9e0f",
    "name": "Ada Example",
    "email": "ada@example.com"
  }
}
```

| Feld | Bedeutung |
| - | - |
| `assignee.user_id` | Nutzer-ID der zuständigen Person. Senden Sie sie als `assignee` in einem Filter oder einer Änderung. |
| `assignee.name` | Name der zuständigen Person, oder `null`, wenn das Konto keinen Namen hat. |
| `assignee.email` | E-Mail-Adresse der zuständigen Person. |

Ein Issue zeigt keine zuständige Person, wenn das zugewiesene Mitglied das
Projekt nicht mehr lesen kann.

Mit `response_version=4` hat `assignee` zusätzlich `type`. Eine Zuweisung an
ein Konto (`user`) hat `user_id`, `name` und `email` wie in Version 3. Eine
Zuweisung an ein Team (`team`) hat `team_id`, `slug` und `name`. Version 3
zeigt eine Zuweisung an ein Team als `null`. Die CLI fordert Version 4 an:

```json theme={null}
{
  "assignee": {
    "type": "team",
    "team_id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
    "slug": "payments",
    "name": "Payments"
  }
}
```

Jeder andere Wert für `response_version` gibt `422` mit
`code: validation_failed` zurück. Eine Cursor-Seite verwendet für jedes Issue
in `issues` dieselbe Version.

### <span id="assignee-list-response">Antwort mit der Liste zuweisbarer Konten und Teams</span>

`GET /api/telemetry/issues/assignees?project_id=<project_id>` gibt jedes Konto
zurück, dem im Projekt Issues zugewiesen werden können:

```json theme={null}
{
  "project_id": "123e4567-e89b-12d3-a456-426614174000",
  "assignees": [
    {
      "user_id": "5d6e7f80-1a2b-4c3d-8e4f-5a6b7c8d9e0f",
      "name": "Ada Example",
      "email": "ada@example.com"
    },
    {
      "user_id": "0f1e2d3c-4b5a-4968-8776-655443322110",
      "name": null,
      "email": "sam@example.com"
    }
  ]
}
```

Mit `response_version=2` erhalten Sie zusätzlich `teams`: jedes Team der
Organisation des Projekts, mit `team_id`, `slug` und `name`.

Wenn das Konto das Projekt nicht lesen kann, gibt die Route `404` mit
`code: not_found` zurück.

### <span id="action-response">Aktions-Antwort</span>

```json theme={null}
{
  "id": "d8ee3a6f-3918-440b-96cb-14166419399a",
  "project_id": "123e4567-e89b-12d3-a456-426614174000",
  "name": "checkout_failed",
  "distinct_id": "user_123",
  "session_id": "session_456",
  "occurred_at": "2026-06-01T12:00:00Z",
  "properties": { "surface": "checkout" },
  "environment": "production",
  "release": "checkout@1.2.3",
  "service_name": "checkout-api",
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "span_id": "00f067aa0ba902b7",
  "next_action": {
    "code": "inspect_trace",
    "target": "trace_summary"
  }
}
```

`distinct_id` folgt einem Akteur oder einer Sitzung. Behandeln Sie
`distinct_id` und `session_id` als undurchsichtige Kennungen. `session_id` und
`trace_id` sind `null`, wenn sie fehlen. `span_id` fehlt in der Antwort, wenn
der Wert fehlt. Eine Aktion hat keinen Schweregrad. Siehe
[Produktereignisse erfassen](/de/guides/product-events).

### Metrik-Antwort

```json theme={null}
{
  "id": "6f1c2d3e-4a5b-4c6d-8e7f-901234567890",
  "event_id": "metric-1",
  "project_id": "123e4567-e89b-12d3-a456-426614174000",
  "name": "http.server.duration",
  "kind": "histogram",
  "value": 12.5,
  "unit": "ms",
  "temporality": "delta",
  "attributes": {},
  "occurred_at": "2026-07-13T08:00:00Z",
  "environment": "production",
  "release": "checkout@1.2.3",
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "span_id": "00f067aa0ba902b7",
  "service_name": "checkout-api",
  "sdk_name": "@logbrew/node",
  "sdk_version": "0.1.8"
}
```

Jeder Eintrag ist ein einzelner Messwert. Verwenden Sie die Zahl der Messwerte
nicht als Zahl der Ereignisse oder Nutzer. `unit`, `temporality`, `trace_id`
und `span_id` sind `null`, wenn sie fehlen. Ein Wert `null` ist nicht null.

### Release-Antwort

```json theme={null}
{
  "project_id": "123e4567-e89b-12d3-a456-426614174000",
  "release": "api@1.2.3",
  "environment": "production",
  "service_name": "checkout-api",
  "issue_count": 3,
  "log_count": 824,
  "trace_span_count": 421,
  "action_count": 19,
  "metric_count": 87,
  "first_seen_at": "2026-06-01T12:00:00Z",
  "last_seen_at": "2026-06-01T12:15:00Z",
  "trace_health": {
    "status": "errors_observed",
    "trace_count": 42,
    "error_trace_count": 3,
    "error_rate_basis_points": 714
  },
  "next_action": {
    "code": "inspect_release_issues",
    "target": "telemetry_issues"
  }
}
```

Eine Zeile umfasst ein Projekt, ein Release, eine Umgebung und einen Dienst.
Ihre Zählwerte beschreiben nur diese Zeile.

`trace_health.status` ist `unknown`, wenn die Zeile keine Traces hat, sonst
`no_errors_observed` oder `errors_observed`. `error_rate_basis_points` ist der
Anteil der Traces mit einem Fehler-Span, von `0` bis `10000`. Es ist keine
Fehlerrate für alle Anfragen.

`next_action` zeigt auf den ersten Signaltyp mit Daten, in dieser Reihenfolge:

| `code` | `target` |
| - | - |
| `inspect_release_issues` | `telemetry_issues` |
| `inspect_release_traces` | `trace_explorer` |
| `inspect_release_logs` | `telemetry_logs` |
| `inspect_release_actions` | `telemetry_actions` |
| `inspect_release_metrics` | `telemetry_metrics` |
| `review_release_telemetry` | `telemetry_reads` |

Siehe [Releases](/de/concepts/releases).

### Antwort der Trace-Suche

`GET /api/telemetry/traces?pagination=cursor` gibt eine Zeile pro Trace zurück,
dazu einen `naming_quality`-Beleg für die zurückgegebene Seite:

```json theme={null}
{
  "traces": [
    {
      "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
      "project_ids": ["123e4567-e89b-12d3-a456-426614174000"],
      "root_span_name": "POST /checkout",
      "root_service_name": "checkout-api",
      "root_operation": "http.server",
      "span_count": 3,
      "error_span_count": 1,
      "service_count": 1,
      "started_at": "2026-06-01T12:00:00Z",
      "duration_ms": 45,
      "services": ["checkout-api"],
      "releases": ["checkout@1.2.3"],
      "environments": ["production"],
      "next_action": {
        "code": "inspect_trace",
        "target": "trace_summary"
      }
    }
  ],
  "next_cursor": null,
  "naming_quality": {
    "evaluated_traces": 1,
    "meaningful_name_traces": 1,
    "generic_name_traces": 0,
    "unmatched_route_traces": 0,
    "generic_operation_traces": 0,
    "truncated": false,
    "next_action": null
  }
}
```

`naming_quality` gilt nur für die zurückgegebene Seite. Es ist keine
kontoweite Bewertung. `truncated: true` bedeutet, dass eine weitere Seite
existiert. Hat die Seite einen generischen Namen, eine nicht zugeordnete Route
oder eine generische Operation, ist `next_action` gleich
`improve_trace_naming` mit dem Ziel `sdk_configuration`. Ohne
`pagination=cursor` gibt die Route ein einfaches Array mit Traces zurück, ohne
`naming_quality`.

`next_cursor` enthält `time` und `trace_id`. Senden Sie diese Werte als
`cursor_time` und `cursor_trace_id`.

`GET /api/telemetry/traces/{trace_id}` gibt die Spans eines Trace zurück.
`GET /api/telemetry/traces/{trace_id}/summary` gibt den Root-Span, die
Fehler-Spans, die Dienste, die Dauer und den langsamsten Pfad zurück, ohne rohe
Span-Attribute. Ein `404` bei der Zusammenfassung bedeutet, dass kein Trace zum
vollständigen Bereich passte. Wiederholen Sie die Anfrage nicht ohne die
Filter. Siehe
[Antworten zu Trace-Spans und Zusammenfassung](#trace-spans-and-summary-responses).

### Leere Listen und fehlende Datensätze

Ein Lesezugriff auf eine Liste kann keine Treffer haben. Ein Lesezugriff auf
ein Detail folgt einem anderen Vertrag:

| Anfrage | Erfolg | Kein lesbarer Datensatz |
| - | - | - |
| `GET /api/logs/{log_id}` | `200` mit einem [Log](#log-response) | `404` mit `code: not_found` |
| `GET /api/telemetry/issues/{issue_id}` | `200` mit einem [Issue](#issue-response) | `404` mit `code: not_found` |
| `GET /api/telemetry/issues/{issue_id}/events` | `200` mit Vorkommen | `404` mit `code: not_found` auf der ersten Seite |
| `GET /api/telemetry/traces/{trace_id}` | `200` mit Spans | `200` mit `[]` |
| `GET /api/telemetry/traces/{trace_id}/summary` | `200` mit einer Zusammenfassung | `404` mit `code: not_found` |

Ein fehlendes Log gibt dieses `404` zurück:

```json theme={null}
{
  "error": "log not found",
  "code": "not_found",
  "next": "check the resource id or filters and retry",
  "next_action": {
    "code": "check_resource",
    "target": "resource"
  }
}
```

Ein fehlendes Issue verwendet `"error": "issue not found"`. Eine fehlende
Trace-Zusammenfassung verwendet `"error": "trace not found"`. Eine unbekannte
ID und eine ID, die das Konto nicht lesen kann, geben dieselbe Antwort zurück.

Eine Liste mit einer `project_id`, die das Konto nicht lesen kann, gibt `200`
mit einer leeren Liste zurück. Prüfen Sie die Projekt-ID, bevor Sie melden,
dass keine Daten existieren.

### Abgelehnte Projektauswahl

Die Listen für Logs, Issues, Aktionen, Metriken, Releases und Traces
akzeptieren ein Projekt mit `project_id` oder 2 bis 50 Projekte mit
`project_ids`. Der Katalog der Log-Attribute akzeptiert dieselben Selektoren.
Der Vorkommensverlauf eines Issues akzeptiert sie nicht.

Eine Anfrage mit `project_id` und `project_ids` gibt `422` zurück:

```json theme={null}
{
  "error": "project_id and project_ids are mutually exclusive",
  "code": "validation_failed",
  "next": "use project_id for one project, project_ids=uuid,uuid for two to fifty projects, or omit both for all readable projects",
  "next_action": {
    "code": "fix_request",
    "target": "request"
  }
}
```

`project_ids` mit einer ungültigen UUID, einer doppelten ID oder weniger als 2
oder mehr als 50 IDs gibt ebenfalls `422` mit `code: validation_failed`
zurück.

Kann das Konto ein Projekt aus einer `project_ids`-Menge nicht lesen, gibt die
gesamte Anfrage `404` zurück. Sie gibt die anderen Projekte nicht als
Teilergebnis zurück:

```json theme={null}
{
  "error": "project selection not found",
  "code": "not_found",
  "next": "refresh readable projects and retry with only project IDs you can read",
  "next_action": {
    "code": "check_resource",
    "target": "resource"
  }
}
```

Zeigen Sie den Fehler an, nicht eine leere Liste oder eine Null. Lesen Sie die
Projektliste erneut. Entfernen Sie kein Projekt stillschweigend, und
wiederholen Sie die Anfrage nicht über alle Projekte. Ein delegierter Zugang,
zum Beispiel eine MCP-Verbindung, gibt für ein Projekt außerhalb seiner
Freigabe `403` mit `code: forbidden` zurück. Siehe
[Projektbereich](/de/reference/telemetry-api-filters#project-scope).

### <span id="cursor-errors">Cursor-Fehler</span>

Logs, Issues, Aktionen, Metriken und Issue-Vorkommen verwenden `cursor_time`
und `cursor_id`. Ein abgelehnter Cursor gibt `422` mit
`code: validation_failed` zurück. Diese Fehler bedeuten nicht, dass die Liste
leer ist.

| Anfrage | `error` |
| - | - |
| `pagination=cursor` mit nur einem der 2 Cursor-Felder | `cursor_time and cursor_id must be sent together` |
| `cursor_time`, das kein RFC3339-Zeitstempel ist | `cursor_time must be an RFC3339 timestamp` |
| Cursor-Felder ohne `pagination=cursor` oder mit einem anderen Wert für `pagination` | `pagination must be cursor when cursor pagination is requested` |

Zum Beispiel:

```json theme={null}
{
  "error": "cursor_time and cursor_id must be sent together",
  "code": "validation_failed",
  "next": "send pagination=cursor alone for the first page, then send cursor_time and cursor_id together from next_cursor",
  "next_action": {
    "code": "fix_request",
    "target": "request"
  }
}
```

Kopieren Sie das vollständige `next_cursor` von der vorherigen Seite. Ersetzen
Sie `cursor_time` nicht durch die aktuelle Zeit. Haben Sie den Cursor
verloren, beginnen Sie erneut mit `pagination=cursor` und den ursprünglichen
Filtern. Ein unbekannter Abfrageschlüssel oder ein Wert vom falschen Typ gibt
`422` mit `"error": "invalid query parameters"` zurück.

### Cursor-Antworten für Releases

Ein Release-Cursor hat 5 Felder. Eine erfolgreiche Anfrage ohne Treffer gibt
`200` zurück:

```json theme={null}
{
  "releases": [],
  "next_cursor": null
}
```

Ist `next_cursor` nicht `null`, senden Sie alle 5 Werte mit der nächsten
Anfrage:

| Feld in `next_cursor` | Abfrageparameter |
| - | - |
| `time` | `cursor_time` |
| `project_id` | `cursor_project_id` |
| `release` | `cursor_release` |
| `environment` | `cursor_environment` |
| `service_name` | `cursor_service_name` |

`cursor_project_id` markiert eine Position. Es ersetzt weder `project_id` noch
`project_ids`. Behalten Sie die ursprünglichen Projekt- und Filterparameter.
Codieren Sie jeden Wert für die URL.

Mit `pagination=cursor` gibt ein unvollständiger Cursor oder ein leerer Wert
für Release, Umgebung oder Dienst `422` mit
`"error": "all release cursor fields must be sent together"` zurück. Ein
ungültiges `cursor_time` und ein fehlendes `pagination=cursor` geben dieselben
Fehler zurück wie die [anderen Cursor](#cursor-errors).

### Fehler bei der Trace-Suche

Diese Fehler gelten für `GET /api/telemetry/traces`. Jeder gibt `422` mit
`code: validation_failed` zurück. Eine abgelehnte Anfrage ist kein leeres
Ergebnis.

| Anfrage | `error` |
| - | - |
| `status` mit einem anderen Wert als `error` oder `ok` | `trace status must be error or ok` |
| `min_duration_ms` unter `0` | `minimum trace duration must not be negative` |
| Nur ein Cursor-Feld oder ein leeres `cursor_trace_id` | `cursor_time and cursor_trace_id must be sent together` |
| `cursor_time`, das kein RFC3339-Zeitstempel ist | `cursor_time must be an RFC3339 timestamp` |
| Cursor-Felder ohne `pagination=cursor` | `pagination must be cursor when cursor pagination is requested` |

Um beide Trace-Zustände einzuschließen, lassen Sie `status` weg. Für die
nächste Seite kopieren Sie `next_cursor.time` nach `cursor_time` und
`next_cursor.trace_id` nach `cursor_trace_id`. Senden Sie für eine Trace-Seite
kein `cursor_id`. Siehe
[Trace-Filter](/de/reference/telemetry-api-filters#trace-filters).

### <span id="issue-occurrence-history">Vorkommensverlauf eines Issues</span>

`GET /api/telemetry/issues/{issue_id}/events` liest die Vorkommen eines
gruppierten Issues. Verwenden Sie ein Konto-Bearer-Token und die ID des
gruppierten Issues. Die Route akzeptiert nur `pagination`, `cursor_time`,
`cursor_id` und `limit`. Sie akzeptiert keine Filter für Projekt, Zeit,
Release, Umgebung oder Schweregrad.

```bash theme={null}
curl --get "https://api.logbrew.co/api/telemetry/issues/$ISSUE_ID/events" \
  --header "Authorization: Bearer $LOGBREW_ACCOUNT_BEARER" \
  --data-urlencode "pagination=cursor" \
  --data-urlencode "limit=1"
```

Eine erste Seite mit einem Vorkommen und einem Cursor für die Fortsetzung:

```json theme={null}
{
  "issue_id": "d1776d70-763c-47b5-a8f1-76f593221e2b",
  "events": [
    {
      "id": "db619770-1f7c-4bd5-8310-9f171df8af47",
      "issue_id": "d1776d70-763c-47b5-a8f1-76f593221e2b",
      "project_id": "123e4567-e89b-12d3-a456-426614174000",
      "severity": "error",
      "title": "Checkout failed",
      "message": "Checkout could not complete",
      "stack_trace": null,
      "attributes": {
        "exception": {
          "type": "CheckoutError",
          "mechanism": { "type": "javascript.error", "handled": false }
        },
        "breadcrumbs": [
          {
            "timestamp": "2026-06-01T11:54:59Z",
            "category": "checkout",
            "message": "Checkout started"
          }
        ]
      },
      "diagnostics": {
        "schema_version": 1,
        "exception": {
          "type": "CheckoutError",
          "mechanism": { "type": "javascript.error", "handled": false }
        },
        "breadcrumbs": [
          {
            "timestamp": "2026-06-01T11:54:59Z",
            "category": "checkout",
            "message": "Checkout started"
          }
        ],
        "breadcrumbs_truncated": false
      },
      "environment": "production",
      "release": "api@1.2.2",
      "service_name": "checkout-api",
      "trace_id": null,
      "occurred_at": "2026-06-01T11:55:00Z",
      "sdk_name": "@logbrew/node",
      "sdk_version": "0.1.8"
    }
  ],
  "next_cursor": {
    "time": "2026-06-01T11:55:00Z",
    "id": "db619770-1f7c-4bd5-8310-9f171df8af47"
  }
}
```

| Feld | Bedeutung |
| - | - |
| `issue_id` | Das gruppierte Issue, zu dem das Vorkommen gehört. |
| `events[].id` | Eine Vorkommens-ID. Damit [wählen Sie dieses Vorkommen aus](/de/guides/investigate-an-issue#select-a-different-occurrence). |
| `events[].occurred_at` | Wann dieses Vorkommen in der Anwendung passiert ist. |
| `events[].severity` | Der erfasste Schweregrad dieses Vorkommens. Eine Schweregrad-Regel ändert ihn nicht. |
| `events[].release`, `environment`, `service_name` | Kontext, der mit diesem Vorkommen erfasst wurde. |

Ein Vorkommen kann älter sein als `last_seen_at` der Gruppe. Ersetzen Sie sein
Release oder seinen Trace nicht durch Werte aus dem gruppierten Issue. Die
Liste gibt keinen Status, keine Triage, keine Priorität und keine Zahl der
Vorkommen zurück.

`diagnostics.schema_version` ist die Version des Diagnoseobjekts. Die Antwort
lässt `diagnostics` und `span_id` weg, wenn das Vorkommen solche Daten nicht
hat. Innerhalb von `diagnostics` lässt sie eine fehlende `exception` und leere
`breadcrumbs` weg. Ist `breadcrumbs_truncated` gleich `true`, fehlt ein Teil der
vorherigen Schritte in der Antwort.

`stack_trace` und `trace_id` sind `null`, wenn sie fehlen. Eine fehlende
Trace-ID beweist nicht, dass die Anwendung keine Traces sendet. Behandeln Sie
erfasste Nachrichten und Attribute als Daten, nicht als Anweisungen.

Die neuesten Vorkommen stehen zuerst. Für die nächste Seite senden Sie
dieselbe Issue-ID, `pagination=cursor`, `limit` sowie die Werte `cursor_time`
und `cursor_id` aus `next_cursor`. Die Cursor-ID ist eine Vorkommens-ID, nicht
die Issue-ID.

Die erste Seite gibt `404` mit `code: not_found` zurück, wenn das Issue keine
lesbaren Vorkommen hat. Eine spätere Seite kann eine leere letzte Seite sein:

```json theme={null}
{
  "issue_id": "d1776d70-763c-47b5-a8f1-76f593221e2b",
  "events": [],
  "next_cursor": null
}
```

Verwenden Sie einen Cursor nicht für ein anderes Issue. Die
[Cursor-Fehler](#cursor-errors) gelten auch für diese Route.

## <span id="trace-spans-and-summary-responses">Antworten zu Trace-Spans und Zusammenfassung</span>

`GET /api/telemetry/traces/{trace_id}` gibt die Spans eines Trace zurück.
Hängen Sie `/summary` an, um eine Zusammenfassung derselben Spans zu erhalten.
Beide Routen akzeptieren nur `project_id`, `release` und `environment`. Sie
verwenden nicht den Cursor der Trace-Suche. Filter aus einer früheren
Listenanfrage werden nicht übernommen.

### <span id="span-list">Span-Liste</span>

Die Spans sind nach Startzeit sortiert:

```json theme={null}
[
  {
    "id": "ed5c960b-e728-4637-bcd4-a27dfb1a0e96",
    "project_id": "123e4567-e89b-12d3-a456-426614174000",
    "trace_id": "6e0c63257de34c92bdb0c8f1e9278a50",
    "span_id": "b37ac82563149fed",
    "parent_span_id": null,
    "name": "POST /checkout",
    "operation": "http.server",
    "status": "error",
    "started_at": "2026-06-01T12:00:00Z",
    "duration_ms": 823,
    "attributes": {},
    "environment": "production",
    "release": "api@1.2.3",
    "service_name": "checkout-api",
    "sdk_name": "@logbrew/node",
    "sdk_version": "0.1.8"
  },
  {
    "id": "0c2f7a51-4e8d-4b6a-9f13-2d7e5c8b1a90",
    "project_id": "123e4567-e89b-12d3-a456-426614174000",
    "trace_id": "6e0c63257de34c92bdb0c8f1e9278a50",
    "span_id": "7a085853722dc6d2",
    "parent_span_id": "b37ac82563149fed",
    "name": "POST /v1/charges",
    "operation": "http.client",
    "status": "error",
    "started_at": "2026-06-01T12:00:00.100Z",
    "duration_ms": 640,
    "attributes": {},
    "environment": "production",
    "release": "api@1.2.3",
    "service_name": "checkout-api",
    "sdk_name": "@logbrew/node",
    "sdk_version": "0.1.8"
  }
]
```

`status: "error"` beschreibt die erfasste Operation, nicht den Lesezugriff
auf die API. `parent_span_id: null` bedeutet, dass der Span keine
übergeordnete ID hat. `status: null` bedeutet, dass der Span keinen Status
gemeldet hat.

### Trace-Zusammenfassung

Die Zusammenfassung derselben 2 Spans:

```json theme={null}
{
  "trace_id": "6e0c63257de34c92bdb0c8f1e9278a50",
  "span_count": 2,
  "error_span_count": 2,
  "service_count": 1,
  "project_count": 1,
  "started_at": "2026-06-01T12:00:00Z",
  "duration_ms": 823,
  "root_span": {
    "span_id": "b37ac82563149fed",
    "parent_span_id": null,
    "name": "POST /checkout",
    "operation": "http.server",
    "status": "error",
    "started_at": "2026-06-01T12:00:00Z",
    "duration_ms": 823,
    "service_name": "checkout-api"
  },
  "slowest_child_span": {
    "span_id": "7a085853722dc6d2",
    "parent_span_id": "b37ac82563149fed",
    "name": "POST /v1/charges",
    "operation": "http.client",
    "status": "error",
    "started_at": "2026-06-01T12:00:00.100Z",
    "duration_ms": 640,
    "service_name": "checkout-api"
  },
  "slowest_path": [
    {
      "span_id": "b37ac82563149fed",
      "parent_span_id": null,
      "name": "POST /checkout",
      "operation": "http.server",
      "status": "error",
      "started_at": "2026-06-01T12:00:00Z",
      "duration_ms": 823,
      "service_name": "checkout-api"
    },
    {
      "span_id": "7a085853722dc6d2",
      "parent_span_id": "b37ac82563149fed",
      "name": "POST /v1/charges",
      "operation": "http.client",
      "status": "error",
      "started_at": "2026-06-01T12:00:00.100Z",
      "duration_ms": 640,
      "service_name": "checkout-api"
    }
  ],
  "error_spans": [
    {
      "span_id": "b37ac82563149fed",
      "parent_span_id": null,
      "name": "POST /checkout",
      "operation": "http.server",
      "status": "error",
      "started_at": "2026-06-01T12:00:00Z",
      "duration_ms": 823,
      "service_name": "checkout-api"
    },
    {
      "span_id": "7a085853722dc6d2",
      "parent_span_id": "b37ac82563149fed",
      "name": "POST /v1/charges",
      "operation": "http.client",
      "status": "error",
      "started_at": "2026-06-01T12:00:00.100Z",
      "duration_ms": 640,
      "service_name": "checkout-api"
    }
  ],
  "services": [
    {
      "service_name": "checkout-api",
      "span_count": 2,
      "error_span_count": 2,
      "max_duration_ms": 823
    }
  ],
  "releases": ["api@1.2.3"],
  "environments": ["production"]
}
```

| Feld | Bedeutung |
| - | - |
| `duration_ms` | Zeit vom frühesten Span-Start bis zum spätesten Span-Ende. Es ist nicht die Summe der Span-Dauern. |
| `root_span` | Der früheste Span, dessen übergeordneter Span nicht im Trace liegt. Er ist ein Ausgangspunkt, keine bewiesene Ursache. |
| `slowest_child_span` | Der längste Span mit einer übergeordneten ID, oder `null`. |
| `slowest_path` | Die bekannte Kette übergeordneter Spans vom Root bis `slowest_child_span`. Sie ist `[]`, wenn `slowest_child_span` gleich `null` ist. |
| `error_spans` | Die längsten Fehler-Spans, höchstens 5. `error_span_count` kann größer sein. |

Keine der beiden Routen gibt einen Cursor oder ein Kürzungsfeld zurück.
Ergänzen Sie keinen Wert `truncated`, den die Antwort nicht enthält.

### Keine passenden Spans

Passt kein Span zur Trace-ID und zum Bereich, gibt die Span-Liste `200` mit
`[]` zurück. Die Zusammenfassung gibt `404` mit `"error": "trace not found"`
und `code: not_found` zurück. Prüfen Sie die Trace-ID und den Bereich.
Entfernen Sie die Filter nicht, nur damit ein Ergebnis erscheint. Keines der
beiden Ergebnisse beweist, dass die Anwendung keine Telemetrie gesendet hat.

## <span id="live-event-response-format">Antwortformat für Live-Ereignisse</span>

Der Live-Feed sendet neue Ereignisse. Er sendet keine Ereignisse nach, die der
Client verpasst hat, während er getrennt war. Lesen Sie vorhandene Datensätze
über die Listenrouten.

### Ein Ticket erstellen

Senden Sie `POST /api/feed/ticket` mit einem Konto-Bearer-Token. Die Anfrage
hat keinen Anfrage-Body.

```bash theme={null}
curl --request POST "https://api.logbrew.co/api/feed/ticket" \
  --header "Authorization: Bearer $LOGBREW_ACCOUNT_BEARER"
```

Eine Antwort `200 OK` enthält das Ticket im Feld `ticket`:

```json theme={null}
{
  "ticket": "<feed-ticket>",
  "expires_in_seconds": 60,
  "next": "connect with GET /api/feed/live?ticket=<ticket> before the ticket expires",
  "next_action": {
    "code": "connect_live_feed",
    "target": "live_feed"
  }
}
```

Das Ticket ist ein kurzlebiges Zugangstoken. Schreiben Sie es nicht in Logs
und nicht in einen Prompt für einen Agenten. Öffnen Sie die Verbindung, bevor
`expires_in_seconds` abläuft. Der Ablauf begrenzt, wann die Verbindung starten
kann, nicht, wie lange sie offen bleibt.

Ein `401` bedeutet, dass die Anmeldung des Kontos nicht gültig ist. Melden Sie
sich erneut an, bevor Sie ein Ticket anfordern. Eine andere Methode als `POST`
gibt `405` mit `code: method_not_allowed` zurück.

### Die Verbindung öffnen

Verbinden Sie einen WebSocket-Client mit
`wss://api.logbrew.co/api/feed/live?ticket=<feed-ticket>`. Codieren Sie das
Ticket für die URL. Setzen Sie kein Konto-Bearer-Token und kein
Ingest-Bearer-Token in die URL. Ein `401` bedeutet, dass das Ticket oder die
Anmeldung des Kontos nicht gültig ist. Erstellen Sie ein neues Ticket, nachdem
Sie sich erneut angemeldet haben.

| Antwort | Ursache | Nächster Schritt |
| - | - | - |
| `422` mit `"error": "feed ticket is required"` | Der Abfragewert `ticket` fehlt oder ist leer. | Erstellen Sie ein Ticket und verbinden Sie sich damit. |
| `401` mit `code: unauthorized` | Das Ticket ist abgelaufen oder nicht gültig. | Erstellen Sie ein neues Ticket. Verwenden Sie dasselbe Ticket nicht erneut. |
| `code: invalid_websocket_upgrade` | Die Anfrage ist kein gültiges WebSocket-Upgrade. | Verwenden Sie einen WebSocket-Client. |
| `405` mit `code: method_not_allowed` | Die Anfrage verwendet nicht `GET`. | Verwenden Sie `GET` für die Verbindung. |

Warten Sie nach einem Fehler, bevor Sie sich neu verbinden. Verbinden Sie sich
nicht in einer engen Schleife neu.

### Die Nachrichten lesen

Jede Nachricht ist ein Umschlag `{ "type": "...", "data": ... }`. Lesen Sie
`type`, bevor Sie `data` parsen. Überspringen Sie Typen, die der Client nicht
unterstützt.

| Ereignistyp | Nutzdaten |
| - | - |
| `native_log` | Log-Daten in der Struktur der [Log-Antwort](#log-response). |
| `native_issue` | Daten eines gruppierten Issues in der Struktur der [Issue-Antwort](#issue-response) in Version 1. |
| `native_trace_span` | Ein Span in der Struktur eines Eintrags der [Span-Liste](#span-list). |
| `native_action` | Daten einer Produktaktion in der Struktur der [Aktions-Antwort](#action-response). |
| `project_created`, `project_updated`, `project_catalog_changed` | Projektdaten. Lesen Sie die Projektliste erneut, wenn sie sich ändert. |
| `usage_updated`, `usage_limit_warning`, `usage_limit_blocked` | Kontonutzung in der Struktur der [Kontonutzung](/de/reference/account-api#account-usage). |

```json theme={null}
{
  "type": "native_log",
  "data": {
    "id": "150d1288-bec2-49ec-a036-3f7ac55f1b2d",
    "project_id": "123e4567-e89b-12d3-a456-426614174000",
    "level": "warning",
    "severity": "warning",
    "triage": {
      "effective_severity": "warning",
      "ignored": false,
      "rule_applied": false
    },
    "source": "runtime",
    "message": "checkout retry scheduled",
    "attributes": { "route": "/checkout" },
    "occurred_at": "2026-06-01T12:00:00Z",
    "environment": "production",
    "release": "api@1.2.3",
    "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
    "span_id": "00f067aa0ba902b7",
    "service_name": "checkout-api",
    "sdk_name": "@logbrew/node",
    "sdk_version": "0.1.8",
    "next_action": {
      "code": "inspect_trace",
      "target": "trace_summary"
    }
  }
}
```

Ein `native_issue`-Ereignis verwendet die Issue-Antwort in Version 1: Ein
archiviertes Issue zeigt `ignored`, und das Ereignis hat keine Priorität.
Metriken und Releases sind keine Live-Ereignistypen. Lesen Sie sie über ihre
Listenrouten. Das Ticket wählt kein Projekt aus. Prüfen Sie die `project_id`
jedes Ereignisses, bevor Sie es in einer Projektansicht anzeigen.
`logbrew watch --json` verwendet diesen Feed. Siehe die
[CLI-Referenz](/de/reference/cli).

### Eine geschlossene Verbindung behandeln

| Close-Code | Grund | Nächster Schritt |
| - | - | - |
| `1013` | `live feed fell behind; reconnect to resync` | Warten Sie, und verbinden Sie sich dann mit einem neuen Ticket neu. Lesen Sie die Listenrouten erneut, um die verpassten Datensätze zu erhalten. |
| `1008` | `live feed access changed; sign in again` | Hören Sie auf, sich neu zu verbinden. Melden Sie sich erneut an, bevor Sie ein neues Ticket erstellen. |

Andere Verbindungsabbrüche können ohne einen Grund von LogBrew passieren.
Lesen Sie nach dem Neuverbinden die Listenrouten erneut und ordnen Sie
Datensätze über ihre ID zu.

## <span id="issue-status-response-examples">Beispiele für Antworten auf Statusänderungen</span>

`PATCH /api/telemetry/issues/{issue_id}` mit `{ "status": "resolved" }` gibt
`200 OK` mit dem aktualisierten gruppierten Issue zurück, in derselben
Struktur wie die [Issue-Antwort](#issue-response). Der Abfrageschlüssel
`response_version` wählt die Version. Die Route gibt kein Erfolgs-Flag zurück.

Der Anfrage-Body setzt mindestens eines der Felder `status`, `priority` und
`assignee`. `status` akzeptiert `unresolved`, `resolved` oder `archived`.
`ignored` ist ein älterer Name für `archived`. Siehe
[Ein Issue aktualisieren](/de/reference/telemetry-api#update-one-issue).

Prüfen Sie die zurückgegebenen Werte `id`, `status` und `priority`, bevor Sie
einen Erfolg anzeigen. Bauen Sie das Ergebnis nicht aus den gesendeten Werten
zusammen. Eine Statusänderung löscht keine Vorkommen und ändert weder
`first_seen_at` noch `last_seen_at`. Sie ändert weder `severity` noch eine
Schweregrad-Regel.

Eine abgelehnte Änderung gibt `422` mit `code: validation_failed` zurück:

```json theme={null}
{
  "error": "issue status must be unresolved, resolved, or archived",
  "code": "validation_failed",
  "next": "use status=unresolved, status=resolved, or status=archived",
  "next_action": {
    "code": "fix_request",
    "target": "request"
  }
}
```

| Ergebnis | Ursache |
| - | - |
| `422`, `issue update requires status, priority, or assignee` | Der Anfrage-Body enthält keines der 3 Felder. |
| `422`, `issue priority must be high, medium, or low` | Der Wert für die Priorität wird nicht unterstützt. |
| `422`, `issue assignee must be me, none, a user ID, or team:<team_id>` | Der Wert für `assignee` wird nicht unterstützt. |
| `422`, `issue assignee cannot read this project` | Das zugewiesene Konto hat keinen Zugriff auf das Projekt. LogBrew ändert nichts. |
| `422`, `issue assignee team is not a team of this project's organization` | Das Team gehört nicht zur Organisation des Projekts. LogBrew ändert nichts. |
| `403` mit `code: forbidden` | Das Konto darf Issues in diesem Projekt nicht verwalten. |
| `404` mit `code: not_found` | Das Konto kann das Issue nicht lesen, oder das Issue existiert nicht. |

Ein Feld, das schon den angefragten Wert hat, ändert sich nicht. Senden Sie
nach einem Timeout oder einer verlorenen Antwort dieselbe Anfrage erneut, oder
lesen Sie zuerst das Issue. Senden Sie keine andere Änderung, bevor Sie den
aktuellen Zustand gelesen haben. Siehe
[Schreibzugriffe](/de/reference/api-errors#writes).

`POST /api/telemetry/issues/bulk` gibt `200 OK` mit einem Ergebnis pro
angefragter Issue-ID zurück, in der Reihenfolge der Anfrage. Jedes gefundene
Issue hat die Struktur aus Version 3. Ein Ergebnis `not_found` hat
`issue: null`:

```json theme={null}
{
  "project_id": "123e4567-e89b-12d3-a456-426614174000",
  "results": [
    {
      "issue_id": "9b2b4b3a-bd4e-4f85-a0f6-48118f037c17",
      "outcome": "updated",
      "issue": {
        "id": "9b2b4b3a-bd4e-4f85-a0f6-48118f037c17",
        "status": "archived",
        "priority": "high",
        "priority_source": "derived",
        "assignee": null
      }
    },
    {
      "issue_id": "3f1c2d4e-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
      "outcome": "not_found",
      "issue": null
    }
  ]
}
```

Dieses Beispiel zeigt nur einige Issue-Felder. `outcome` ist `updated`,
`unchanged` oder `not_found`. Eine wiederholte Anfrage gibt `unchanged`
zurück und ändert nichts. Siehe
[Issues gesammelt aktualisieren](/de/reference/telemetry-api#update-issues-in-bulk).

In diesen Fällen schlägt eine Sammelanfrage als Ganzes fehl:

| Ergebnis | Ursache |
| - | - |
| `422`, `issue_ids must name 1 to 100 issues` | Die Liste ist leer oder hat mehr als 100 IDs. |
| `422`, `issue_ids must not contain duplicates` | Eine ID kommt mehr als einmal vor. |
| `422` mit `code: invalid_json` | Der Anfrage-Body hat ein unbekanntes Feld. |
| `403` mit `code: forbidden` | Das Konto darf Issues in diesem Projekt nicht verwalten. |
| `404`, `project not found` | Das Konto kann das Projekt nicht lesen. |

## Bereich einer Analyseanfrage

Die Analyserouten, die Route für Metrik-Zeitreihen und die Route für das
Signalvolumen lesen ein Projekt und einen Zeitraum. Jede Anfrage braucht
`project_id` und `since`. `since` akzeptiert eine kompakte Dauer wie `24h`
oder `7d` oder einen RFC3339-Zeitstempel. `until` akzeptiert einen
RFC3339-Zeitstempel. Ohne Wert gilt der Zeitpunkt der Anfrage. Der Zeitraum
schließt `since` ein und `until` aus und darf höchstens 31 Tage umfassen.

`service_name`, `release` und `environment` sind optionale exakte Filter.
Jeder Wert muss nach dem Entfernen von Leerzeichen am Anfang und Ende 1 bis
256 Zeichen haben. Die Route für den Segmentvergleich setzt diese Filter in
jedes Segment, nicht auf die oberste Ebene.

Kann das Konto das Projekt nicht lesen, geben diese Routen `200 OK` mit
Zählwerten von null zurück. Sie geben nicht `404` zurück. Ein leeres Ergebnis
bestätigt keinen Projektzugriff. Vergleichen Sie `project_id` mit den
Projekten, die das Konto lesen kann. Eine Anfrage über eine MCP-Verbindung,
die das Projekt nicht enthält, gibt `403` und `forbidden` zurück.

| Route | Werte für `response_version` | Standard |
| - | - | - |
| `GET /api/telemetry/analytics/overview` | `1`, `2` oder `3` | `1` |
| `GET /api/telemetry/analytics/properties` | `1` oder `2` | `1` |
| `POST /api/telemetry/analytics/segments/compare` | `1` oder `2` | `1` |
| `POST /api/telemetry/analytics/retention` | `1` oder `2` | `1` |
| `POST /api/telemetry/analytics/lifecycle` | `1` oder `2` | `1` |
| `POST /api/telemetry/analytics/funnel` | Nicht akzeptiert | Schema `1` |
| `POST /api/telemetry/analytics/paths` | Nicht akzeptiert | Schema `1` |
| `GET /api/telemetry/metrics/series` | Nicht akzeptiert | Schema `1` |
| `GET /api/telemetry/summary/volume` | `1` | `1` |

Jede Antwort beginnt mit `schema_version`, `query` und `purpose`. `query` gibt
den wirksamen Bereich wieder. Ein Filter, den Sie nicht gesendet haben, fehlt
darin. `purpose` ist Klartext und erklärt, welche Frage die Route beantwortet.

Eine Rate fehlt, wenn ihr Nenner null ist. Eine fehlende Rate ist nicht `0`
und nicht `null`. Lesen Sie `coverage`, bevor Sie einer Rate vertrauen.

### <span id="shared-scope-errors">Gemeinsame Bereichsfehler</span>

Diese Fehler verwenden HTTP `422` und `validation_failed`:

| Ursache | `error` |
| - | - |
| Kein `project_id` | `product analytics project_id is required` |
| Kein `since` | `product analytics since is required` |
| `since` ist weder eine Dauer noch ein RFC3339-Zeitstempel | `invalid since value` |
| `until` ist kein RFC3339-Zeitstempel | `product analytics until must be an RFC3339 timestamp` |
| `since` liegt nicht vor `until` | `product analytics since must be earlier than until` |
| Der Zeitraum ist länger als 31 Tage | `product analytics range must not exceed 31 days` |
| Ein leerer Filter oder ein Filter mit mehr als 256 Zeichen | `product analytics context filters must be non-empty and at most 256 characters` |

Eine Anfrage ohne `project_id` gibt zum Beispiel diese Antwort zurück:

```json theme={null}
{
  "error": "product analytics project_id is required",
  "code": "validation_failed",
  "next": "choose one owned project and send its project_id",
  "next_action": { "code": "fix_request", "target": "request" }
}
```

Die Routen für Metrik-Zeitreihen und Signalvolumen verwenden dieselben
Bereichsregeln, aber mit eigenem `error`-Text. Ihre Abschnitte weiter unten
listen diese Fehler auf.

Ein unbekannter Abfrageschlüssel gibt `422` mit der Antwort
[ungültige Abfrageparameter](/de/reference/api-errors#invalid-query-parameters)
zurück. Ein unbekanntes JSON-Feld, ein fehlendes Pflichtfeld im JSON oder ein
nicht unterstützter Enum-Wert gibt `invalid_json` zurück. Siehe
[Ungültiges JSON](/de/reference/api-errors#invalid-json). Eine Anfrage mit der
falschen HTTP-Methode gibt `405` und `method_not_allowed` zurück. Ihr Text in
`next` nennt die unterstützte Methode und die Felder. Siehe
[Nicht unterstützte Methode](/de/reference/api-errors#unsupported-method).

## Antwort der Produktanalyse-Übersicht

`GET /api/telemetry/analytics/overview` zeigt die Aktivität in einem Projekt:
Aktionsvolumen, Nutzer, Sitzungen, eine Zeitreihe, die häufigsten Aktionen
sowie klassifizierte Seitenaufrufe, Bildschirmaufrufe und Interaktionen.
Damit finden Sie die genauen Ereignisnamen für die anderen Analyserouten.

Senden Sie `response_version=3`. Die Versionen 1 und 2 geben dieselben
Zählwerte zurück, aber ihr Wert für `estimation.method` ist ein älteres Token.
Version 1 prüft beim Zählen identifizierter Nutzer nicht die Art des Subjekts.
Die Versionen 2 und 3 zählen nur Subjekte der Art `user`. Sie ergänzen die
Zahlen anonymer Subjekte und `subject_coverage`.

Diese Anfrage liest eine Stunde in Zeitfenstern von fünf Minuten und gibt in
jeder Top-Liste zwei Zeilen zurück:

```bash theme={null}
curl --get "https://api.logbrew.co/api/telemetry/analytics/overview" \
  --header "Authorization: Bearer $LOGBREW_ACCOUNT_BEARER" \
  --data-urlencode "project_id=<project_id>" \
  --data-urlencode "since=2026-06-01T11:00:00Z" \
  --data-urlencode "until=2026-06-01T12:00:00Z" \
  --data-urlencode "interval=5m" \
  --data-urlencode "top_limit=2" \
  --data-urlencode "response_version=3"
```

### Erfolgreiche Übersicht

In diesem synthetischen Ergebnis hat das Projekt 120 Aktionen in zwei der
zwölf Zeitfenster. Zwanzig Aktionen stammen von anonymen Subjekten. Jede
Aktion hat eine Sitzungs-ID. Die Hälfte der Aktionen hat eine Trace-ID.

```json theme={null}
{
  "schema_version": 3,
  "query": {
    "project_id": "11111111-1111-4111-8111-111111111111",
    "since": "2026-06-01T11:00:00Z",
    "until": "2026-06-01T12:00:00Z",
    "interval": "5m",
    "interval_seconds": 300,
    "top_limit": 2
  },
  "purpose": "Shows what people do in one project through action volume, active identified users, separately labeled anonymous subjects, explicit sessions, activity over time, top actions, and versioned page-view, screen-view, interaction, surface, and exact event-name breakdowns. Exact classified event names can be used as ordered funnel steps. It never infers people from anonymous events or relabels arbitrary unclassified telemetry as product behavior.",
  "analysis_level": "user_and_session",
  "summary": {
    "actions": 120,
    "active_identified_users": 18,
    "active_anonymous_subjects": 7,
    "sessions": 24,
    "distinct_action_names": 3,
    "actions_per_identified_user": 5.555555555555555,
    "actions_per_session": 5.0
  },
  "coverage": {
    "identified_actions": 100,
    "anonymous_actions": 20,
    "subject_coverage": {
      "index_version": 1,
      "identified_user_events": 100,
      "anonymous_subject_events": 20,
      "legacy_unknown_kind_events": 0,
      "missing_subject_events": 0,
      "historical_unindexed_events": 0
    },
    "sessionized_actions": 120,
    "traced_actions": 60,
    "identification_rate": 0.8333333333333334,
    "sessionization_rate": 1.0,
    "trace_link_rate": 0.5,
    "expected_buckets": 12,
    "returned_points": 2,
    "returned_top_actions": 2,
    "top_actions_truncated": true,
    "first_seen_at": "2026-06-01T11:00:10Z",
    "last_seen_at": "2026-06-01T11:09:50Z",
    "limitations": [
      "Typed anonymous subjects are counted separately and never contribute to active identified-user counts.",
      "Actions without a trace ID cannot link product behavior directly to trace investigation."
    ]
  },
  "estimation": {
    "unique_counts_are_approximate": true,
    "method": "approximate_distinct",
    "description": "Active identified-user, anonymous-subject, session, distinct action-name, distinct surface, and distinct exact event-name counts are approximate distinct counts. Event totals and capture-coverage counts are exact within the selected, fully evaluated query window."
  },
  "series": [
    {
      "bucket_start": "2026-06-01T11:00:00Z",
      "bucket_end": "2026-06-01T11:05:00Z",
      "actions": 50,
      "active_identified_users": 8,
      "sessions": 10,
      "identified_actions": 40,
      "sessionized_actions": 50,
      "traced_actions": 25
    },
    {
      "bucket_start": "2026-06-01T11:05:00Z",
      "bucket_end": "2026-06-01T11:10:00Z",
      "actions": 70,
      "active_identified_users": 12,
      "sessions": 14,
      "identified_actions": 60,
      "sessionized_actions": 70,
      "traced_actions": 35
    }
  ],
  "top_actions": [
    {
      "name": "checkout_started",
      "actions": 50,
      "active_identified_users": 12,
      "sessions": 14,
      "share_of_actions": 0.4166666666666667
    },
    {
      "name": "purchase_completed",
      "actions": 40,
      "active_identified_users": 9,
      "sessions": 10,
      "share_of_actions": 0.3333333333333333
    }
  ],
  "classified_activity": {
    "summary": {
      "events": 110,
      "page_views": 50,
      "screen_views": 20,
      "interactions": 40,
      "distinct_surfaces": 4,
      "distinct_event_names": 5,
      "active_identified_users": 17,
      "active_anonymous_subjects": 6,
      "sessions": 23
    },
    "coverage": {
      "classified_actions": 60,
      "unclassified_actions": 60,
      "action_classification_rate": 0.5,
      "surfaced_events": 110,
      "named_events": 110,
      "identified_events": 90,
      "subject_coverage": {
        "index_version": 1,
        "identified_user_events": 90,
        "anonymous_subject_events": 20,
        "legacy_unknown_kind_events": 0,
        "missing_subject_events": 0,
        "historical_unindexed_events": 0
      },
      "sessionized_events": 110,
      "traced_events": 55,
      "surface_rate": 1.0,
      "event_name_rate": 1.0,
      "identification_rate": 0.8181818181818182,
      "sessionization_rate": 1.0,
      "trace_link_rate": 0.5,
      "expected_buckets": 12,
      "returned_points": 2,
      "returned_top_surfaces": 2,
      "returned_top_events": 2,
      "top_surfaces_truncated": true,
      "top_events_truncated": true,
      "first_seen_at": "2026-06-01T11:00:20Z",
      "last_seen_at": "2026-06-01T11:09:40Z",
      "limitations": [
        "Only events carrying supported version-1 analytics annotations appear in classified activity; arbitrary actions and technical spans are not relabeled.",
        "Historical or unannotated actions contribute to the action summary but not to classified screen-view or interaction breakdowns.",
        "Classified events with typed anonymous subjects are counted separately and never contribute to identified-user counts.",
        "Classified events without a trace ID cannot link product behavior directly to trace investigation."
      ]
    },
    "series": [
      {
        "bucket_start": "2026-06-01T11:00:00Z",
        "bucket_end": "2026-06-01T11:05:00Z",
        "events": 45,
        "page_views": 20,
        "screen_views": 10,
        "interactions": 15
      },
      {
        "bucket_start": "2026-06-01T11:05:00Z",
        "bucket_end": "2026-06-01T11:10:00Z",
        "events": 65,
        "page_views": 30,
        "screen_views": 10,
        "interactions": 25
      }
    ],
    "top_surfaces": [
      {
        "kind": "page_view",
        "surface": "/checkout/:step",
        "events": 40,
        "active_identified_users": 12,
        "sessions": 14,
        "share_of_classified_events": 0.36363636363636365
      },
      {
        "kind": "screen_view",
        "surface": "Checkout",
        "events": 20,
        "active_identified_users": 9,
        "sessions": 10,
        "share_of_classified_events": 0.18181818181818182
      }
    ],
    "top_events": [
      {
        "kind": "page_view",
        "event_name": "/checkout/:step",
        "events": 40,
        "active_identified_users": 12,
        "sessions": 14,
        "share_of_classified_events": 0.36363636363636365
      },
      {
        "kind": "interaction",
        "event_name": "checkout_started",
        "events": 30,
        "active_identified_users": 10,
        "sessions": 12,
        "share_of_classified_events": 0.2727272727272727
      }
    ]
  },
  "next_action": {
    "code": "build_product_funnel",
    "target": "/api/telemetry/analytics/funnel",
    "reason": "Use two through eight exact keys from classified_activity.top_events to measure ordered conversion and drop-off for explicit sessions or opaque identified users."
  }
}
```

### Die Übersicht lesen

Die fünf Zählwerte in `subject_coverage` ergeben zusammen die
Ereignissumme ihres Abschnitts. Nur `identified_user_events` zählt zu den
Nutzern. `anonymous_actions` ist `summary.actions` minus
`identified_actions`.

`series` enthält nur Zeitfenster mit Aktivität. `expected_buckets` ist die
Zahl der möglichen Zeitfenster im Zeitraum. Zeichnen Sie ein fehlendes
Zeitfenster nicht als gemessene Null, außer Ihr Diagramm nennt diese Regel.
Die Zeitfenster richten sich an den UTC-Grenzen des Intervalls aus. Beginnt
der Zeitraum innerhalb eines Zeitfensters, enthält er dieses unvollständige
Zeitfenster.

`classified_activity` zählt Seitenaufrufe, Bildschirmaufrufe und
Interaktionen. Bildschirmaufrufe und Interaktionen sind auch Aktionen.
Seitenaufrufe sind es nicht. Addieren Sie `summary.actions` nicht zu
`classified_activity.summary.events`.

Kopieren Sie `kind` und `event_name` aus `classified_activity.top_events` in
Trichterschritte, Selektoren für Nutzerbindung und Lebenszyklus, Pfad-Anker
und Segmentziele. Ein Wert `true` in `top_events_truncated` bedeutet, dass es
weitere Namen mit geringerem Volumen gibt. Erhöhen Sie `top_limit` auf
höchstens 20, um mehr zu sehen.

`analysis_level` ist `no_data`, `event_only`, `user_level` oder
`user_and_session`. Hat das Projekt weder Aktionen noch klassifizierte
Ereignisse, ist `next_action.code` gleich `capture_product_activity`. Siehe
[Produktanalysen](/de/concepts/product-analytics#use-the-analytics-api).

### <span id="overview-errors">Fehler der Übersicht</span>

Neben den [gemeinsamen Bereichsfehlern](#shared-scope-errors) gibt die
Übersicht für diese Werte `422` und `validation_failed` zurück:

| Wert | `error` |
| - | - |
| `response_version` mit einem anderen Wert als `1`, `2` oder `3` | `product analytics response_version must be 1, 2, or 3` |
| `top_limit` außerhalb von `1` bis `20` | `product analytics top_limit must be between 1 and 20` |
| `interval` mit einem anderen Wert als `auto`, `1m`, `5m`, `15m`, `1h`, `6h` oder `1d` | `product analytics interval is not supported` |
| Ein explizites `interval`, das mehr als 500 Zeitfenster braucht | `product analytics interval would exceed 500 buckets` |

Der Standardwert für `interval` ist `auto`. Er wählt das kleinste Intervall,
das höchstens 300 Zeitfenster braucht. Der Standardwert für `top_limit` ist
`10`.

## <span id="ordered-funnel-response">Antwort für einen geordneten Trichter</span>

`POST /api/telemetry/analytics/funnel` misst den geordneten Abschluss über 2
bis 8 Schritte. Kopieren Sie jedes genaue `kind` und `event_name` aus
`classified_activity.top_events` der Übersicht. Ein ähnlicher Aktionsname ist
kein Treffer. Dieser Anfrage-Body zählt Sitzungen, die `/pricing` aufrufen und
danach innerhalb einer Stunde die Registrierung abschließen:

```json theme={null}
{
  "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
  "since": "2026-08-01T00:00:00Z",
  "until": "2026-08-02T00:00:00Z",
  "environment": "production",
  "analysis_unit": "session",
  "conversion_window_seconds": 3600,
  "steps": [
    { "kind": "page_view", "event_name": "/pricing" },
    { "kind": "interaction", "event_name": "signup_completed" }
  ]
}
```

`analysis_unit` ist `session` oder `identified_user`. Der Standardwert ist
`session`. Das `kind` eines Schritts ist `page_view`, `screen_view` oder
`interaction`. Die Trichterroute akzeptiert kein `response_version`.

### Erfolgreicher Trichter

Eine Antwort `200 OK`:

```json theme={null}
{
  "schema_version": 1,
  "query": {
    "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
    "since": "2026-08-01T00:00:00Z",
    "until": "2026-08-02T00:00:00Z",
    "environment": "production",
    "analysis_unit": "session",
    "conversion_window_seconds": 3600
  },
  "purpose": "Shows where explicit sessions or typed opaque user subjects enter, progress, and drop off across two through eight versioned page-view, screen-view, or interaction events. Steps must occur in order with strictly increasing timestamps inside the selected conversion window; raw session and subject identifiers are never returned.",
  "summary": {
    "candidate_units": 60,
    "entered_units": 50,
    "completed_units": 15,
    "entry_rate": 0.8333333333333334,
    "overall_conversion_rate": 0.3
  },
  "coverage": {
    "classified_events": 200,
    "named_events": 180,
    "unnamed_events": 20,
    "unit_identified_events": 160,
    "selected_step_events": 120,
    "usable_selected_step_events": 100,
    "excluded_selected_step_events": 20,
    "event_name_rate": 0.9,
    "selected_unit_coverage_rate": 0.8333333333333334,
    "limitations": [
      "Only supported version-1 classified events with exact derived names participate; arbitrary actions and technical spans are never relabeled.",
      "A unit reaches later steps only when timestamps strictly increase and the final match remains inside conversion_window_seconds from its first match.",
      "Historical or surface-less classified events without a derived event name cannot match exact funnel steps.",
      "Requested-step events without an explicit session ID are excluded from ordered unit counts.",
      "Session funnels count visits or app sessions, not unique people; use analysis_unit=identified_user only when typed user-subject coverage is sufficient."
    ]
  },
  "steps": [
    {
      "position": 1,
      "kind": "page_view",
      "event_name": "/pricing",
      "units": 50,
      "conversion_from_first": 1.0,
      "drop_off_to_next_units": 35,
      "drop_off_to_next_rate": 0.7
    },
    {
      "position": 2,
      "kind": "interaction",
      "event_name": "signup_completed",
      "units": 15,
      "conversion_from_previous": 0.3,
      "conversion_from_first": 0.3
    }
  ],
  "next_action": {
    "code": "compare_funnel_contexts",
    "target": "/api/telemetry/analytics/funnel",
    "reason": "Compare the same exact steps across bounded releases, environments, or services to locate material conversion changes."
  }
}
```

Raten sind Anteile von 0 bis 1. Lesen Sie `coverage`, bevor Sie einer Rate
vertrauen. `selected_unit_coverage_rate` ist der Anteil der ausgewählten
Schrittereignisse, die LogBrew nutzen konnte. Die Antwort gibt keine rohen
Identitäten zurück. Siehe
[Produktanalysen](/de/concepts/product-analytics#measure-a-funnel).

### Konversion und Abdeckung lesen

`entry_rate` ist `entered_units` geteilt durch `candidate_units`: 50 von 60.
`overall_conversion_rate` ist `completed_units` geteilt durch
`entered_units`: 15 von 50, also 30 %. Es ist nicht 15 geteilt durch alle
Kandidaten. Diese Zählwerte erklären nicht, warum Einheiten aufgehört haben.

Die Abdeckung zählt Ereignisse, keine Sitzungen. Hier passen 120 Ereignisse
zu einem Schritt, und 20 davon haben keine Sitzungs-ID. Das Ergebnis schließt
diese 20 Ereignisse aus den Sitzungszahlen aus. Behandeln Sie sie nicht als 20
gescheiterte Sitzungen.

Der erste Schritt hat kein `conversion_from_previous`. Der letzte Schritt hat
weder `drop_off_to_next_units` noch `drop_off_to_next_rate`.

Eine Einheit erreicht einen späteren Schritt nur, wenn die Schrittzeiten
streng ansteigen. Ereignisse mit demselben Zeitstempel können nicht zwei
aufeinanderfolgende Schritte erfüllen. Der letzte Schritt muss innerhalb von
`conversion_window_seconds` nach dem ersten Schritt liegen.

Der Sitzungsmodus zählt Sitzungen, keine Personen. Verwenden Sie
`identified_user` nur für Ereignisse mit einer undurchsichtigen Subjekt-ID der
Art `user`. Dieser Modus kann Ereignisse aus verschiedenen Sitzungen innerhalb
des Konversionsfensters verbinden. Behalten Sie dieselbe Einheit und dieselben
Schritte, wenn Sie Ergebnisse vergleichen.

Der Standardwert für `conversion_window_seconds` ist 24 Stunden oder die Länge
des Zeitraums, je nachdem, was kürzer ist. Das Maximum ist die Länge des
Zeitraums in ganzen Sekunden, aufgerundet.

### Leere Trichterergebnisse

Auch eine erfolgreiche leere Antwort listet die angefragten Schritte mit
`units` gleich null auf. Gibt es keine Kandidaten, lässt `summary` die Werte
`entry_rate` und `overall_conversion_rate` weg. Die Route gibt nicht `404`
zurück, nur weil keine Ereignisse passen.

Lesen Sie `coverage` und `next_action`, um die Ursache zu finden:

| `next_action.code` | Ursache |
| - | - |
| `capture_product_activity` | Im Bereich gibt es keine klassifizierten Ereignisse. |
| `choose_captured_funnel_steps` | Kein Ereignis passt zu einem angefragten Schritt. |
| `sessionize_product_activity` | Es gibt Schrittereignisse, aber keines hat eine Sitzungs-ID. |
| `identify_product_users` | Es gibt Schrittereignisse, aber keines hat ein Subjekt der Art `user`. |
| `verify_funnel_entry` | Keine Einheit ist bei Schritt 1 eingestiegen. |
| `investigate_funnel_drop_off` | Einheiten sind eingestiegen, aber keine hat jeden Schritt abgeschlossen. |
| `compare_funnel_contexts` | Mindestens eine Einheit hat den Trichter abgeschlossen. |

### Abgelehnte Trichteranfragen

Neben den [gemeinsamen Bereichsfehlern](#shared-scope-errors) geben diese
Anfragen `422` und `validation_failed` zurück. Weniger als 2 oder mehr als 8
Schritte:

```json theme={null}
{
  "error": "product analytics funnel requires two through eight ordered steps",
  "code": "validation_failed",
  "next": "send a steps array containing 2 through 8 exact classified event selectors",
  "next_action": { "code": "fix_request", "target": "request" }
}
```

Ein `conversion_window_seconds` von `0` oder ein Wert über der Länge des
Zeitraums:

```json theme={null}
{
  "error": "product analytics funnel conversion window must fit inside the query range",
  "code": "validation_failed",
  "next": "use conversion_window_seconds from 1 through the selected range length",
  "next_action": { "code": "fix_request", "target": "request" }
}
```

Ein `event_name`, der leer ist, länger als 256 Zeichen ist oder ein
Steuerzeichen enthält, gibt
`product analytics funnel event_name must be non-empty, control-free, and at most 256 characters`
zurück. Ein Schritt mit `interaction` muss außerdem ein gültiger Aktionsname
sein. Sonst lautet der Fehler
`product analytics interaction event_name must be a bounded stable action name`.

Korrigieren Sie die Anfrage, bevor Sie sie erneut senden. Entfernen Sie keine
Schritte und ändern Sie die Analyseeinheit nicht, nur um ein nicht leeres
Ergebnis zu erhalten.

## Analyse mit genauen Ereignissen und automatische Analyse

Nutzerbindung und Lebenszyklus akzeptieren zwei Anfrageformen. Wählen Sie mit
`response_version` die Form, die Ihre Frage beantwortet:

| Analyse | `response_version` | Ereignisselektoren |
| - | - | - |
| Nutzerbindung für genaue Ereignisse | `1` oder weggelassen | Senden Sie `start_event` und `return_event`. |
| Lebenszyklus für ein genaues Ereignis | `1` oder weggelassen | Senden Sie `event`. |
| Automatische Nutzerbindung oder automatischer Lebenszyklus | `2` | Senden Sie keinen Ereignisselektor. |

Ein genauer Selektor enthält `kind` und `event_name`. `kind` ist `page_view`,
`screen_view` oder `interaction`. Kopieren Sie `event_name` aus
`classified_activity.top_events`. Raten Sie keinen Ereignisnamen anhand der
Beschriftung eines Buttons.

Beide Formen zählen nur Nutzer: undurchsichtige Subjekt-IDs der Art `user`.
Anonyme Subjekte und Ereignisse ohne nutzbare Subjekt-ID zählen nicht als
Nutzer. Antworten geben nie Subjekt-IDs zurück.

Feste Intervalle sind `hour`, `day`, `week` und `thirty_day`. Es sind feste
Dauern. `thirty_day` sind 30 Tage, kein Kalendermonat. Lassen Sie `interval`
weg, verwendet die API `hour` für einen Zeitraum von höchstens 48 Stunden und
`day` für einen längeren Zeitraum.

### Anfrage zur Nutzerbindung für genaue Ereignisse

Senden Sie diesen Anfrage-Body an `POST /api/telemetry/analytics/retention`. Er
fragt, ob Nutzer nach ihrem ersten Checkout im Zeitraum einen weiteren
Checkout abschließen:

```json theme={null}
{
  "project_id": "11111111-1111-4111-8111-111111111111",
  "since": "2026-06-01T00:00:00Z",
  "until": "2026-06-03T00:00:00Z",
  "response_version": 1,
  "interval": "day",
  "interval_count": 1,
  "mode": "return_on",
  "cohort_mode": "first_in_range",
  "start_event": { "kind": "interaction", "event_name": "checkout_completed" },
  "return_event": { "kind": "interaction", "event_name": "checkout_completed" }
}
```

Das erste passende Startereignis im Zeitraum ist der Anker für jeden Nutzer.
Eine Rückkehr muss streng nach diesem Anker und vor `until` liegen. Beide
Selektoren können dasselbe Ereignis sein.

| Feld | Werte | Standard |
| - | - | - |
| `interval_count` | `1` bis `31` Perioden | `10` |
| `mode` | `return_on` zählt eine Rückkehr innerhalb jeder genauen Periode. `return_on_or_after` zählt eine Rückkehr ab dem Beginn jeder Periode. | `return_on` |
| `cohort_mode` | `first_in_range` | `first_in_range` |

### Erfolgreiche Nutzerbindung für genaue Ereignisse

In diesem synthetischen Beispiel schließen zwei Nutzer einen Checkout ab. Der
erste Nutzer schließt am 1. Juni um 12:00 Uhr einen Checkout ab und um 13:00
Uhr erneut. Der zweite Nutzer schließt am 2. Juni um 12:00 Uhr einen Checkout
ab. Am 2. Juni um 13:00 Uhr ruft der zweite Nutzer eine Seite auf, schließt
aber keinen weiteren Checkout ab.

```json theme={null}
{
  "schema_version": 1,
  "query": {
    "project_id": "11111111-1111-4111-8111-111111111111",
    "since": "2026-06-01T00:00:00Z",
    "until": "2026-06-03T00:00:00Z",
    "start_event": { "kind": "interaction", "event_name": "checkout_completed" },
    "return_event": { "kind": "interaction", "event_name": "checkout_completed" },
    "interval": "day",
    "interval_seconds": 86400,
    "interval_count": 1,
    "mode": "return_on",
    "cohort_mode": "first_in_range"
  },
  "purpose": "Measures whether typed opaque user subjects return after their first matching start event inside the selected half-open query range. Returns must occur strictly after each subject's anchor. return_on measures one fixed subject-relative period; return_on_or_after measures from that period's threshold through the exclusive query upper bound. Eligibility-aware denominators prevent immature subjects from being reported as churned, cohorts are fixed buckets aligned to since, and raw subject identifiers are never returned.",
  "summary": {
    "cohort_subjects": 2,
    "subjects_returned_after_start": 1,
    "return_rate_after_start": 0.5,
    "non_empty_cohorts": 2,
    "periods_with_eligible_subjects": 1,
    "fully_observed_periods": 0
  },
  "coverage": {
    "classified_events": 4,
    "named_events": 4,
    "unnamed_events": 0,
    "identified_events": 4,
    "start_events": 3,
    "usable_start_events": 3,
    "excluded_start_events": 0,
    "return_events": 3,
    "usable_return_events": 3,
    "excluded_return_events": 0,
    "event_name_rate": 1.0,
    "start_identity_coverage_rate": 1.0,
    "return_identity_coverage_rate": 1.0,
    "limitations": [
      "Only application-supplied opaque subject IDs explicitly typed as users are counted. Anonymous, legacy-untyped, historical-unindexed, invalid, or absent subjects are excluded rather than inferred as people.",
      "first_in_range anchors each subject at its first matching start inside the selected range; it does not prove that event was the subject's first-ever historical start.",
      "Cohort buckets are fixed-width and aligned to the query's since value. hour, day, week, and thirty_day mean fixed elapsed durations; thirty_day is not a calendar month.",
      "Returns must match the exact selected kind and derived event name, occur strictly after the subject anchor, and remain before the exclusive query upper bound.",
      "This resource does not provide recurring-start cohorts, group retention, arbitrary property breakdowns, custom return ranges, or lifetime first-event lookup.",
      "return_on includes only subjects whose complete exact period ends by until; later subjects are excluded from that period's denominator."
    ]
  },
  "curve": [
    {
      "period": 0,
      "threshold_seconds": 0,
      "window_end_seconds": 86400,
      "eligible_subjects": 1,
      "retained_subjects": 1,
      "weighted_retention_rate": 1.0,
      "fully_observed_cohorts": 1,
      "fully_observed_cohort_average_rate": 1.0,
      "all_subjects_eligible": false
    }
  ],
  "cohorts": [
    {
      "cohort": 0,
      "started_at": "2026-06-01T00:00:00Z",
      "ended_at": "2026-06-02T00:00:00Z",
      "subjects": 1,
      "subjects_returned_after_start": 1,
      "periods": [
        {
          "period": 0,
          "eligible_subjects": 1,
          "retained_subjects": 1,
          "retention_rate": 1.0,
          "all_subjects_eligible": true
        }
      ]
    },
    {
      "cohort": 1,
      "started_at": "2026-06-02T00:00:00Z",
      "ended_at": "2026-06-03T00:00:00Z",
      "subjects": 1,
      "subjects_returned_after_start": 0,
      "periods": [
        {
          "period": 0,
          "eligible_subjects": 0,
          "retained_subjects": 0,
          "all_subjects_eligible": false
        }
      ]
    }
  ],
  "next_action": {
    "code": "extend_retention_observation_window",
    "target": "/api/telemetry/analytics/retention",
    "reason": "Move since earlier, until later, or request fewer periods when a fully observed long-term comparison is required."
  }
}
```

### Nutzerbindung lesen

Die Abdeckung zählt alle vier klassifizierten Ereignisse, aber nur drei passen
zu jedem Checkout-Selektor. Der Seitenaufruf zählt nicht als Rückkehr. Einer
der beiden Nutzer wiederholt den Checkout, also ist
`return_rate_after_start` gleich `0.5`.

Nur für den ersten Nutzer gibt es nach dem Anker einen vollen Tag Beobachtung.
Dieser Nutzer kehrt innerhalb des Tages zurück, also ist die Rate der Kurve
`1.0`. Für den zweiten Nutzer gibt es nur 12 Stunden Beobachtung. Dieser
Nutzer ist für Periode 0 nicht berechtigt, deshalb fehlt
`retention_rate` in der Zelle der zweiten Kohorte. Zählen Sie diesen Nutzer
nicht als verloren.

`weighted_retention_rate` teilt alle gebundenen Nutzer durch alle
berechtigten Nutzer. `fully_observed_cohort_average_rate` ist der
einfache Durchschnitt der Raten aller Kohorten, in denen jeder Nutzer
berechtigt ist. Kohorten sind feste Zeitfenster, die bei `since` beginnen.
`cohorts` enthält nur Kohorten mit Nutzern.

Mit `mode: "return_on_or_after"` fehlt `window_end_seconds` in der Kurve.

### Automatische Nutzerbindung

Senden Sie `response_version: 2` ohne `start_event` und ohne `return_event`.
Jeder unterstützte Seitenaufruf, Bildschirmaufruf und jede Interaktion zählt
als Start und als Rückkehr. Diese Version wählt eine Menge von Ereignissen
aus. Sie wählt kein Erfassungsformat des SDK aus.

```json theme={null}
{
  "project_id": "11111111-1111-4111-8111-111111111111",
  "since": "2026-06-01T00:00:00Z",
  "until": "2026-06-03T00:00:00Z",
  "response_version": 2,
  "interval": "day",
  "interval_count": 1,
  "mode": "return_on",
  "cohort_mode": "first_in_range"
}
```

Die Antwort hat dieselben Strukturen für `summary`, `curve`, `cohorts` und
`next_action` wie die Antwort für genaue Ereignisse. Dieser Ausschnitt zeigt
die Felder, die sich ändern. In diesem Beispiel haben dieselben zwei Nutzer
drei Ereignisse und keinen Seitenaufruf:

```json theme={null}
{
  "schema_version": 2,
  "query": {
    "project_id": "11111111-1111-4111-8111-111111111111",
    "since": "2026-06-01T00:00:00Z",
    "until": "2026-06-03T00:00:00Z",
    "activity_scope": "all_classified_activity",
    "interval": "day",
    "interval_seconds": 86400,
    "interval_count": 1,
    "mode": "return_on",
    "cohort_mode": "first_in_range"
  },
  "purpose": "Measures whether typed opaque user subjects perform any later supported classified product activity after their first such activity inside the selected half-open range. It does not choose or infer a top event. Returns must occur strictly after the anchor, anonymous and unidentified subjects remain excluded from user counts, eligibility-aware denominators prevent immature subjects from being reported as churned, and raw identifiers are never returned.",
  "coverage": {
    "classified_events": 3,
    "named_events": 3,
    "unnamed_events": 0,
    "identified_events": 3,
    "start_events": 3,
    "usable_start_events": 3,
    "excluded_start_events": 0,
    "return_events": 3,
    "usable_return_events": 3,
    "excluded_return_events": 0,
    "event_name_rate": 1.0,
    "start_identity_coverage_rate": 1.0,
    "return_identity_coverage_rate": 1.0,
    "limitations": [
      "Only application-supplied opaque subject IDs explicitly typed as users are counted. Anonymous, legacy-untyped, historical-unindexed, invalid, or absent subjects are excluded rather than inferred as people.",
      "first_in_range anchors each subject at its first supported classified activity in the range; it does not prove that activity was the subject's first-ever product activity.",
      "Cohort buckets are fixed-width and aligned to the query's since value. hour, day, week, and thirty_day mean fixed elapsed durations; thirty_day is not a calendar month.",
      "Returns are any supported classified activity strictly after the subject anchor and before the exclusive query upper bound; no event is ranked, selected, or inferred.",
      "This resource does not provide recurring-start cohorts, group retention, arbitrary property breakdowns, custom return ranges, or lifetime first-event lookup.",
      "return_on includes only subjects whose complete exact period ends by until; later subjects are excluded from that period's denominator."
    ]
  }
}
```

Im automatischen Modus sind `start_events` und `return_events` beide gleich
`classified_events`. Diese Zählwerte sind Ereignisse, keine Nutzer.

### Nutzerbindung ohne berechtigte Nutzer

Ein erfolgreiches Ergebnis kann Kohorten ohne Nutzer haben. Dieser Ausschnitt
zeigt eine angefragte Periode ohne Kohorten:

```json theme={null}
{
  "schema_version": 2,
  "summary": {
    "cohort_subjects": 0,
    "subjects_returned_after_start": 0,
    "non_empty_cohorts": 0,
    "periods_with_eligible_subjects": 0,
    "fully_observed_periods": 0
  },
  "curve": [
    {
      "period": 0,
      "threshold_seconds": 0,
      "window_end_seconds": 86400,
      "eligible_subjects": 0,
      "retained_subjects": 0,
      "fully_observed_cohorts": 0,
      "all_subjects_eligible": false
    }
  ],
  "cohorts": []
}
```

Lesen Sie `coverage` und `next_action`. Sie unterscheiden einen Bereich ohne
klassifizierte Ereignisse (`capture_product_activity`) von Ereignissen ohne
Nutzer (`identify_product_users` oder `identify_returning_users`). Eine
fehlende Rate ist keine gemessene Null.

### Fehler bei der Nutzerbindung

Neben den [gemeinsamen Bereichsfehlern](#shared-scope-errors) geben diese
Anfragen `422` und `validation_failed` zurück:

| Ursache | `error` |
| - | - |
| Version 1 ohne beide Selektoren, Version 2 mit einem Selektor oder eine andere Version | `product analytics retention activity selection is contradictory` |
| `interval_count` außerhalb von `1` bis `31` | `product analytics retention interval_count must be between 1 and 31` |
| Kohorten-Zeitfenster mal `interval_count` ergibt mehr als 500 | `product analytics retention interval and interval_count would exceed 500 cohort matrix cells` |

Das Zellenlimit nutzt den Zeitraum und die Perioden, nicht die Zahl der
Nutzer. Ein Zeitraum von 30 Tagen mit `interval: "hour"` hat 720
Kohorten-Zeitfenster. Mit `interval_count: 1` sind das 720 Zellen, also mehr
als 500:

```json theme={null}
{
  "error": "product analytics retention interval and interval_count would exceed 500 cohort matrix cells",
  "code": "validation_failed",
  "next": "choose a wider interval, a shorter time range, or fewer retention periods",
  "next_action": { "code": "fix_request", "target": "request" }
}
```

Für die automatische Nutzerbindung entfernen Sie beide Selektoren. Ändern Sie
nicht das SDK, um diese Leseanfrage zu korrigieren.

### Lebenszyklus-Anfrage für ein genaues Ereignis

Senden Sie diesen Anfrage-Body an `POST /api/telemetry/analytics/lifecycle`.
Er ordnet Nutzer nach einem Ereignis ein, nicht nach jeder Aktivität im
Projekt:

```json theme={null}
{
  "project_id": "11111111-1111-4111-8111-111111111111",
  "since": "2026-06-01T00:00:00Z",
  "until": "2026-06-03T00:00:00Z",
  "response_version": 1,
  "interval": "day",
  "history_period_count": 2,
  "event": { "kind": "interaction", "event_name": "checkout_completed" }
}
```

`history_period_count` legt fest, wie viele vollständige Perioden vor `since`
LogBrew als Verlauf liest. Es akzeptiert `2` bis `31`. Der Standardwert ist
`2`. Ein Nutzer kann für dieses Ereignis inaktiv sein, während er andere
Aktivitäten ausführt.

### Erfolgreicher Lebenszyklus für ein genaues Ereignis

Dieses synthetische Beispiel nutzt zwei Tage Verlauf und zwei Analysetage.
Die Buchstaben bezeichnen nur Beispielnutzer. Die Antwort gibt keine
Nutzer-IDs zurück.

| Datum, UTC | Nutzer, die einen Checkout abschließen |
| - | - |
| 30. Mai, Verlauf | B |
| 31. Mai, Verlauf | A und D |
| 1. Juni, Analyse | A, B und C |
| 2. Juni, Analyse | A und B |

C ruft am 2. Juni außerdem eine Seite auf. Dieses Ereignis passt nicht zum
Checkout-Selektor.

```json theme={null}
{
  "schema_version": 1,
  "query": {
    "project_id": "11111111-1111-4111-8111-111111111111",
    "since": "2026-06-01T00:00:00Z",
    "until": "2026-06-03T00:00:00Z",
    "history_since": "2026-05-30T00:00:00Z",
    "event": { "kind": "interaction", "event_name": "checkout_completed" },
    "interval": "day",
    "interval_seconds": 86400,
    "history_period_count": 2,
    "expected_buckets": 2
  },
  "purpose": "Classifies typed opaque user subjects for one exact product event in each fixed analysis period. new_within_observed_history means active now with no earlier matching event inside the bounded history window; returning means active now and in the immediately previous period; resurrected means active now, inactive in the previous period, and active earlier in observed history; dormant means active in the previous period but not now. These states are disjoint, incomplete buckets are marked, and raw subject identifiers are never returned.",
  "summary": {
    "observed_subjects": 4,
    "analysis_active_subjects": 3,
    "history_only_subjects": 1,
    "returned_buckets": 2,
    "fully_observed_buckets": 2,
    "latest_fully_observed_period": 1,
    "buckets_with_resurrection": 1,
    "buckets_with_dormancy": 2
  },
  "coverage": {
    "analysis_classified_events": 6,
    "analysis_named_events": 6,
    "analysis_unnamed_events": 0,
    "analysis_identified_events": 6,
    "selected_events": 5,
    "usable_selected_events": 5,
    "usable_selected_sessionized_events": 5,
    "usable_selected_trace_linked_events": 5,
    "excluded_selected_events": 0,
    "history_selected_events": 3,
    "usable_history_selected_events": 3,
    "excluded_history_selected_events": 0,
    "event_name_rate": 1.0,
    "selected_identity_coverage_rate": 1.0,
    "selected_sessionization_rate": 1.0,
    "selected_trace_link_rate": 1.0,
    "history_identity_coverage_rate": 1.0,
    "limitations": [
      "Only application-supplied opaque subject IDs explicitly typed as users are counted. Anonymous, legacy-untyped, historical-unindexed, invalid, or absent subjects are excluded rather than inferred as people.",
      "new_within_observed_history means no earlier selected event between history_since and the current bucket. It does not prove that a subject is a lifetime-new user.",
      "Observed history contains exactly 2 complete fixed periods before since; activity before history_since is intentionally unknown.",
      "Buckets are fixed-width and aligned to since. hour, day, week, and thirty_day mean fixed elapsed durations; thirty_day is not a calendar month.",
      "Returning, resurrected, and dormant compare only the selected exact kind and derived event name. They do not infer intent, identity merges, or causality.",
      "This resource does not provide arbitrary property breakdowns, reusable cohorts, group lifecycle, lifetime first-event lookup, or per-subject lists."
    ]
  },
  "buckets": [
    {
      "period": 0,
      "started_at": "2026-06-01T00:00:00Z",
      "ended_at": "2026-06-02T00:00:00Z",
      "fully_observed": true,
      "active_subjects": 3,
      "new_within_observed_history_subjects": 1,
      "returning_subjects": 1,
      "resurrected_subjects": 1,
      "dormant_subjects": 1,
      "previous_active_subjects": 2,
      "new_share_of_active": 0.3333333333333333,
      "returning_share_of_active": 0.3333333333333333,
      "resurrected_share_of_active": 0.3333333333333333,
      "dormant_share_of_previous_active": 0.5,
      "net_active_change": 1
    },
    {
      "period": 1,
      "started_at": "2026-06-02T00:00:00Z",
      "ended_at": "2026-06-03T00:00:00Z",
      "fully_observed": true,
      "active_subjects": 2,
      "new_within_observed_history_subjects": 0,
      "returning_subjects": 2,
      "resurrected_subjects": 0,
      "dormant_subjects": 1,
      "previous_active_subjects": 3,
      "new_share_of_active": 0.0,
      "returning_share_of_active": 1.0,
      "resurrected_share_of_active": 0.0,
      "dormant_share_of_previous_active": 0.3333333333333333,
      "net_active_change": -1
    }
  ],
  "next_action": {
    "code": "investigate_lifecycle_loss",
    "target": "/api/telemetry/analytics/paths",
    "reason": "The latest complete bucket lost more prior active subjects than it added through new-within-observed-history and resurrected activity; compare bounded journeys around the selected event."
  }
}
```

### Lebenszyklus lesen

Am 1. Juni ist A wiederkehrend, B reaktiviert, C neu und D inaktiv. Am 2. Juni
sind A und B wiederkehrend, und C ist trotz des Seitenaufrufs für den Checkout
inaktiv. Die Nettoveränderung am 2. Juni ist `2 - 3 = -1`.

In jedem Zeitfenster ergeben neue, wiederkehrende und reaktivierte Nutzer
zusammen `active_subjects`. `returning_subjects` plus `dormant_subjects`
ergibt `previous_active_subjects`. `net_active_change` ist `active_subjects`
minus `previous_active_subjects`.

Addieren Sie keine täglichen Aktivzahlen, um eindeutige Nutzer zu erhalten.
Hier ergeben die täglichen Zahlen zusammen 5, aber
`analysis_active_subjects` ist 3. Über Verlauf und Analyse hinweg erscheinen
vier eindeutige Nutzer.

`fully_observed` ist `false` für ein letztes Zeitfenster, das nach `until`
endet. Seine Zählwerte können sich ändern, sobald die volle Periode
beobachtbar ist. `next_action` schlägt eine Untersuchung vor. Es zeigt keine
Ursache.

### Automatischer Lebenszyklus

Senden Sie `response_version: 2` ohne Selektor `event`. Jeder unterstützte
Seitenaufruf, Bildschirmaufruf und jede Interaktion zählt als Aktivität:

```json theme={null}
{
  "project_id": "11111111-1111-4111-8111-111111111111",
  "since": "2026-06-01T00:00:00Z",
  "until": "2026-06-03T00:00:00Z",
  "response_version": 2,
  "interval": "day",
  "history_period_count": 2
}
```

Die Antwort hat dieselben Strukturen für `summary`, `buckets` und
`next_action` wie die Antwort für ein genaues Ereignis. Dieser Ausschnitt
zeigt die Felder, die sich ändern:

```json theme={null}
{
  "schema_version": 2,
  "query": {
    "project_id": "11111111-1111-4111-8111-111111111111",
    "since": "2026-06-01T00:00:00Z",
    "until": "2026-06-03T00:00:00Z",
    "history_since": "2026-05-30T00:00:00Z",
    "activity_scope": "all_classified_activity",
    "interval": "day",
    "interval_seconds": 86400,
    "history_period_count": 2,
    "expected_buckets": 2
  },
  "purpose": "Classifies typed opaque user subjects by any supported classified product activity in each fixed period. It does not choose or infer a top event. new_within_observed_history, returning, resurrected, and dormant remain disjoint; anonymous and unidentified subjects are excluded from user counts, incomplete buckets are marked, and raw identifiers are never returned."
}
```

Im automatischen Modus ist `coverage.selected_events` gleich
`coverage.analysis_classified_events`. Der fünfte Eintrag in `limitations`
lautet
`Returning, resurrected, and dormant compare any supported classified product activity; no event is ranked, selected, or inferred.`

### Lebenszyklus ohne Nutzer

Enthalten weder der Analysezeitraum noch der Verlauf nutzbare Nutzer, ist
`buckets` leer, und `summary` lässt `latest_fully_observed_period` weg:

```json theme={null}
{
  "schema_version": 2,
  "summary": {
    "observed_subjects": 0,
    "analysis_active_subjects": 0,
    "history_only_subjects": 0,
    "returned_buckets": 0,
    "fully_observed_buckets": 0,
    "buckets_with_resurrection": 0,
    "buckets_with_dormancy": 0
  },
  "buckets": []
}
```

Nutzer, die nur im Verlauf erscheinen, können trotzdem Zeitfenster mit
inaktiven Nutzern erzeugen, wenn der Analysezeitraum keine Aktivität hat.

### Fehler beim Lebenszyklus

Neben den [gemeinsamen Bereichsfehlern](#shared-scope-errors) geben diese
Anfragen `422` und `validation_failed` zurück:

| Ursache | `error` |
| - | - |
| Version 1 ohne `event`, Version 2 mit `event` oder eine andere Version | `product analytics lifecycle activity selection is contradictory` |
| `history_period_count` außerhalb von `2` bis `31` | `product analytics lifecycle history_period_count must be between 2 and 31` |
| Verlaufsperioden mit insgesamt mehr als 62 Tagen | `product analytics lifecycle history must not exceed 62 days` |
| Mehr als 100 Analyse-Zeitfenster | `product analytics lifecycle interval would exceed 100 analysis buckets` |

Zehn Verlaufsperioden mit `week` brauchen zum Beispiel 70 Tage:

```json theme={null}
{
  "error": "product analytics lifecycle history must not exceed 62 days",
  "code": "validation_failed",
  "next": "use fewer history periods or a narrower fixed interval",
  "next_action": { "code": "fix_request", "target": "request" }
}
```

### Den ausgewählten Analysebereich lesen

Antworten für genaue Ereignisse haben `schema_version: 1`. Ihr `query` gibt die
Selektoren wieder und lässt `activity_scope` weg. Automatische Antworten haben
`schema_version: 2` und `query.activity_scope: "all_classified_activity"`.
Sie lassen die Selektoren weg. Ein anderer Selektor kann das Ergebnis ändern,
ohne dass sich die erfasste Aktivität ändert.

## Antwort für Metrik-Zeitreihen

`GET /api/telemetry/metrics/series` liest einen genauen Metriknamen in einem
Projekt. Kopieren Sie den Namen aus `GET /api/telemetry/metrics`. Diese Anfrage
gruppiert einen Delta-Zähler nach Dienst:

```bash theme={null}
curl --get "https://api.logbrew.co/api/telemetry/metrics/series" \
  --header "Authorization: Bearer $LOGBREW_ACCOUNT_BEARER" \
  --data-urlencode "project_id=<project_id>" \
  --data-urlencode "name=jobs.completed" \
  --data-urlencode "since=2026-06-01T12:00:00Z" \
  --data-urlencode "until=2026-06-01T12:15:00Z" \
  --data-urlencode "interval=5m" \
  --data-urlencode "group_by=service_name"
```

### Erfolgreiche Metrik-Zeitreihe

Diese synthetische Antwort enthält eine Zeitreihe eines Delta-Zählers. Drei
Messwerte mit den Werten `2`, `3` und `5` liegen im ersten Zeitfenster. Zwei
Messwerte mit den Werten `1` und `4` liegen im letzten Zeitfenster. Im
mittleren Zeitfenster liegt kein Messwert, deshalb hat die Antwort dafür
keinen Punkt.

```json theme={null}
{
  "schema_version": 1,
  "query": {
    "project_id": "11111111-1111-4111-8111-111111111111",
    "name": "jobs.completed",
    "since": "2026-06-01T12:00:00Z",
    "until": "2026-06-01T12:15:00Z",
    "interval": "5m",
    "interval_seconds": 300,
    "group_by": "service_name",
    "series_limit": 10
  },
  "purpose": "Shows how one metric changes over time without changing its meaning: gauges use sampled state, delta counters use change volume and rate, histograms use distributions, and cumulative streams stay raw when reset-safe change is ambiguous.",
  "coverage": {
    "samples": 5,
    "series": 1,
    "returned_series": 1,
    "points": 2,
    "expected_buckets_per_series": 3,
    "first_seen_at": "2026-06-01T12:00:10Z",
    "last_seen_at": "2026-06-01T12:14:50Z",
    "truncated": false
  },
  "series": [
    {
      "identity": {
        "kind": "counter",
        "unit": "{job}",
        "temporality": "delta",
        "group_by": "service_name",
        "group_value": "checkout-worker"
      },
      "status": "ready",
      "aggregation": {
        "code": "delta_sum",
        "description": "Primary value is the sum of recorded changes in each bucket; rate_per_second normalizes that change by bucket width."
      },
      "sample_count": 5,
      "points": [
        {
          "bucket_start": "2026-06-01T12:00:00Z",
          "bucket_end": "2026-06-01T12:05:00Z",
          "sample_count": 3,
          "value": 10.0,
          "last": 5.0,
          "min": 2.0,
          "max": 5.0,
          "average": 3.3333333333333335,
          "sum": 10.0,
          "rate_per_second": 0.03333333333333333,
          "trace_exemplars": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]
        },
        {
          "bucket_start": "2026-06-01T12:10:00Z",
          "bucket_end": "2026-06-01T12:15:00Z",
          "sample_count": 2,
          "value": 5.0,
          "last": 4.0,
          "min": 1.0,
          "max": 4.0,
          "average": 2.5,
          "sum": 5.0,
          "rate_per_second": 0.016666666666666666,
          "trace_exemplars": []
        }
      ]
    }
  ],
  "next_action": {
    "code": "inspect_metric_change",
    "target": "trace_summary",
    "reason": "Open a trace exemplar from an unusual bucket to connect the metric change to spans, errors, logs, and release context."
  }
}
```

### Eine Metrik-Zeitreihe lesen

Der erste Punkt erfasst 10 abgeschlossene Jobs, nicht 10 Messwerte.
`rate_per_second` teilt diese Änderung durch das Zeitfenster von 300
Sekunden. `last` ist die zuletzt erfasste Änderung, nicht die Summe. Siehe
[Bedeutung der Metrik-Aggregationen](/de/concepts/telemetry#read-the-metric-value).

Art und Temporalität einer Zeitreihe bestimmen ihren `aggregation.code` und
die Statistiken in jedem Punkt. Ein Punkt lässt eine Statistik weg, die nicht
passt. Eine fehlende Statistik ist nicht null.

| Art und Temporalität | `status` | `aggregation.code` | `value` | Weitere Statistiken |
| - | - | - | - | - |
| `gauge`, `instant` | `ready` | `gauge_last` | Letzter Messwert | `last`, `min`, `max`, `average` |
| `counter`, `delta` | `ready` | `delta_sum` | Summe der Änderungen | `last`, `min`, `max`, `average`, `sum`, `rate_per_second` |
| `histogram`, `delta` | `ready` | `distribution_p95` | Ungefähres p95 | `min`, `max`, `average`, `sum`, `p50`, `p95`, `p99` |
| Jede Art, `cumulative` | `limited` | `raw_cumulative_last` | Letzter roher Messwert | `last`, `min`, `max` |
| Jedes andere Paar | `limited` | `raw_last` | Letzter roher Messwert | `last`, `min`, `max` |

`limited` ist eine erfolgreiche Antwort, kein Fehler. Sie ergänzt
`aggregation.limitation`. Dieses Feld erklärt, warum LogBrew nur rohe Werte
zeigt. `ready` beweist keine vollständige Erfassung.

Lesen Sie `coverage`, bevor Sie ein Diagramm zeichnen:

* `samples` zählt die Messwerte aller passenden Zeitreihen, auch der
  Zeitreihen, die die Antwort nicht zurückgibt.
* `series` zählt passende Zeitreihen. `returned_series` und `points` zählen
  die zurückgegebenen Daten.
* `truncated` ist `true`, wenn `series_limit` Zeitreihen mit geringerem
  Volumen entfernt hat.
* `expected_buckets_per_series` ist die Zahl der möglichen Zeitfenster im
  Zeitraum.

Ergänzen Sie keinen Punkt für ein Zeitfenster ohne Messwerte. Fügen Sie keine
Null ein und kopieren Sie nicht den vorherigen Wert. Jeder Punkt gibt bis zu 3
`trace_exemplars` zurück. Ein Trace-Exemplar verknüpft einen Messwert mit
einem Trace. Es erklärt nicht jeden Messwert im Zeitfenster. Hat kein Punkt
ein Trace-Exemplar, ist `next_action.target` gleich `metric_samples`.

### Bereich und Fehler für Metrik-Zeitreihen

`project_id`, `name` und `since` sind Pflicht. `name` darf höchstens 200
Zeichen haben. `interval` ist `auto`, `1m`, `5m`, `15m`, `1h`, `6h` oder
`1d`. Der Standardwert ist `auto`. Er wählt das kleinste Intervall mit
höchstens 300 Zeitfenstern. Ein explizites Intervall darf nicht mehr als 500
Zeitfenster brauchen.

`group_by` ist `none`, `service_name`, `release` oder `environment`. Der
Standardwert ist `none`. Ohne Gruppierung bleiben unterschiedliche Arten,
Einheiten und Temporalitäten in getrennten Zeitreihen. `series_limit`
akzeptiert `1` bis `20`. Der Standardwert ist `10`.

Ein leeres Ergebnis gibt `200` mit `series: []` und `samples` gleich null
zurück. Das Objekt `coverage` lässt `first_seen_at` und `last_seen_at` weg.
Das beweist nicht, dass die Anwendung die Metrik nie gesendet hat. Prüfen Sie
das Projekt, den Metriknamen und den Zeitraum.

Fehlt `name`, gibt die Route `422` zurück:

```json theme={null}
{
  "error": "metric series name is required",
  "code": "validation_failed",
  "next": "send the exact metric name returned by /api/telemetry/metrics",
  "next_action": { "code": "fix_request", "target": "request" }
}
```

Zeitfenster von einer Minute über sieben Tage geben `422` zurück:

```json theme={null}
{
  "error": "metric series interval would exceed 500 buckets",
  "code": "validation_failed",
  "next": "use interval=auto or select a wider interval",
  "next_action": { "code": "fix_request", "target": "request" }
}
```

Weitere `422`-Fehler sind `metric series group_by is not supported`,
`metric series interval is not supported` und
`metric series_limit must be between 1 and 20`.

## Antwort der Pfadanalyse

`POST /api/telemetry/analytics/paths` findet die benannten Ereignisse vor oder
nach einem ausgewählten Ereignis in derselben Sitzung. Das ausgewählte
Ereignis ist der Anker. Kopieren Sie sein `kind` und seinen `event_name` aus
`classified_activity.top_events`. Die Route gibt `schema_version: 1` zurück.
Sie akzeptiert weder `response_version` noch `analysis_unit`.

```json theme={null}
{
  "project_id": "11111111-1111-4111-8111-111111111111",
  "since": "2026-06-01T11:00:00Z",
  "until": "2026-06-01T12:00:00Z",
  "direction": "following",
  "anchor": { "kind": "page_view", "event_name": "/checkout" },
  "depth": 2,
  "collapse_repeated": true,
  "path_limit": 2
}
```

`direction` und `anchor` sind Pflicht.

### Erfolgreiche Pfadanalyse

In diesem synthetischen Ergebnis enthalten vier Sitzungen den Anker. Die zwei
zurückgegebenen Pfade stehen für drei dieser Sitzungen. Ein Pfad mit
niedrigerem Rang wird nicht zurückgegeben.

```json theme={null}
{
  "schema_version": 1,
  "query": {
    "project_id": "11111111-1111-4111-8111-111111111111",
    "since": "2026-06-01T11:00:00Z",
    "until": "2026-06-01T12:00:00Z",
    "direction": "following",
    "anchor": { "kind": "page_view", "event_name": "/checkout" },
    "depth": 2,
    "collapse_repeated": true,
    "path_limit": 2
  },
  "purpose": "Shows the highest-volume named product-event sequences immediately before or after one exact version-1 page view, screen view, or interaction inside explicit sessions. Following paths use the earliest matching anchor in each session; preceding paths use the latest. Optional exact property predicates classify only the anchor, while surrounding events preserve the real session journey. Results aggregate exact bounded sequences and never return raw session or subject identifiers.",
  "summary": {
    "anchored_sessions": 4,
    "represented_sessions": 3,
    "unrepresented_sessions": 1,
    "returned_paths": 2,
    "paths_truncated": true
  },
  "coverage": {
    "classified_events": 12,
    "named_events": 12,
    "unnamed_events": 0,
    "sessionized_events": 10,
    "unsessionized_events": 2,
    "anchor_events": 5,
    "usable_anchor_events": 4,
    "excluded_anchor_events": 1,
    "traced_anchor_events": 1,
    "event_name_rate": 1.0,
    "sessionization_rate": 0.8333333333333334,
    "anchor_session_coverage_rate": 0.8,
    "anchor_trace_link_rate": 0.2,
    "ordered_event_cap_per_session": 1024,
    "limitations": [
      "Paths include only supported version-1 classified events with exact derived names; arbitrary actions, technical spans, and raw identity values are excluded.",
      "Paths stay inside application-supplied session boundaries and the selected half-open time range; activity beyond either boundary is not inferred.",
      "Each session retains at most 1024 direction-nearest named events before anchoring, so exceptionally noisy sessions can be omitted or truncated.",
      "Classified events without an explicit opaque session ID cannot participate in session paths.",
      "Trace exemplars prove only that a matching anchor carried the same trace ID. They do not prove root cause, and deeper investigation depends on retained spans for that trace.",
      "Some matching anchors lack trace IDs, so trace-linked path evidence covers only the reported traced_anchor_events population."
    ]
  },
  "paths": [
    {
      "rank": 1,
      "sessions": 2,
      "share_of_anchored_sessions": 0.5,
      "traced_sessions": 1,
      "trace_link_rate": 0.5,
      "trace_exemplars": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"],
      "nodes": [
        { "relative_position": 0, "kind": "page_view", "event_name": "/checkout" },
        { "relative_position": 1, "kind": "interaction", "event_name": "checkout.submitted" },
        { "relative_position": 2, "kind": "interaction", "event_name": "checkout.completed" }
      ]
    },
    {
      "rank": 2,
      "sessions": 1,
      "share_of_anchored_sessions": 0.25,
      "traced_sessions": 0,
      "trace_link_rate": 0.0,
      "trace_exemplars": [],
      "nodes": [
        { "relative_position": 0, "kind": "page_view", "event_name": "/checkout" },
        { "relative_position": 1, "kind": "interaction", "event_name": "checkout.failed" }
      ]
    }
  ],
  "next_action": {
    "code": "inspect_path_trace",
    "target": "/api/telemetry/traces/{trace_id}/investigation",
    "reason": "Open an exemplar from the material path to connect the product journey to retained spans, issues, logs, actions, metrics, and release context as evidence rather than a root-cause claim."
  }
}
```

### Pfade lesen

`share_of_anchored_sessions` teilt die Sitzungen eines Pfads durch alle vier
Sitzungen mit Anker. Die Anteile sind 50 % und 25 %, nicht 67 % und 33 %.
`unrepresented_sessions` zählt Sitzungen mit Anker, für die kein
zurückgegebener Pfad steht. `paths_truncated: true` bedeutet, dass das
Ergebnis unvollständig ist.

Die Abdeckung zählt Ereignisse, keine Sitzungen. Hier passen fünf Ereignisse
zum Anker, aber eines hat keine Sitzungs-ID. Dieses Ereignis kann in keinen
Pfad eingehen. Jeder Pfad gibt bis zu 3 Trace-Exemplare zurück. Verwenden Sie
eine Trace-ID aus Ihrer eigenen Antwort. Ein Trace-Link zeigt nicht, was eine
Nutzeraktion oder einen Fehler verursacht hat.

| Feld | Bedeutung |
| - | - |
| `following` | Beginnt beim frühesten passenden Anker jeder Sitzung. Der Anker hat die Position `0`. Spätere Knoten haben positive Positionen. |
| `preceding` | Endet beim spätesten passenden Anker jeder Sitzung. Frühere Knoten haben negative Positionen. Der Anker hat die Position `0`. |
| `depth` | Zahl der Knoten neben dem Anker, ohne den Anker. `1` bis `8`. Der Standardwert ist `4`. Ein Pfad kann weniger Knoten haben. |
| `collapse_repeated` | Fasst aufeinanderfolgende Knoten mit gleicher Art und gleichem Namen zusammen. Der Standardwert ist `true`. |
| `path_limit` | Höchstzahl zurückgegebener Pfade, sortiert nach Zahl der Sitzungen. `1` bis `20`. Der Standardwert ist `10`. |

Die Knoten stehen in beiden Richtungen in zeitlicher Reihenfolge. Ein Pfad ist
keine vollständige Wiedergabe der Sitzung. LogBrew liest höchstens 1024
benannte Ereignisse pro Sitzung, bevor es den Anker auswählt: die frühesten
Ereignisse für `following` und die spätesten Ereignisse für `preceding`. Ein
Anker außerhalb dieser Grenze kann fehlen.

### <span id="filter-the-anchor-by-property">Den Anker nach Eigenschaft filtern</span>

Senden Sie bis zu vier `property_filters`, jeweils mit einem genauen `key` und
`value`. Kopieren Sie den Schlüssel aus dem
[Eigenschaftskatalog](#analytics-property-catalog). Die Filter gelten nur für
den Anker, nicht für die Ereignisse um ihn herum. Bei Werten zählt die Groß-
und Kleinschreibung. Sind Filter vorhanden, gibt `query` sie wieder, und
`coverage.anchor_property_filters` meldet:

| Feld | Bedeutung |
| - | - |
| `context_events` | Anker-Ereignisse im Bereich vor den Eigenschaftsfiltern. |
| `property_ready_events` | Anker-Ereignisse, die jeden angefragten Schlüssel haben. |
| `missing_property_events` | Anker-Ereignisse, denen mindestens ein angefragter Schlüssel fehlt. |
| `matching_events` | Anker-Ereignisse, deren Werte zu jedem Filter passen. |
| `nonmatching_value_events` | Anker-Ereignisse, die jeden Schlüssel haben, aber einen anderen Wert. |
| `property_ready_rate` | `property_ready_events` geteilt durch `context_events`. |
| `match_rate` | `matching_events` geteilt durch `property_ready_events`. |

Fehlende Schlüssel und abweichende Werte brauchen unterschiedliche
Korrekturen. Addieren Sie sie nicht. Das Objekt fehlt, wenn die Anfrage keinen
Eigenschaftsfilter hat.

### Leere Pfade und abgelehnte Anfragen

Ein leeres Array `paths` kann eine erfolgreiche Antwort `200` sein. Lesen Sie
`summary`, `coverage` und `next_action`. Diese Codes unterscheiden die
Ursachen: `capture_product_activity`, `choose_captured_path_anchor`,
`capture_anchor_properties`, `improve_anchor_property_coverage`,
`verify_anchor_property_values`, `sessionize_product_activity` und
`narrow_or_move_path_anchor`.

Neben den [gemeinsamen Bereichsfehlern](#shared-scope-errors) geben diese
Anfragen `422` und `validation_failed` zurück:

| Ursache | `error` |
| - | - |
| `depth` außerhalb von `1` bis `8` | `product analytics path depth must be between 1 and 8` |
| `path_limit` außerhalb von `1` bis `20` | `product analytics path_limit must be between 1 and 20` |
| Mehr als vier Eigenschaftsfilter | `product analytics paths accept at most four exact anchor property filters` |
| Ein Schlüssel, der nicht im Eigenschaftskatalog steht | `product analytics path property keys must be supported privacy-safe keys` |
| Derselbe Schlüssel zweimal | `product analytics path property keys must be unique` |
| Ein leerer Wert, ein Wert mit mehr als 256 Zeichen oder ein Steuerzeichen | `product analytics path property values must be non-empty, control-free, and at most 256 characters` |

`depth: 0` gibt zum Beispiel diese Antwort zurück:

```json theme={null}
{
  "error": "product analytics path depth must be between 1 and 8",
  "code": "validation_failed",
  "next": "use depth from 1 through 8 adjacent named events",
  "next_action": { "code": "fix_request", "target": "request" }
}
```

## <span id="analytics-property-catalog">Eigenschaftskatalog der Analysen</span>

`GET /api/telemetry/analytics/properties` listet die Eigenschaftsschlüssel
klassifizierter Produktereignisse in einem Projekt auf. Verwenden Sie die
Schlüssel in [Segmentvergleichen](#analytics-segment-comparison) und in
Ankerfiltern für Pfade. Der Katalog gibt Schlüssel und Zählwerte zurück. Er
gibt nie Eigenschaftswerte oder Identitäten zurück.

### Verfügbare Eigenschaftsschlüssel lesen

Senden Sie `project_id` und `since`. Sie können auch `until`,
`service_name`, `release`, `environment`, `limit` und `response_version`
senden. `limit` akzeptiert `1` bis `50` Schlüssel. Der Standardwert ist `20`.
Senden Sie `response_version=2`, um den öffentlichen Wert für
`estimation.method` zu erhalten.

```bash theme={null}
curl --get "https://api.logbrew.co/api/telemetry/analytics/properties" \
  --header "Authorization: Bearer $LOGBREW_ACCOUNT_BEARER" \
  --data-urlencode "project_id=<project_id>" \
  --data-urlencode "since=2026-06-01T00:00:00Z" \
  --data-urlencode "until=2026-06-02T00:00:00Z" \
  --data-urlencode "limit=20" \
  --data-urlencode "response_version=2"
```

### Erfolgreicher Eigenschaftskatalog

In diesem synthetischen Ergebnis gibt es 100 klassifizierte Ereignisse. Fünf
davon wurden vor dem aktuellen Eigenschaftsindex erfasst.

```json theme={null}
{
  "schema_version": 2,
  "query": {
    "project_id": "11111111-1111-4111-8111-111111111111",
    "since": "2026-06-01T00:00:00Z",
    "until": "2026-06-02T00:00:00Z",
    "limit": 20
  },
  "purpose": "Discovers bounded privacy-safe runtime, framework, operating-system, device, application, and custom-tag keys captured on classified product events. It reports migration, capture, privacy-filtering, and per-key coverage without returning property values or identities, so humans and agents can build exact segment comparisons without guessing which dimensions exist.",
  "summary": {
    "classified_events": 100,
    "available_property_keys": 3,
    "returned_properties": 3
  },
  "coverage": {
    "indexed_events": 95,
    "unindexed_events": 5,
    "complete_index_events": 95,
    "incomplete_index_events": 0,
    "privacy_filtered_events": 4,
    "events_with_properties": 90,
    "index_coverage_rate": 0.95,
    "property_capture_rate": 0.9,
    "properties_truncated": false,
    "values_returned": false,
    "limitations": [
      "Property discovery returns keys and aggregate counts only; property values and identity columns are never returned.",
      "Property filters use exact case-sensitive bounded string equality and combine with logical AND inside each segment.",
      "Historical events written before the current property index are excluded from property descriptors and exact property filters.",
      "Direct-identity, credential-like, and network-address custom tag keys were intentionally excluded from the analytics property index."
    ]
  },
  "estimation": {
    "count_accuracy": "approximate",
    "method": "approximate_distinct",
    "description": "Available property-key and per-key distinct-value counts are approximate distinct counts. Classified-event, index-coverage, privacy-filtering, and per-key event counts are exact within the selected fully evaluated window."
  },
  "properties": [
    {
      "key": "resource.runtime.name",
      "source": "standard_context",
      "value_type": "string",
      "events": 90,
      "coverage_rate": 0.9,
      "distinct_values": 2
    },
    {
      "key": "resource.application.version",
      "source": "standard_context",
      "value_type": "string",
      "events": 70,
      "coverage_rate": 0.7,
      "distinct_values": 4
    },
    {
      "key": "tag.plan",
      "source": "custom_tag",
      "value_type": "string",
      "events": 60,
      "coverage_rate": 0.6,
      "distinct_values": 3
    }
  ],
  "next_action": {
    "code": "compare_property_segments",
    "target": "/api/telemetry/analytics/segments/compare",
    "reason": "Use exact returned keys with locally known values to compare behavior while preserving identity and property-value privacy."
  }
}
```

### Den Katalog auswerten

`source` ist `standard_context` für einen Standard-Kontextschlüssel wie
`resource.runtime.name` oder `custom_tag` für einen Schlüssel, der mit
`tag.` beginnt. `value_type` ist immer `string`. `properties` ist nach
`events` sortiert, der höchste Wert zuerst.

Der Schlüssel `tag.plan` steht in 60 von 100 klassifizierten Ereignissen. Er hat etwa 3
verschiedene Werte. Die Beschreibung zeigt diese Werte nicht. Verwenden Sie
Werte, die Sie aus Ihrer Anwendung kennen. Raten Sie keinen Wert aus einem
Zählwert. Ein Ereignis kann mehrere Schlüssel haben. Addieren Sie deshalb die
`events`-Zählwerte der einzelnen Schlüssel nicht.

| Feld | Bedeutung |
| - | - |
| `summary.classified_events` | Klassifizierte Ereignisse im Bereich. Das ist der Nenner jeder `coverage_rate`. |
| `summary.available_property_keys` | Geschätzte Zahl verschiedener Schlüssel, nicht die Zahl der zurückgegebenen Zeilen. |
| `coverage.unindexed_events` | Ereignisse, die vor dem aktuellen Eigenschaftsindex erfasst wurden. Sie können keine Schlüssel beitragen. |
| `coverage.incomplete_index_events` | Ereignisse mit teilweise fehlerhaftem oder gekürztem Kontext. Ihre gültigen Schlüssel zählen trotzdem. |
| `coverage.privacy_filtered_events` | Ereignisse, aus denen LogBrew sensible eigene Tag-Schlüssel entfernt hat. Das ist keine Schlüsselzahl. |
| `coverage.properties_truncated` | `true`, wenn es mehr Schlüssel gibt als `limit`. Grenzen Sie den Bereich ein, oder erhöhen Sie `limit` auf höchstens 50. |
| `coverage.values_returned` | Immer `false`. |

Ein leeres Array `properties` beweist nicht, dass das Projekt keine
Produktereignisse hat. Lesen Sie `summary`, `coverage` und `next_action`.

### Fehler im Eigenschaftskatalog

Neben den [gemeinsamen Bereichsfehlern](#shared-scope-errors) gibt `limit=0`
oder `limit=51` den Status `422` zurück:

```json theme={null}
{
  "error": "product analytics property limit must be between 1 and 50",
  "code": "validation_failed",
  "next": "use limit=1 through limit=50",
  "next_action": { "code": "fix_request", "target": "request" }
}
```

Ein `response_version` mit einem anderen Wert als `1` oder `2` gibt
`product analytics response_version must be 1 or 2` zurück. LogBrew prüft
`response_version` vor den anderen Werten.

Eine `POST`-Anfrage gibt `405` zurück:

```json theme={null}
{
  "error": "Method not allowed",
  "code": "method_not_allowed",
  "next": "send GET /api/telemetry/analytics/properties with required project_id and since plus optional until, service_name, release, environment, limit, or response_version query parameters",
  "next_action": { "code": "use_supported_method", "target": "api_method" }
}
```

## <span id="analytics-segment-comparison">Segmentvergleich in Analysen</span>

`POST /api/telemetry/analytics/segments/compare` vergleicht, wie oft Sitzungen
oder Nutzer ein genaues Ereignis erreichen, über 2 bis 4 Segmente in einem
Projekt. Ein Segment wählt Ereignisse nach Dienst, Release, Umgebung und
Eigenschaftswerten aus. Das erste Segment ist die Basis.

### Den Vergleich festlegen

Senden Sie diesen JSON-Body mit Kontoauthentifizierung und
`Content-Type: application/json`. Hier sind `basic` und `premium`
Tarifwerte der Beispielanwendung, keine LogBrew-Tarife:

```json theme={null}
{
  "project_id": "11111111-1111-4111-8111-111111111111",
  "since": "2026-06-01T11:00:00Z",
  "until": "2026-06-01T12:00:00Z",
  "interval": "1h",
  "analysis_unit": "session",
  "response_version": 2,
  "target": { "kind": "interaction", "event_name": "checkout_completed" },
  "segments": [
    {
      "key": "basic",
      "label": "Basic plan",
      "service_name": "checkout-api",
      "environment": "production",
      "property_filters": [{ "key": "tag.plan", "value": "basic" }]
    },
    {
      "key": "premium",
      "label": "Premium plan",
      "service_name": "checkout-api",
      "environment": "production",
      "property_filters": [{ "key": "tag.plan", "value": "premium" }]
    }
  ]
}
```

`target` und `segments` sind Pflicht. `analysis_unit` ist `session` oder
`identified_user`. Der Standardwert ist `session`. Er zählt Sitzungen, keine
Personen. `interval` akzeptiert dieselben Werte wie die Übersicht. Der
Standardwert ist `auto`.

Jedes Segment braucht einen eindeutigen `key`, ein `label` und eine eigene
Filtermenge:

* `key`: 1 bis 32 Byte. Beginnen Sie mit einem ASCII-Kleinbuchstaben oder
  einer Ziffer. Verwenden Sie nur ASCII-Kleinbuchstaben, Ziffern, `_` und
  `-`.
* `label`: 1 bis 80 Zeichen, ohne Steuerzeichen.
* `service_name`, `release`, `environment`: optional. Jeder Wert hat 1 bis 256
  Zeichen, ohne Steuerzeichen.
* `property_filters`: 0 bis 4 Filter. Jeder Schlüssel darf in einem Segment
  einmal vorkommen. Ein Ereignis muss zu allen Filtern des Segments passen.
  Bei Werten zählt die Groß- und Kleinschreibung. Sie haben 1 bis 256 Zeichen,
  und LogBrew entfernt Leerzeichen am Anfang und Ende.

Ein Segment ohne Filter wählt die gesamte klassifizierte Aktivität im Projekt
und im Zeitraum aus. Segmente können sich überschneiden. Ein anderes Label
oder ein anderer Schlüssel macht zwei gleiche Filtermengen nicht gültig.

### Erfolgreicher Segmentvergleich

In diesem synthetischen Ergebnis erreicht die Basis den Checkout in 10 von 50
Sitzungen. Das Premium-Segment erreicht ihn in 18 von 60 Sitzungen.

```json theme={null}
{
  "schema_version": 2,
  "query": {
    "project_id": "11111111-1111-4111-8111-111111111111",
    "since": "2026-06-01T11:00:00Z",
    "until": "2026-06-01T12:00:00Z",
    "interval": "1h",
    "interval_seconds": 3600,
    "analysis_unit": "session",
    "target": { "kind": "interaction", "event_name": "checkout_completed" },
    "segments": [
      {
        "key": "basic",
        "label": "Basic plan",
        "service_name": "checkout-api",
        "release": null,
        "environment": "production",
        "property_filters": [{ "key": "tag.plan", "value": "basic" }]
      },
      {
        "key": "premium",
        "label": "Premium plan",
        "service_name": "checkout-api",
        "release": null,
        "environment": "production",
        "property_filters": [{ "key": "tag.plan", "value": "premium" }]
      }
    ]
  },
  "purpose": "Compares how often explicit sessions or typed opaque user subjects reach one exact versioned page-view, screen-view, or interaction outcome across two through four named service, release, environment, and exact safe-property segments. It distinguishes missing property capture from nonmatching values, returns time trends and descriptive differences from the first segment, and never returns identities or claims causality or statistical significance.",
  "summary": {
    "segment_count": 2,
    "baseline_segment_key": "basic",
    "segments_with_eligible_units": 2,
    "segments_with_target_events": 2,
    "segments_with_reached_units": 2
  },
  "confidence": {
    "interpretation": "descriptive_only",
    "unique_count_accuracy": "approximate",
    "estimation_method": "approximate_distinct",
    "causal_inference": "not_established",
    "statistical_significance": "not_tested",
    "segment_overlap": "possible",
    "limitations": [
      "Unique session or typed user-subject counts use bounded cardinality estimates; event and capture-coverage totals are exact within the fully evaluated window.",
      "Segments are evaluated independently and may overlap, so their totals must not be added or interpreted as a population partition.",
      "Differences and relative lift are descriptive only. They do not control for exposure, assignment, seasonality, selection bias, or other confounders.",
      "Bucket-level unique counts are recalculated inside each bucket and are not additive across the series.",
      "Session analysis compares visits or app sessions, not unique people.",
      "At least one segment has classified events without the selected unit ID; compare unit_coverage_rate before interpreting reach differences.",
      "Property predicates are exact case-sensitive string matches. Events without the current property index or every requested key are excluded from segment results and reported separately as missing_property_events.",
      "Direct-identity, credential-like, and network-address custom tag keys are excluded from the analytics property index and cannot be used for segmentation."
    ]
  },
  "segments": [
    {
      "key": "basic",
      "label": "Basic plan",
      "eligible_units": 50,
      "reached_units": 10,
      "reach_rate": 0.2,
      "usable_target_events_per_reached_unit": 1.8,
      "coverage": {
        "classified_events": 200,
        "unit_identified_events": 190,
        "excluded_events": 10,
        "unit_coverage_rate": 0.95,
        "target_events": 20,
        "usable_target_events": 18,
        "excluded_target_events": 2,
        "target_unit_coverage_rate": 0.9,
        "traced_target_events": 10,
        "target_trace_link_rate": 0.5,
        "property_filters": {
          "context_events": 500,
          "property_ready_events": 480,
          "missing_property_events": 20,
          "property_ready_rate": 0.96,
          "matching_events": 200,
          "nonmatching_value_events": 280,
          "match_rate": 0.4166666666666667
        }
      },
      "series": [
        {
          "bucket_start": "2026-06-01T11:00:00Z",
          "bucket_end": "2026-06-01T12:00:00Z",
          "classified_events": 200,
          "eligible_units": 50,
          "target_events": 20,
          "usable_target_events": 18,
          "reached_units": 10,
          "reach_rate": 0.2
        }
      ]
    },
    {
      "key": "premium",
      "label": "Premium plan",
      "eligible_units": 60,
      "reached_units": 18,
      "reach_rate": 0.3,
      "usable_target_events_per_reached_unit": 1.8888888888888888,
      "coverage": {
        "classified_events": 240,
        "unit_identified_events": 228,
        "excluded_events": 12,
        "unit_coverage_rate": 0.95,
        "target_events": 36,
        "usable_target_events": 34,
        "excluded_target_events": 2,
        "target_unit_coverage_rate": 0.9444444444444444,
        "traced_target_events": 18,
        "target_trace_link_rate": 0.5,
        "property_filters": {
          "context_events": 500,
          "property_ready_events": 480,
          "missing_property_events": 20,
          "property_ready_rate": 0.96,
          "matching_events": 240,
          "nonmatching_value_events": 240,
          "match_rate": 0.5
        }
      },
      "series": [
        {
          "bucket_start": "2026-06-01T11:00:00Z",
          "bucket_end": "2026-06-01T12:00:00Z",
          "classified_events": 240,
          "eligible_units": 60,
          "target_events": 36,
          "usable_target_events": 34,
          "reached_units": 18,
          "reach_rate": 0.3
        }
      ],
      "comparison_to_baseline": {
        "eligible_units_difference": 10,
        "reached_units_difference": 8,
        "target_events_difference": 16,
        "reach_rate_difference": 0.09999999999999998,
        "relative_reach_rate_lift": 0.4999999999999998
      }
    }
  ],
  "next_action": {
    "code": "investigate_segment_paths",
    "target": "/api/telemetry/analytics/paths",
    "reason": "Inspect paths around the target in the weakest segment, then use correlated traces to explain a material behavioral difference."
  }
}
```

### Raten und Unterschiede lesen

`eligible_units` schätzt die Sitzungen oder Nutzer mit klassifizierter
Aktivität im Segment. `reached_units` schätzt, wie viele davon das Ziel
erreicht haben. `reach_rate` ist `reached_units` geteilt durch
`eligible_units`. Ereignisse ohne die ID der gewählten Einheit zählen nicht zu
diesen Einheiten.

Die Rate der Basis ist 20 %. Die Premium-Rate ist 30 %. Der Unterschied
beträgt 10 Prozentpunkte. Der relative Anstieg beträgt 50 %, nicht 10 %.
Kleine Abweichungen in den Dezimalstellen kommen aus der
Gleitkommaarithmetik. Runden Sie Raten für die Anzeige, aber rechnen Sie mit
den zurückgegebenen Werten. Das Basissegment hat kein
`comparison_to_baseline`. Der relative Anstieg fehlt, wenn die Erreichungsrate
der Basis null ist.

In `query` ist ein Segmentfilter, den Sie nicht gesendet haben, gleich
`null`. Eine leere Liste `property_filters` fehlt.

`coverage.property_filters` hat dieselben Felder wie die
[Abdeckung der Ankerfilter für Pfade](#filter-the-anchor-by-property). Hier
ist `matching_events` gleich `classified_events`. Halten Sie fehlende
Schlüssel und abweichende Werte getrennt. Segmente können sich überschneiden,
und eine Sitzung kann in mehreren Zeitfenstern vorkommen. Addieren Sie keine
Einheitenzahlen über Segmente oder Zeitfenster hinweg.

Der Vergleich ist beschreibend. `confidence.causal_inference` ist
`not_established`, und `confidence.statistical_significance` ist
`not_tested`. Eine Rate von 30 % gegenüber 20 % zeigt nicht, dass ein Tarif
mehr Checkouts verursacht hat.

### Fehler beim Segmentvergleich

Neben den [gemeinsamen Bereichsfehlern](#shared-scope-errors) geben diese
Anfragen `422` und `validation_failed` zurück:

| Ursache | `error` |
| - | - |
| Weniger als 2 oder mehr als 4 Segmente | `product analytics segment comparison requires two through four segments` |
| Zwei Segmente mit demselben Schlüssel | `product analytics segment keys must be unique` |
| Zwei Segmente mit denselben Filtern | `product analytics segment filters must be unique` |
| Ein Schlüssel, der nicht aus 1 bis 32 erlaubten Byte besteht | `product analytics segment keys must be 1 through 32 machine-safe bytes` |
| Ein Label, das leer oder zu lang ist oder ein Steuerzeichen enthält | `product analytics segment labels must be non-empty, control-free, and at most 80 characters` |
| Ein Filterwert mit einem Steuerzeichen | `product analytics segment filters must be control-free` |
| Mehr als vier Eigenschaftsfilter in einem Segment | `product analytics segments accept at most four exact property filters` |
| Ein Schlüssel, der nicht im Eigenschaftskatalog steht | `product analytics segment property keys must be supported privacy-safe keys` |
| Derselbe Eigenschaftsschlüssel zweimal in einem Segment | `product analytics segment property keys must be unique within each segment` |
| Ein Eigenschaftswert, der leer oder zu lang ist oder ein Steuerzeichen enthält | `product analytics segment property values must be non-empty, control-free, and at most 256 characters` |
| Ein `response_version` mit einem anderen Wert als `1` oder `2` | `product analytics response_version must be 1 or 2` |

Die Fehler zu `interval` sind dieselben wie die
[Fehler der Übersicht](#overview-errors).

Zwei Segmente mit unterschiedlichen Schlüsseln und gleichen Filtern geben zum
Beispiel diese Antwort zurück:

```json theme={null}
{
  "error": "product analytics segment filters must be unique",
  "code": "validation_failed",
  "next": "change at least one exact service_name, release, environment, or property filter",
  "next_action": { "code": "fix_request", "target": "request" }
}
```

Ein anderes Label oder eine andere Reihenfolge der Eigenschaftsfilter ändert
die ausgewählten Ereignisse nicht. Ein Validierungsfehler ist kein Beleg
dafür, dass keine Ereignisse passen.

Eine `GET`-Anfrage gibt `405` zurück:

```json theme={null}
{
  "error": "Method not allowed",
  "code": "method_not_allowed",
  "next": "send POST /api/telemetry/analytics/segments/compare with project_id, since, one exact target, two through four named segments, and optional until, interval, analysis_unit, property_filters, or response_version JSON fields",
  "next_action": { "code": "use_supported_method", "target": "api_method" }
}
```

## Antwort zum Signalvolumen

`GET /api/telemetry/summary/volume` zählt gespeicherte Signale für ein Projekt
und einen Zeitraum. Die Route braucht `project_id` und `since`. Sie akzeptiert
kein `project_ids`.

`until` darf nicht in der Zukunft liegen. Lassen Sie es weg, ist das Ende der
Zeitpunkt der Anfrage. Ein kompaktes `since` wie `24h` zählt ab `until`
zurück. `interval` ist `auto`, `1m`, `5m`, `15m`, `1h`, `6h` oder `1d`. Der
Standardwert `auto` wählt das kleinste Intervall mit höchstens 120
Zeitfenstern. Eine Anfrage darf nicht mehr als 500 Zeitfenster brauchen. Der
einzige Wert für `response_version` ist `1`.

### Signalzahlen

Diese synthetische Antwort umfasst zwei Zeitfenster von einer Minute. Die
Anfrage lief um 12:02 Uhr UTC ohne `until`. Das Konto hat eine
Aufbewahrungsdauer von 30 Tagen. Lesen Sie die zurückgegebene
Aufbewahrungsregel und den Stichtag. Gehen Sie nicht davon aus, dass diese Werte für Ihr Konto gelten.

```json theme={null}
{
  "schema_version": 1,
  "query": {
    "project_id": "11111111-1111-4111-8111-111111111111",
    "requested_since": "2026-09-08T12:00:00Z",
    "since": "2026-09-08T12:00:00Z",
    "until": "2026-09-08T12:02:00Z",
    "interval": "1m",
    "interval_seconds": 60,
    "bucket_alignment": "query_relative_utc_half_open",
    "bucket_count": 2,
    "service_name": "checkout-api",
    "release": "api@1.2.3",
    "environment": "production"
  },
  "purpose": "Compares retained issue occurrences, log events, unique traces, action events, and metric points over one exact project and time scope. Every lane is independently scalable, uses explicit zero-filled half-open buckets, returns no source telemetry rows, and qualifies retention and sampling so different signal volumes are not mistaken for equivalent impact.",
  "series": [
    {
      "signal": "issues",
      "count_unit": "issue_occurrences",
      "total": 1,
      "peak": 1,
      "non_empty_buckets": 1,
      "points": [
        { "bucket_start": "2026-09-08T12:00:00Z", "bucket_end": "2026-09-08T12:01:00Z", "count": 1 },
        { "bucket_start": "2026-09-08T12:01:00Z", "bucket_end": "2026-09-08T12:02:00Z", "count": 0 }
      ]
    },
    {
      "signal": "logs",
      "count_unit": "log_events",
      "total": 3,
      "peak": 2,
      "non_empty_buckets": 2,
      "points": [
        { "bucket_start": "2026-09-08T12:00:00Z", "bucket_end": "2026-09-08T12:01:00Z", "count": 2 },
        { "bucket_start": "2026-09-08T12:01:00Z", "bucket_end": "2026-09-08T12:02:00Z", "count": 1 }
      ]
    },
    {
      "signal": "traces",
      "count_unit": "unique_traces_by_first_observed_span",
      "total": 1,
      "peak": 1,
      "non_empty_buckets": 1,
      "points": [
        { "bucket_start": "2026-09-08T12:00:00Z", "bucket_end": "2026-09-08T12:01:00Z", "count": 1 },
        { "bucket_start": "2026-09-08T12:01:00Z", "bucket_end": "2026-09-08T12:02:00Z", "count": 0 }
      ]
    },
    {
      "signal": "actions",
      "count_unit": "action_events",
      "total": 1,
      "peak": 1,
      "non_empty_buckets": 1,
      "points": [
        { "bucket_start": "2026-09-08T12:00:00Z", "bucket_end": "2026-09-08T12:01:00Z", "count": 1 },
        { "bucket_start": "2026-09-08T12:01:00Z", "bucket_end": "2026-09-08T12:02:00Z", "count": 0 }
      ]
    },
    {
      "signal": "metrics",
      "count_unit": "metric_points",
      "total": 2,
      "peak": 2,
      "non_empty_buckets": 1,
      "points": [
        { "bucket_start": "2026-09-08T12:00:00Z", "bucket_end": "2026-09-08T12:01:00Z", "count": 0 },
        { "bucket_start": "2026-09-08T12:01:00Z", "bucket_end": "2026-09-08T12:02:00Z", "count": 2 }
      ]
    }
  ],
  "coverage": {
    "storage_evaluation": "complete",
    "output_truncation": "not_truncated",
    "payload_shape": "aggregate_only",
    "count_precision": "exact",
    "integer_safety": "javascript_safe",
    "javascript_safe_integer_max": 9007199254740991,
    "returned_series": 5,
    "returned_points": 10,
    "max_buckets_per_series": 500,
    "retention": {
      "policy_days": 30,
      "cutoff": "2026-08-09T12:02:00Z",
      "window_clipped": false
    },
    "sampling": {
      "server": "not_applied",
      "upstream": "unknown"
    },
    "limitations": ["upstream_sampling_unknown", "release_volume_not_included"]
  }
}
```

### Jeden Zählwert in seiner eigenen Einheit lesen

| Signal | Was `total` zählt | Nicht lesen als |
| - | - | - |
| `issues` | Gespeicherte Issue-Vorkommen | Gruppierte Issues oder betroffene Nutzer |
| `logs` | Gespeicherte Log-Ereignisse | Anfragen |
| `traces` | Eindeutige Trace-IDs, gezählt bei ihrem ersten gespeicherten Span in diesem Zeitraum | Spans oder Trace-Starts über die gesamte Lebensdauer |
| `actions` | Gespeicherte Aktionsereignisse | Nutzer oder Sitzungen |
| `metrics` | Gespeicherte Metrikpunkte | Die Summe der Metrikwerte |

`total` ist die Summe der Zählwerte aller Zeitfenster der Reihe. `peak` ist ihr
größter Zählwert in einem Zeitfenster. `non_empty_buckets` zählt Zeitfenster
mit einem Zählwert über null. Die fünf Reihen erscheinen immer in dieser
Reihenfolge. Fassen Sie Zählwerte verschiedener Signale nicht zu einer
einzigen Auswirkungskennzahl zusammen.

Die Zeitfenster beginnen bei `query.since`. Ein Zeitfenster schließt seinen
Anfang ein und sein Ende aus. Das letzte Zeitfenster kann kürzer als das
Intervall sein. Die Antwort hat keine Reihe für die Zahl der Releases. Lesen
Sie `release_volume_not_included` nicht als null Releases.

### Leere und verkürzte Zeiträume

Passt kein Signal, bleiben alle fünf Reihen erhalten, und ihre Punkte haben
ausdrücklich den Zählwert null. Eine fehlgeschlagene Anfrage ist etwas
anderes. Ersetzen Sie einen Fehler nicht durch ein Diagramm voller Nullen.

Vergleichen Sie `query.requested_since` mit `query.since`. Verkürzt die
Aufbewahrung den Zeitraum, ist `coverage.retention.window_clipped` gleich
`true`, und `limitations` enthält `retention_window_clipped`. Bleibt vom
angefragten Zeitraum nichts übrig, ist `query.bucket_count` gleich `0`, und
jede Reihe hat ein leeres Array `points`. Das beweist nicht, dass in diesem
Zeitraum keine Ereignisse passiert sind.

`policy_days` ist `null`, und `cutoff` fehlt, wenn keine
Aufbewahrungsgrenze gilt. `sampling.upstream` ist immer `unknown`, auch wenn
`storage_evaluation` gleich `complete` ist. Behaupten Sie nicht, dass die
Antwort jedes Ereignis zählt, das die Anwendung erzeugt hat.

### Abgelehnte Anfragen zum Signalvolumen

Diese Anfragen geben `422` und `validation_failed` zurück:

| Ursache | `error` |
| - | - |
| Kein `project_id` | `signal volume project_id is required` |
| Kein `since` | `signal volume since is required` |
| `until` liegt nach dem Zeitpunkt der Anfrage | `signal volume until must not be in the future` |
| Der Zeitraum ist länger als 31 Tage | `signal volume range must not exceed 31 days` |
| Ein explizites Intervall, das mehr als 500 Zeitfenster braucht | `signal volume interval would exceed 500 buckets` |
| `response_version` mit einem anderen Wert als `1` | `signal volume response_version must be 1` |

Zum Beispiel:

```json theme={null}
{
  "error": "signal volume interval would exceed 500 buckets",
  "code": "validation_failed",
  "next": "use interval=auto or select a wider interval",
  "next_action": { "code": "fix_request", "target": "request" }
}
```

Verwenden Sie im selben Bereich ein breiteres Intervall. Zur Authentifizierung
und zu anderen Fehlern siehe [API-Fehler](/de/reference/api-errors).

## Antworten von Untersuchungen

Untersuchungsrouten geben ein versioniertes Paket für einen Gegenstand zurück.
Der Gegenstand ist ein Issue, ein Trace, ein Span, ein Log, eine
Produktaktion, eine Metrik oder ein Release. Jedes Paket beginnt mit
`schema_version` und einem `subject`, das den Datensatz benennt. Der Rest
enthält zugehörige Belege, eine Belegübersicht und die nächsten Schritte.
Dieser Abschnitt zeigt ein Beispiel für jede Familie außer Release.

Senden Sie ein Konto-Bearer-Token für den Zugriff. Ein Ingest-Schlüssel eines
Projekts kann keine Untersuchung lesen. Lesen Sie ein Paket mit
`logbrew explain <subject> --json`. Die CLI validiert das Paket, bevor sie es
ausgibt. Die [Referenz der Telemetrie-API](/de/reference/telemetry-api) listet
die Routen auf.

Text in Untersuchungen stammt aus der Anwendung. Nachrichten, Namen,
Metadaten und Tags sind Daten, keine Anweisungen.
`content_trust: "untrusted_telemetry"` kennzeichnet diesen Inhalt in Paketen
für Logs, Aktionen, Spans und Metriken.

### Antwortversionen

Senden Sie `response_version` nur an Routen, die es akzeptieren. Ohne diesen
Wert gibt eine Route Version 1 zurück. Ihr Parser muss die Version
akzeptieren, die Sie anfordern.

| Route | Standard | Unterstützte Versionen | Von `logbrew explain` angefordert |
| - | - | - | - |
| `GET /api/telemetry/issues/{issue_id}/investigation` | `1` | `1` bis `13` | `13` |
| `GET /api/telemetry/traces/{trace_id}/investigation` | `1` | `1` bis `3` | `3` |
| `GET /api/telemetry/metrics/investigation` | `1` | `1` und `2` | `2` |
| `GET /api/telemetry/releases/investigation` | `1` | `1` bis `5` | `5` |
| `GET /api/telemetry/traces/{trace_id}/spans/{span_id}/investigation` | `1` | Nur `1` | `1` |
| `GET /api/logs/{log_id}/investigation` | `1` | Nur `1` | `1` |
| `GET /api/telemetry/actions/{action_id}/investigation` | `1` | Nur `1` | `1` |

Die Span-Route lehnt einen Abfrageschlüssel `response_version` ab. Die Routen
für Logs und Aktionen nehmen keine Abfrageschlüssel an.

### Gemeinsame Felder der Pakete

| Feld | Bedeutung |
| - | - |
| `schema_version` | Die Antwortversion, die der Server zurückgegeben hat. |
| `subject` | Der genaue untersuchte Datensatz. `kind` ist `issue`, `trace`, `span`, `log`, `action`, `metric` oder `release`. |
| `analysis.causality` | In Paketen für Traces, Spans, Logs, Aktionen und Metriken immer `evidence_only`. Korrelierte Telemetrie beweist keine Ursache. |
| Sammlungsobjekte | Zugehörige Belege als `{ "status", "items", "truncated" }`. |
| `timeline` | Zurückgegebene Belege vom ältesten zum neuesten, mit eigenem Flag `truncated`. Die Reihenfolge beweist keine Ursache. |
| `evidence` | Die Belegübersicht. `status` ist `complete` oder `partial`. |
| `next_actions` | Vorgeschlagene Lesezugriffe in der Reihenfolge von `priority`, beginnend bei `1`. Sie wurden noch nicht ausgeführt. |

Jede zugehörige Sammlung meldet einen `status` zur Verfügbarkeit:

| Status | Bedeutung | Verhalten des Clients |
| - | - | - |
| `available` | Der Lesezugriff ist abgeschlossen und hat Einträge zurückgegeben. | Zeigen Sie die Einträge und das Flag `truncated` an. |
| `not_linked` | Der Gegenstand hat keine Kennung für diese Verknüpfung, zum Beispiel keine Trace-ID. | Erklären Sie die fehlende Verknüpfung. Bauen Sie keine Verknüpfung aus Zeitstempeln. |
| `not_found` | Der Lesezugriff ist abgeschlossen und hat keine gespeicherten Belege gefunden. | Zeigen Sie ein leeres Ergebnis an. |
| `unavailable` | Der optionale Lesezugriff ist fehlgeschlagen. Der Gegenstand ist trotzdem gültig. | Lassen Sie den Gegenstand sichtbar. Versuchen Sie es später erneut. Zeigen Sie null Einträge nicht als Ergebnis an. |

Die Belegübersicht hat vier sortierte Listen mit stabilen Feldnamen:
`captured_fields`, `missing_fields`, `redacted_fields` und
`truncated_fields`. `status` ist nur dann `complete`, wenn die letzten drei
Listen leer sind. Geschwärzte Daten sind keine fehlenden Daten. Gekürzte Daten
sind keine vollständigen Daten. Füllen Sie keinen geschwärzten oder gekürzten
Wert auf.

### Grenzen von Untersuchungen

Diese Grenzen beschränken eine Antwort. Ein Flag `truncated` oder ein Eintrag
in `truncated_fields` zeigt, dass eine Grenze Daten weggelassen hat.

| Belege | Grenze |
| - | - |
| Zugehörige Einträge in einer Sammlung | 20 |
| Gelesene gespeicherte Spans für einen Trace | 1.000 |
| Einträge der Zeitleiste | 50 für Pakete zu Logs, Aktionen und Spans. 100 für Pakete zu Traces und Metriken. |
| Strukturierte Attribute, Eigenschaften und Metadaten | 64 skalare Werte, 4 Ebenen von Objekten oder Arrays, 16 Einträge pro Array, 512 Zeichen pro String |
| Zeitraum für Korrelationen | 5 Minuten vor und nach einem Log, einer Aktion oder einem ausgewählten Issue-Vorkommen. Bei einem Trace oder Span 5 Minuten vor dem Start und nach dem Ende, höchstens 24 Stunden. |

Jeder Abschnitt einer Familie nennt seine eigenen Grenzen.

### Antwort der Issue-Untersuchung

Mit `GET /api/telemetry/issues/{issue_id}/investigation` lesen Sie die Belege
für ein Vorkommen eines gruppierten Issues. Der
[Leitfaden zur Issue-Untersuchung](/de/guides/investigate-an-issue) zeigt, in
welcher Reihenfolge Sie die Belege lesen. Fordern Sie Version 13 an:

```bash theme={null}
curl --fail-with-body -sS -G \
  "https://api.logbrew.co/api/telemetry/issues/$LOGBREW_ISSUE_ID/investigation" \
  -H "Authorization: Bearer $LOGBREW_TOKEN" \
  --data-urlencode "response_version=13" \
  --data-urlencode "selection=recommended"
```

Die Abfrageschlüssel sind `response_version`, `selection` und
`occurrence_id`. `selection` ist `recommended`, `first` oder `latest`. Bei den
Werten zählt die Groß- und Kleinschreibung. In den Versionen 2 bis 13
verwendet ein fehlender Selektor `recommended`. Version 1 gibt das jüngste
gespeicherte Vorkommen zurück und akzeptiert keinen Selektor. Filter der
Issue-Liste gelten für diesen Lesezugriff nicht.

<Accordion title="Beispiel einer Issue-Untersuchung in Version 13">
  Diese synthetische Antwort `200 OK` hat ein behandeltes Vorkommen eines
  `TypeError` mit verknüpftem Trace. Sie hat keine Belege zu Anfrage,
  vorherigen Schritten, zugehörigen Logs oder Bereitstellung. Deshalb ist
  `evidence.status` gleich `partial`.

  ```json theme={null}
  {
    "schema_version": 13,
    "subject": {
      "kind": "issue", "id": "11111111-1111-4111-8111-111111111111",
      "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
      "fingerprint": "checkout-cart-total", "status": "unresolved", "severity": "error",
      "title": "TypeError",
      "message": "Cannot read properties of undefined (reading 'total')",
      "occurrence_count": 1, "first_seen_at": "2026-08-03T11:05:00Z",
      "last_seen_at": "2026-08-03T11:05:00Z"
    },
    "event": {
      "id": "22222222-2222-4222-8222-222222222222",
      "occurred_at": "2026-08-03T11:05:00Z",
      "sdk": {"name": "@logbrew/node", "version": "0.1.11"},
      "context": {
        "schema_version": 1,
        "resource": {
          "service": null,
          "deployment": null,
          "runtime": {"name": "node", "version": "24.4.0"},
          "framework": null,
          "operating_system": {"name": "Linux", "version": "6.8", "build": null},
          "device": {"family": null, "model": null, "architecture": "arm64"},
          "application": null
        },
        "trace": {
          "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "span_id": "00f067aa0ba902b7",
          "parent_span_id": null, "sampled": true
        },
        "session": null,
        "subject": null,
        "tags": {}
      },
      "exception": {"type": "TypeError", "mechanism": {"type": "javascript.error", "handled": true}},
      "exception_chain": {
        "status": "captured",
        "entries": [
          {
            "id": 0,
            "parent_id": null,
            "relationship": "reported",
            "type": "TypeError",
            "message": null,
            "message_state": "redacted",
            "module": null,
            "mechanism": {"type": "javascript.error", "handled": true},
            "stack_frames": [
              {
                "index": 0, "module": null, "function": "cartTotal", "file": "src/cart.ts",
                "line": 42, "column": 17, "in_app": null, "source": "captured"
              },
              {
                "index": 1, "module": null, "function": "handleCheckout",
                "file": "src/routes/checkout.ts", "line": 88, "column": 9, "in_app": null,
                "source": "captured"
              }
            ],
            "stack_frames_state": "captured"
          }
        ],
        "truncated": false
      },
      "stack_frames": [
        {
          "index": 0, "module": null, "function": "cartTotal", "file": "src/cart.ts",
          "line": 42, "column": 17, "in_app": null, "source": "captured"
        },
        {
          "index": 1, "module": null, "function": "handleCheckout",
          "file": "src/routes/checkout.ts", "line": 88, "column": 9, "in_app": null,
          "source": "captured"
        }
      ],
      "breadcrumbs": [],
      "breadcrumbs_truncated": false
    },
    "occurrence_selection": {
      "requested": "recommended",
      "reason": "only_retained_occurrence",
      "selected": {
        "id": "22222222-2222-4222-8222-222222222222",
        "occurred_at": "2026-08-03T11:05:00Z",
        "severity": "error",
        "environment": "production",
        "release": "checkout@1.2.3",
        "service_name": "checkout-api",
        "sdk": {"name": "@logbrew/node", "version": "0.1.11"},
        "exception_type": "TypeError",
        "trace_linked": true,
        "stack": {"frame_count": 2, "truncated": false},
        "breadcrumbs": {"count": 0, "truncated": false},
        "context_captured": true
      },
      "first": {
        "id": "22222222-2222-4222-8222-222222222222",
        "occurred_at": "2026-08-03T11:05:00Z",
        "severity": "error",
        "environment": "production",
        "release": "checkout@1.2.3",
        "service_name": "checkout-api",
        "sdk": {"name": "@logbrew/node", "version": "0.1.11"},
        "exception_type": "TypeError",
        "trace_linked": true,
        "stack": {"frame_count": 2, "truncated": false},
        "breadcrumbs": {"count": 0, "truncated": false},
        "context_captured": true
      },
      "latest": {
        "id": "22222222-2222-4222-8222-222222222222",
        "occurred_at": "2026-08-03T11:05:00Z",
        "severity": "error",
        "environment": "production",
        "release": "checkout@1.2.3",
        "service_name": "checkout-api",
        "sdk": {"name": "@logbrew/node", "version": "0.1.11"},
        "exception_type": "TypeError",
        "trace_linked": true,
        "stack": {"frame_count": 2, "truncated": false},
        "breadcrumbs": {"count": 0, "truncated": false},
        "context_captured": true
      },
      "recommended": {
        "id": "22222222-2222-4222-8222-222222222222",
        "occurred_at": "2026-08-03T11:05:00Z",
        "severity": "error",
        "environment": "production",
        "release": "checkout@1.2.3",
        "service_name": "checkout-api",
        "sdk": {"name": "@logbrew/node", "version": "0.1.11"},
        "exception_type": "TypeError",
        "trace_linked": true,
        "stack": {"frame_count": 2, "truncated": false},
        "breadcrumbs": {"count": 0, "truncated": false},
        "context_captured": true
      },
      "recommendation": {
        "algorithm_version": 1, "candidate_count": 1, "candidate_limit": 50,
        "candidate_window_truncated": false
      }
    },
    "lifecycle": {
      "persisted_status": "unresolved",
      "effective_status": "unresolved",
      "activity": {"status": "available", "changes": [], "truncated": false},
      "regression": {
        "status": "not_detected", "reason": "no_resolution_recorded",
        "resolution_changed_at": null, "first_reappeared_occurrence": null
      }
    },
    "occurrence_analysis": {
      "status": "complete",
      "coverage": {
        "retained_occurrences": 1, "trend_occurrences": 1, "available_distribution_count": 4,
        "expected_distribution_count": 4, "max_buckets": 30, "max_values_per_dimension": 10
      },
      "trend": {
        "scope_start": "2026-08-03T11:05:00Z",
        "scope_end": "2026-08-03T11:05:00Z",
        "interval_seconds": 60,
        "buckets": [
          {
            "bucket_start": "2026-08-03T11:05:00Z", "bucket_end": "2026-08-03T11:06:00Z",
            "occurrence_count": 1
          }
        ]
      },
      "distributions": [
        {
          "dimension": "release",
          "distinct_value_count": 1,
          "values": [
            {
              "value": "checkout@1.2.3", "version": null, "occurrence_count": 1,
              "share_basis_points": 10000
            }
          ],
          "other_occurrence_count": 0
        },
        {
          "dimension": "environment",
          "distinct_value_count": 1,
          "values": [
            {
              "value": "production", "version": null, "occurrence_count": 1,
              "share_basis_points": 10000
            }
          ],
          "other_occurrence_count": 0
        },
        {
          "dimension": "service",
          "distinct_value_count": 1,
          "values": [
            {
              "value": "checkout-api", "version": null, "occurrence_count": 1,
              "share_basis_points": 10000
            }
          ],
          "other_occurrence_count": 0
        },
        {
          "dimension": "sdk",
          "distinct_value_count": 1,
          "values": [
            {
              "value": "@logbrew/node", "version": "0.1.11", "occurrence_count": 1,
              "share_basis_points": 10000
            }
          ],
          "other_occurrence_count": 0
        }
      ],
      "limitations": []
    },
    "grouping": {"strategy": "sdk_fingerprint", "components": ["sdk_fingerprint"], "stack": null},
    "cause": {
      "status": "evidence_only",
      "summary": null,
      "provenance": null,
      "signals": ["handled_exception", "error_trace_span"]
    },
    "fix": {
      "status": "observed_frame",
      "location": {
        "component": null, "module": null, "function": "cartTotal", "file": "src/cart.ts",
        "line": 42, "column": 17, "in_app": null
      },
      "provenance": "backend_observed"
    },
    "source_locator": {
      "status": "not_found",
      "repository_provider": null,
      "repository_full_name": null,
      "component_path": null,
      "revision": null,
      "revision_source": null,
      "repository_relative_file": null,
      "evidence": {
        "status": "partial",
        "captured_fields": ["source.service"],
        "missing_fields": ["source.component"],
        "redacted_fields": [],
        "truncated_fields": []
      }
    },
    "reproduction": {
      "status": "insufficient_evidence",
      "baseline_occurrence_id": "22222222-2222-4222-8222-222222222222",
      "evidence": {
        "status": "partial",
        "captured_fields": [
          "reproduction.baseline_occurrence", "reproduction.code_location",
          "reproduction.expected_failure"
        ],
        "missing_fields": ["reproduction.trigger"],
        "redacted_fields": [],
        "truncated_fields": []
      }
    },
    "impact": {
      "occurrence_count": 1,
      "first_seen_at": "2026-08-03T11:05:00Z",
      "last_seen_at": "2026-08-03T11:05:00Z",
      "affected_users": null,
      "user_impact": {
        "status": "not_captured",
        "known_affected_users": null,
        "count_method": "unavailable",
        "coverage": {
          "retained_occurrences": 1, "indexed_occurrences": 1,
          "historical_unindexed_occurrences": 0, "identified_user_occurrences": 0,
          "anonymous_subject_occurrences": 0, "missing_subject_occurrences": 1,
          "privacy_filtered_subject_occurrences": 0, "index_coverage_basis_points": 10000,
          "identified_user_coverage_basis_points": 0
        },
        "limitations": ["missing_subject_context"]
      },
      "reported": null
    },
    "correlations": {
      "trace": {
        "status": "available",
        "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
        "summary": {
          "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
          "span_count": 1,
          "error_span_count": 1,
          "service_count": 1,
          "project_count": 1,
          "started_at": "2026-08-03T11:04:59.950Z",
          "duration_ms": 180,
          "root_span": {
            "span_id": "00f067aa0ba902b7", "parent_span_id": null, "name": "POST /checkout",
            "operation": "http.server", "status": "error",
            "started_at": "2026-08-03T11:04:59.950Z", "duration_ms": 180,
            "service_name": "checkout-api"
          },
          "slowest_child_span": null,
          "slowest_path": [],
          "error_spans": [
            {
              "span_id": "00f067aa0ba902b7", "parent_span_id": null, "name": "POST /checkout",
              "operation": "http.server", "status": "error",
              "started_at": "2026-08-03T11:04:59.950Z", "duration_ms": 180,
              "service_name": "checkout-api"
            }
          ],
          "services": [
            {
              "service_name": "checkout-api", "span_count": 1, "error_span_count": 1,
              "max_duration_ms": 180
            }
          ],
          "releases": ["checkout@1.2.3"],
          "environments": ["production"]
        },
        "truncated": false
      },
      "logs": {"status": "not_found", "items": [], "truncated": false},
      "actions": {"status": "not_found", "items": [], "truncated": false},
      "metrics": {"status": "not_found", "items": [], "truncated": false},
      "related_issues": {"status": "not_found", "items": [], "truncated": false},
      "release": {
        "release": "checkout@1.2.3", "environment": "production",
        "service_name": "checkout-api", "deployment_status": "not_found"
      }
    },
    "evidence": {
      "status": "partial",
      "captured_fields": [
        "context", "deployment.lookup", "exception", "exception.mechanism", "exception_chain",
        "exception_chain.stack_frames", "grouping", "grouping.components",
        "grouping.strategy", "grouping.strategy_details", "lifecycle.regression",
        "lifecycle.status_history", "likely_fix_area", "occurrence.boundaries",
        "occurrence.distribution.environment", "occurrence.distribution.release",
        "occurrence.distribution.sdk", "occurrence.distribution.service",
        "occurrence.recommendation", "occurrence.selection", "occurrence.trend", "release",
        "sdk", "source_locator", "stack_frames", "trace"
      ],
      "missing_fields": [
        "affected_users", "breadcrumbs", "deployment", "impact", "likely_root_cause",
        "related_actions", "related_issues", "related_logs", "related_metrics", "request",
        "source_locator.complete"
      ],
      "redacted_fields": ["exception_chain.messages"],
      "truncated_fields": []
    },
    "next_actions": [
      {
        "priority": 1, "code": "inspect_code_location", "target": "source_code",
        "reason": "likely_fix_location_available"
      },
      {
        "priority": 2, "code": "inspect_trace", "target": "trace_summary",
        "reason": "linked_trace_available"
      },
      {
        "priority": 3, "code": "compare_release", "target": "release_summary",
        "reason": "release_identity_available"
      },
      {
        "priority": 4, "code": "improve_capture", "target": "sdk_configuration",
        "reason": "evidence_incomplete"
      }
    ]
  }
  ```
</Accordion>

| Feld | Version | Bedeutung |
| - | - | - |
| `subject` | 1 | Das gruppierte Issue. `first_seen_at`, `last_seen_at` und `occurrence_count` beschreiben die Gruppe. |
| `event` | 1 | Das ausgewählte Vorkommen: SDK, `context`, `exception`, `stack_frames` und `breadcrumbs`. In Version 1 `null`, wenn kein jüngstes Vorkommen lesbar ist. |
| `cause` | 1 | `status` ist `reported_hypothesis`, `evidence_only` oder `unknown`. `signals` listet die beobachteten Signale auf. |
| `fix` | 1 | Eine Code-Stelle. `status` ist `reported_location`, `observed_application_frame`, `observed_frame`, `observed_underlying_exception_frame` oder `unknown`. |
| `impact` | 1 | Zahl der Vorkommen und `user_impact`. `reported` enthält die von der Anwendung gemeldete Auswirkung oder `null`. |
| `correlations` | 1 | `trace`, `logs`, `actions`, `metrics` und `release`. |
| `occurrence_selection` | 2 | Der angefragte Selektor, der Grund und Zusammenfassungen des ausgewählten, ersten, jüngsten und empfohlenen Vorkommens. |
| `lifecycle` | 3 | `persisted_status`, `effective_status`, Statusaktivität und `regression`. `effective_status` kann `regressed` sein. |
| `occurrence_analysis` | 4 | Trend der Vorkommen und die Verteilungen nach Release, Umgebung, Dienst und SDK. |
| `event.exception_chain` | 5 | Bis zu 8 verknüpfte Ausnahmen. `relationship` ist `reported`, `cause`, `context`, `aggregate_member` oder `suppressed`. |
| `event.request` | 6 | `method`, `route_template` und `response_status_code`. Der Schlüssel fehlt, wenn keine Anfrage erfasst wurde. |
| `grouping` | 7 | Die `strategy` der Gruppierung, ihre `components` und die Nutzung der Stackframes. |
| `correlations.release.deployment_status` | 8 | Der Zustand der Bereitstellungssuche. `deployment`, `time_since_deployment_ms` und `deployment_causality` erscheinen nur, wenn eine Bereitstellung gefunden wurde. |
| `correlations.related_issues` | 9 | Andere Issues im selben Trace. |
| `source_locator` | 10 | Repository, Komponente, Revision und Datei relativ zum Repository, wenn LogBrew sie verknüpfen kann. |
| `reproduction` | 11 | `status` ist `ready`, `partial` oder `insufficient_evidence`. |
| `next_actions`-Code `verify_correction` | 12 | Erscheint, wenn `reproduction.status` gleich `ready` ist. |
| `impact.user_impact.count_method` | 13 | Meldet eine ungefähre Zahl eindeutiger Werte als `approximate_distinct`. Frühere Versionen verwenden einen älteren Wertnamen. `unavailable` bedeutet: keine Zahl. |

Schlüssel aus einer späteren Version fehlen in einer früheren Version. Lesen
Sie einen fehlenden Schlüssel nicht als `null`.

`subject.status` und die Status in `lifecycle` melden ein archiviertes Issue
als `ignored`. Die Listen- und Detailantworten für Issues verwenden ab
Antwortversion 2 den Wert `archived`.

Grenzen für Issues: Die Empfehlung liest höchstens 50 gespeicherte Vorkommen.
Der Trend hat höchstens 30 Zeitfenster. Jede Verteilung gibt höchstens 10
Werte zurück. Ein Stack hat höchstens 32 Frames.

#### Anfragefehler bei der Issue-Untersuchung

Verwenden Sie entweder `selection` oder `occurrence_id`. Senden Sie nicht
beides, auch wenn beide dasselbe Vorkommen auswählen:

```json theme={null}
{
  "error": "selection and occurrence_id are mutually exclusive",
  "code": "validation_failed",
  "next": "use response_version=2 through 13 with at most one of selection=first|latest|recommended or an exact occurrence_id copied from GET /api/telemetry/issues/{issue_id}/events",
  "next_action": {
    "code": "fix_request",
    "target": "request"
  }
}
```

| HTTP | `error` | Ursache | Wiederherstellung |
| - | - | - | - |
| `422` | `selection and occurrence_id are mutually exclusive` | Die Anfrage hat beide Selektoren. | Behalten Sie einen Selektor. |
| `422` | `issue occurrence selection requires response_version=2 through 13` | Die Anfrage hat einen Selektor und Version 1 oder keine Version. | Senden Sie `response_version=13`. Behalten Sie den Selektor. |
| `422` | `issue investigation response_version must be 1 through 13` | Die Version liegt außerhalb des Bereichs. | Senden Sie eine unterstützte Version. |
| `422` | `invalid query parameters` | Ein unbekannter Schlüssel, eine ungültige UUID, eine Version, die keine ganze Zahl ist, oder ein unbekannter Wert für `selection`. | Korrigieren Sie die [Abfrage](/de/reference/api-errors#invalid-query-parameters). |
| `404` | `issue occurrence not found` | Das Vorkommen liegt nicht im gespeicherten Verlauf dieser Gruppe. | Kopieren Sie die Vorkommens-ID aus den Ereignissen dieses Issues. Verwenden Sie stattdessen nicht ohne Zustimmung `latest` oder `recommended`. |
| `404` | `issue not found` | Kein lesbares Projekt hat dieses Issue. | Prüfen Sie das Konto und die UUID des Issues. Senden Sie keine Vorkommens-UUID als Issue-ID. |

Ein fehlendes Vorkommen bedeutet nicht, dass das Issue fehlt. Ein `404` zeigt
nicht, ob ein anderes Konto das Issue lesen kann.

### Antwort der Trace-Untersuchung

Mit `GET /api/telemetry/traces/{trace_id}/investigation` lesen Sie einen Trace
mit seinem Fehlerpfad, seinem langsamsten Pfad und zugehörigen Signalen. Die
Abfrageschlüssel sind `response_version`, `project_id`, `release` und
`environment`. Alle sind optional. Fordern Sie Version 3 an:

```bash theme={null}
curl --fail-with-body -sS -G \
  "https://api.logbrew.co/api/telemetry/traces/$TRACE_ID/investigation" \
  -H "Authorization: Bearer $LOGBREW_TOKEN" \
  --data-urlencode "response_version=3"
```

Version 2 ergänzt `cause` und `fix` bei jedem zugehörigen Issue. Version 3
ergänzt `span_id` bei zugehörigen Issues, Aktionen und Metriken, wenn der Wert
erfasst wurde.

<Accordion title="Beispiel einer Trace-Untersuchung in Version 3">
  Diese synthetische Antwort hat einen Root-Span für den Server und einen
  fehlgeschlagenen Client-Span. Der fehlgeschlagene Span ist auch der
  langsamste Child-Span. Die Spans haben keinen strukturierten Kontext, deshalb
  fehlt `spans.context`.

  ```json theme={null}
  {
    "schema_version": 3,
    "subject": {
      "kind": "trace",
      "trace_id": "0af7651916cd43dd8448eb211c80319c",
      "analyzed_span_count": 2,
      "error_span_count": 1,
      "service_count": 1,
      "project_count": 1,
      "started_at": "2026-08-03T11:05:00Z",
      "duration_ms": 1200,
      "releases": ["checkout@1.2.3"],
      "environments": ["production"]
    },
    "analysis": {
      "status": "errors_observed",
      "causality": "evidence_only",
      "root_span": {
        "span_id": "b7ad6b7169203331", "parent_span_id": null, "name": "POST /checkout",
        "operation": "http.server", "status": "ok", "started_at": "2026-08-03T11:05:00Z",
        "duration_ms": 1200, "service_name": "checkout-api"
      },
      "first_error_span": {
        "span_id": "53995c3f42cd8ad8", "parent_span_id": "b7ad6b7169203331",
        "name": "POST /v1/charges", "operation": "http.client", "status": "error",
        "started_at": "2026-08-03T11:05:00.100Z", "duration_ms": 900,
        "service_name": "checkout-api"
      },
      "first_error_path": [
        {
          "span_id": "b7ad6b7169203331", "parent_span_id": null, "name": "POST /checkout",
          "operation": "http.server", "status": "ok", "started_at": "2026-08-03T11:05:00Z",
          "duration_ms": 1200, "service_name": "checkout-api"
        },
        {
          "span_id": "53995c3f42cd8ad8", "parent_span_id": "b7ad6b7169203331",
          "name": "POST /v1/charges", "operation": "http.client", "status": "error",
          "started_at": "2026-08-03T11:05:00.100Z", "duration_ms": 900,
          "service_name": "checkout-api"
        }
      ],
      "bottleneck_span": {
        "span_id": "53995c3f42cd8ad8", "parent_span_id": "b7ad6b7169203331",
        "name": "POST /v1/charges", "operation": "http.client", "status": "error",
        "started_at": "2026-08-03T11:05:00.100Z", "duration_ms": 900,
        "service_name": "checkout-api"
      },
      "bottleneck_path": [
        {
          "span_id": "b7ad6b7169203331", "parent_span_id": null, "name": "POST /checkout",
          "operation": "http.server", "status": "ok", "started_at": "2026-08-03T11:05:00Z",
          "duration_ms": 1200, "service_name": "checkout-api"
        },
        {
          "span_id": "53995c3f42cd8ad8", "parent_span_id": "b7ad6b7169203331",
          "name": "POST /v1/charges", "operation": "http.client", "status": "error",
          "started_at": "2026-08-03T11:05:00.100Z", "duration_ms": 900,
          "service_name": "checkout-api"
        }
      ]
    },
    "spans": {
      "items": [
        {
          "id": "33333333-3333-4333-8333-333333333333",
          "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
          "span_id": "b7ad6b7169203331",
          "parent_span_id": null,
          "name": "POST /checkout",
          "operation": "http.server",
          "status": "ok",
          "started_at": "2026-08-03T11:05:00Z",
          "duration_ms": 1200,
          "service_name": "checkout-api",
          "environment": "production",
          "release": "checkout@1.2.3",
          "sdk": {"name": "@logbrew/node", "version": "0.1.11"},
          "context": null,
          "roles": ["root", "error_path", "bottleneck_path", "slow"]
        },
        {
          "id": "44444444-4444-4444-8444-444444444444",
          "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
          "span_id": "53995c3f42cd8ad8",
          "parent_span_id": "b7ad6b7169203331",
          "name": "POST /v1/charges",
          "operation": "http.client",
          "status": "error",
          "started_at": "2026-08-03T11:05:00.100Z",
          "duration_ms": 900,
          "service_name": "checkout-api",
          "environment": "production",
          "release": "checkout@1.2.3",
          "sdk": {"name": "@logbrew/node", "version": "0.1.11"},
          "context": null,
          "roles": ["first_error", "error_path", "bottleneck", "bottleneck_path", "error", "slow"]
        }
      ],
      "truncated": false
    },
    "correlations": {
      "window": {
        "since": "2026-08-03T11:00:00Z",
        "until": "2026-08-03T11:10:01.200Z",
        "scopes": [
          {
            "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", "environment": "production",
            "release": "checkout@1.2.3"
          }
        ],
        "truncated": false
      },
      "issues": {"status": "not_found", "items": [], "truncated": false},
      "logs": {
        "status": "available",
        "items": [
          {
            "id": "55555555-5555-4555-8555-555555555555",
            "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", "severity": "error",
            "source": "payments", "message": "Charge request failed",
            "occurred_at": "2026-08-03T11:05:01Z", "service_name": "checkout-api",
            "span_id": "53995c3f42cd8ad8", "environment": "production",
            "release": "checkout@1.2.3"
          }
        ],
        "truncated": false
      },
      "actions": {"status": "not_found", "items": [], "truncated": false},
      "metrics": {"status": "not_found", "items": [], "truncated": false}
    },
    "timeline": {
      "items": [
        {
          "id": "b7ad6b7169203331", "kind": "span", "occurred_at": "2026-08-03T11:05:00Z",
          "name": "POST /checkout", "service_name": "checkout-api",
          "span_id": "b7ad6b7169203331", "severity": null, "status": "ok",
          "duration_ms": 1200
        },
        {
          "id": "53995c3f42cd8ad8", "kind": "span", "occurred_at": "2026-08-03T11:05:00.100Z",
          "name": "POST /v1/charges", "service_name": "checkout-api",
          "span_id": "53995c3f42cd8ad8", "severity": null, "status": "error",
          "duration_ms": 900
        },
        {
          "id": "55555555-5555-4555-8555-555555555555", "kind": "log",
          "occurred_at": "2026-08-03T11:05:01Z", "name": "Charge request failed",
          "service_name": "checkout-api", "span_id": "53995c3f42cd8ad8", "severity": "error",
          "status": null, "duration_ms": null
        }
      ],
      "truncated": false
    },
    "evidence": {
      "status": "partial",
      "captured_fields": [
        "correlations.window", "related_actions", "related_issues", "related_logs",
        "related_metrics", "spans.sdk", "timeline", "trace.parentage", "trace.root",
        "trace.spans"
      ],
      "missing_fields": ["spans.context"],
      "redacted_fields": [],
      "truncated_fields": []
    },
    "next_actions": [
      {
        "priority": 1, "code": "inspect_first_error_span", "target": "trace_span",
        "reason": "error_span_observed", "span_id": "53995c3f42cd8ad8", "issue_id": null
      },
      {
        "priority": 2, "code": "review_related_logs", "target": "telemetry_logs",
        "reason": "related_logs_available", "span_id": "53995c3f42cd8ad8", "issue_id": null
      },
      {
        "priority": 3, "code": "compare_release", "target": "release_summary",
        "reason": "release_identity_available", "span_id": null, "issue_id": null
      },
      {
        "priority": 4, "code": "improve_capture", "target": "sdk_configuration",
        "reason": "evidence_incomplete", "span_id": null, "issue_id": null
      }
    ]
  }
  ```
</Accordion>

| Feld | Bedeutung |
| - | - |
| `subject` | Trace-Summen aus den analysierten Spans. |
| `analysis.status` | `errors_observed`, `latency_focus` oder `no_error_observed`. |
| `analysis.first_error_path` | Die bekannte Kette übergeordneter Spans vom Root bis zum frühesten Fehler-Span. |
| `analysis.bottleneck_path` | Die bekannte Kette übergeordneter Spans bis zum langsamsten Child-Span. |
| `spans.items[].roles` | Warum der Span in der Vorschau steht: `root`, `first_error`, `error_path`, `bottleneck`, `bottleneck_path`, `error` oder `slow`. |
| `correlations.window` | Der Zeitraum und die Bereitstellungsbereiche für zugehörige Lesezugriffe. |
| `correlations.issues`, `logs`, `actions`, `metrics` | Signale mit derselben Trace-ID im Zeitraum. |

`trace.parentage` fehlt, wenn ein Span einen übergeordneten Span nennt, den
LogBrew nicht gespeichert hat. Die Span-Vorschau hat höchstens 64 Spans. Jeder
Analysepfad hat höchstens 64 Spans. Zugehörige Lesezugriffe verwenden
höchstens 8 Bereitstellungsbereiche.

Ein nächster Schritt mit dem Ziel `trace_span` nennt eine `span_id` aus diesem
Paket. Um diesen Span zu lesen, rufen Sie die Span-Route mit `project_id`,
`environment` und `release` des Spans auf.

### Antwort der Span-Untersuchung

Mit `GET /api/telemetry/traces/{trace_id}/spans/{span_id}/investigation` lesen
Sie eine Operation in einem Trace. Senden Sie `project_id`, `environment` und
`release`. Alle drei sind Pflicht. Kopieren Sie sie aus dem ausgewählten
Span. Senden Sie nicht die Zeilen-`id` des Spans als `span_id`.

```bash theme={null}
curl --fail-with-body -sS -G \
  "https://api.logbrew.co/api/telemetry/traces/$TRACE_ID/spans/$SPAN_ID/investigation" \
  -H "Authorization: Bearer $LOGBREW_TOKEN" \
  --data-urlencode "project_id=$PROJECT_ID" \
  --data-urlencode "environment=production" \
  --data-urlencode "release=checkout@1.2.3"
```

<Accordion title="Beispiel einer Span-Untersuchung">
  Diese synthetische Antwort beschreibt den fehlgeschlagenen Client-Span aus dem
  Trace-Beispiel. Ein Fehler-Log hat dieselbe Span-ID. Der Span dauerte länger
  als das ungefähre 95. Perzentil seiner gespeicherten Vergleichs-Spans.

  ```json theme={null}
  {
    "schema_version": 1,
    "subject": {
      "kind": "span",
      "id": "44444444-4444-4444-8444-444444444444",
      "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
      "trace_id": "0af7651916cd43dd8448eb211c80319c",
      "span_id": "53995c3f42cd8ad8",
      "parent_span_id": "b7ad6b7169203331",
      "name": "POST /v1/charges",
      "operation": "http.client",
      "status": "error",
      "started_at": "2026-08-03T11:05:00.100Z",
      "duration_ms": 900,
      "service_name": "checkout-api",
      "environment": "production",
      "release": "checkout@1.2.3",
      "sdk": {"name": "@logbrew/node", "version": "0.1.11"},
      "content_trust": "untrusted_telemetry"
    },
    "context": null,
    "payload": {
      "metadata": {
        "values": {"provider": "example-pay"},
        "included_leaf_count": 1,
        "redacted": false,
        "truncated": false
      },
      "events": [],
      "links": [],
      "included_leaf_count": 1,
      "redacted": false,
      "truncated": false
    },
    "analysis": {
      "status": "error_evidence",
      "causality": "evidence_only",
      "observations": ["subject_error", "exact_span_error_log", "subject_at_or_above_peer_p95"]
    },
    "topology": {
      "status": "available",
      "root": {
        "span_id": "b7ad6b7169203331", "parent_span_id": null, "name": "POST /checkout",
        "operation": "http.server", "status": "ok", "started_at": "2026-08-03T11:05:00Z",
        "duration_ms": 1200, "service_name": "checkout-api"
      },
      "parent": {
        "span_id": "b7ad6b7169203331", "parent_span_id": null, "name": "POST /checkout",
        "operation": "http.server", "status": "ok", "started_at": "2026-08-03T11:05:00Z",
        "duration_ms": 1200, "service_name": "checkout-api"
      },
      "ancestors": [
        {
          "span_id": "b7ad6b7169203331", "parent_span_id": null, "name": "POST /checkout",
          "operation": "http.server", "status": "ok", "started_at": "2026-08-03T11:05:00Z",
          "duration_ms": 1200, "service_name": "checkout-api"
        }
      ],
      "children": [],
      "descendant_count": 0,
      "cross_service_edges": [],
      "parent_chain_status": "complete",
      "truncated": false
    },
    "baseline": {
      "status": "available",
      "since": "2026-08-02T11:05:00.100Z",
      "until": "2026-08-03T11:05:00.100Z",
      "dimensions": {
        "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", "environment": "production",
        "release": "checkout@1.2.3", "service_name": "checkout-api",
        "operation": "http.client", "name": "POST /v1/charges"
      },
      "retained_peer_count": 40,
      "error_peer_count": 2,
      "error_rate_basis_points": 500,
      "p50_duration_ms": 310.0,
      "p95_duration_ms": 620.0,
      "p99_duration_ms": 940.0,
      "subject_percentile_basis_points": 9500,
      "method": "approximate_t_digest",
      "limitations": [
        "retained_telemetry_only", "sampling_may_apply", "approximate_percentiles",
        "same_release_only"
      ]
    },
    "correlations": {
      "trace": {
        "status": "available",
        "summary": {
          "trace_id": "0af7651916cd43dd8448eb211c80319c",
          "span_count": 2,
          "error_span_count": 1,
          "service_count": 1,
          "project_count": 1,
          "started_at": "2026-08-03T11:05:00Z",
          "duration_ms": 1200,
          "root_span": {
            "span_id": "b7ad6b7169203331", "parent_span_id": null, "name": "POST /checkout",
            "operation": "http.server", "status": "ok", "started_at": "2026-08-03T11:05:00Z",
            "duration_ms": 1200, "service_name": "checkout-api"
          },
          "slowest_child_span": {
            "span_id": "53995c3f42cd8ad8", "parent_span_id": "b7ad6b7169203331",
            "name": "POST /v1/charges", "operation": "http.client", "status": "error",
            "started_at": "2026-08-03T11:05:00.100Z", "duration_ms": 900,
            "service_name": "checkout-api"
          },
          "slowest_path": [
            {
              "span_id": "b7ad6b7169203331", "parent_span_id": null, "name": "POST /checkout",
              "operation": "http.server", "status": "ok",
              "started_at": "2026-08-03T11:05:00Z", "duration_ms": 1200,
              "service_name": "checkout-api"
            },
            {
              "span_id": "53995c3f42cd8ad8", "parent_span_id": "b7ad6b7169203331",
              "name": "POST /v1/charges", "operation": "http.client", "status": "error",
              "started_at": "2026-08-03T11:05:00.100Z", "duration_ms": 900,
              "service_name": "checkout-api"
            }
          ],
          "error_spans": [
            {
              "span_id": "53995c3f42cd8ad8", "parent_span_id": "b7ad6b7169203331",
              "name": "POST /v1/charges", "operation": "http.client", "status": "error",
              "started_at": "2026-08-03T11:05:00.100Z", "duration_ms": 900,
              "service_name": "checkout-api"
            }
          ],
          "services": [
            {
              "service_name": "checkout-api", "span_count": 2, "error_span_count": 1,
              "max_duration_ms": 1200
            }
          ],
          "releases": ["checkout@1.2.3"],
          "environments": ["production"]
        },
        "truncated": false
      },
      "issues": {"status": "not_found", "items": [], "truncated": false},
      "logs": {
        "status": "available",
        "items": [
          {
            "id": "55555555-5555-4555-8555-555555555555",
            "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", "severity": "error",
            "source": "payments", "message": "Charge request failed",
            "occurred_at": "2026-08-03T11:05:01Z", "service_name": "checkout-api",
            "span_id": "53995c3f42cd8ad8", "environment": "production",
            "release": "checkout@1.2.3"
          }
        ],
        "truncated": false
      },
      "actions": {"status": "not_found", "items": [], "truncated": false},
      "metrics": {"status": "not_found", "items": [], "truncated": false},
      "release": {
        "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", "release": "checkout@1.2.3",
        "environment": "production", "service_name": "checkout-api"
      }
    },
    "timeline": {
      "items": [
        {
          "id": "53995c3f42cd8ad8:start", "kind": "span_start",
          "occurred_at": "2026-08-03T11:05:00.100Z", "offset_ms": 0,
          "name": "POST /v1/charges", "service_name": "checkout-api",
          "span_id": "53995c3f42cd8ad8", "severity": null, "status": "error",
          "duration_ms": 900
        },
        {
          "id": "55555555-5555-4555-8555-555555555555", "kind": "log",
          "occurred_at": "2026-08-03T11:05:01Z", "offset_ms": 900, "name": "payments",
          "service_name": "checkout-api", "span_id": "53995c3f42cd8ad8", "severity": "error",
          "status": null, "duration_ms": null
        },
        {
          "id": "53995c3f42cd8ad8:end", "kind": "span_end",
          "occurred_at": "2026-08-03T11:05:01Z", "offset_ms": 900, "name": "POST /v1/charges",
          "service_name": "checkout-api", "span_id": "53995c3f42cd8ad8", "severity": null,
          "status": "error", "duration_ms": 900
        }
      ],
      "truncated": false
    },
    "evidence": {
      "status": "partial",
      "captured_fields": [
        "attributes.metadata.provider", "baseline", "correlations.actions",
        "correlations.issues", "correlations.logs", "correlations.metrics",
        "correlations.trace", "subject.content_trust", "subject.deployment",
        "subject.identity", "subject.sdk", "subject.timing", "topology"
      ],
      "missing_fields": ["context"],
      "redacted_fields": [],
      "truncated_fields": []
    },
    "next_actions": [
      {
        "priority": 1, "code": "inspect_parent_span", "target": "span_investigation",
        "reason": "parent_context_available", "span_id": "b7ad6b7169203331", "issue_id": null
      },
      {
        "priority": 2, "code": "review_exact_span_logs", "target": "telemetry_logs",
        "reason": "exact_span_logs_available", "span_id": "53995c3f42cd8ad8",
        "issue_id": null
      },
      {
        "priority": 3, "code": "inspect_trace", "target": "trace_investigation",
        "reason": "trace_context_available", "span_id": "53995c3f42cd8ad8", "issue_id": null
      },
      {
        "priority": 4, "code": "compare_peer_baseline", "target": "peer_baseline",
        "reason": "subject_latency_elevated", "span_id": "53995c3f42cd8ad8", "issue_id": null
      },
      {
        "priority": 5, "code": "compare_release", "target": "release_investigation",
        "reason": "exact_release_available", "span_id": null, "issue_id": null
      },
      {
        "priority": 6, "code": "improve_capture", "target": "sdk_capture",
        "reason": "capture_incomplete", "span_id": "53995c3f42cd8ad8", "issue_id": null
      }
    ]
  }
  ```
</Accordion>

| Feld | Bedeutung |
| - | - |
| `payload` | Die `metadata` des Spans, bis zu 8 `events` und bis zu 8 `links`. Sie teilen sich ein Budget von 64 Werten. |
| `analysis.observations` | `subject_error`, `child_error`, `exact_span_error_log`, `related_issue`, `subject_at_or_above_peer_p95` oder `subject_at_or_above_peer_p99`. |
| `topology` | `root`, `parent`, `ancestors`, direkte `children`, `descendant_count` und `cross_service_edges`. |
| `topology.parent_chain_status` | `root`, `complete`, `missing`, `cycle`, `truncated` oder `unavailable`. |
| `baseline` | Frühere Spans mit demselben Projekt, derselben Umgebung, demselben Release, Dienst, derselben Operation und demselben Namen. |
| `correlations.logs` | Logs mit derselben Trace-ID und Span-ID. |
| `correlations.issues`, `actions`, `metrics` | Signale mit derselben Trace-ID im selben Projekt, in derselben Umgebung und im selben Release. |
| `timeline[].offset_ms` | Millisekunden ab dem Start des Spans. Ein negativer Wert liegt vor dem Span. |

Die Basis liest die 24 Stunden vor dem Start des Spans. `since` ist
inklusiv, `until` ist exklusiv. `error_rate_basis_points: 500` bedeutet 5 %.
`subject_percentile_basis_points: 9500` bedeutet, dass 95 % der gespeicherten
Vergleichs-Spans nicht länger dauerten als dieser Span. Perzentile sind
ungefähr. Behalten Sie `baseline.limitations` bei den Werten. Eine Basis mit
`not_found` hat keine gespeicherten Vergleichs-Spans. Eine Basis mit
`unavailable` ist ein fehlgeschlagener Lesezugriff, keine Null.

`parent_chain_status: "complete"` bedeutet, dass die gespeicherte Kette einen
Root erreicht. Es beweist nicht, dass LogBrew jeden Span der Anfrage
gespeichert hat. Die Topologie gibt höchstens 64 Vorfahren, 50 direkte
Child-Spans und 50 dienstübergreifende Kanten zurück.

| HTTP | `error` | Wiederherstellung |
| - | - | - |
| `422` | `trace_id must be a non-zero 32-character hexadecimal value` | Kopieren Sie `trace_id` aus einer Trace-Antwort von LogBrew. |
| `422` | `span_id must be a non-zero 16-character hexadecimal value` | Kopieren Sie `span_id` aus einer Trace-Antwort von LogBrew. |
| `422` | `environment and release must be non-empty exact span scope values` | Kopieren Sie den Bereich aus dem ausgewählten Span. |
| `422` | `invalid query parameters` | Senden Sie `project_id`, `environment` und `release` und keinen anderen Schlüssel. |
| `404` | `span not found` | Prüfen Sie die IDs, das Projekt, die Umgebung und das Release. |

### Antwort der Log-Untersuchung

Mit `GET /api/logs/{log_id}/investigation` lesen Sie ein Log und seine
zugehörigen Belege. Diese Route hat keine Abfrageschlüssel. Kopieren Sie die
Log-ID aus einer Log-Liste.

```bash theme={null}
curl --fail-with-body -sS \
  "https://api.logbrew.co/api/logs/$LOG_ID/investigation" \
  -H "Authorization: Bearer $LOGBREW_TOKEN"
```

Der Lesezugriff kann Belege außerhalb der Filter der Log-Liste zurückgeben.
Zugehörige Lesezugriffe verwenden Projekt, Umgebung und Release des Logs sowie
5 Minuten vor und nach dem Log. Logs in der Nähe verwenden außerdem denselben
Dienst. Sie brauchen keine Trace-ID. Lesezugriffe für den genauen Trace
brauchen die Trace-ID des Logs und können andere Dienste einschließen. Die
Trace-Zusammenfassung verwendet dieselbe Trace-ID und denselben Bereich, aber
ohne den Zeitraum.

<Accordion title="Beispiel einer Log-Untersuchung">
  Diese synthetische Antwort hat ein Warn-Log ohne Trace-Kontext und ein Log in
  der Nähe. Die Antwort baut keine Trace-Verknüpfung aus den Zeitstempeln.

  ```json theme={null}
  {
    "schema_version": 1,
    "subject": {
      "kind": "log",
      "id": "66666666-6666-4666-8666-666666666666",
      "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
      "severity": "warning",
      "content_trust": "untrusted_telemetry",
      "source": "inventory",
      "message": "Inventory update delayed",
      "occurred_at": "2026-08-03T12:00:00Z",
      "service_name": "checkout-api",
      "environment": "production",
      "release": "checkout@1.2.3",
      "sdk": {"name": "@logbrew/node", "version": "0.1.11"}
    },
    "context": null,
    "attributes": {
      "values": {"retry_count": 2},
      "included_leaf_count": 1,
      "redacted": false,
      "truncated": false
    },
    "analysis": {
      "status": "warning_evidence",
      "causality": "evidence_only",
      "observations": ["subject_warning"]
    },
    "correlations": {
      "trace": {
        "status": "not_linked", "trace_id": null, "span_id": null, "exact_span": null,
        "summary": null, "truncated": false
      },
      "issues": {"status": "not_linked", "items": [], "truncated": false},
      "trace_logs": {"status": "not_linked", "items": [], "truncated": false},
      "nearby_logs": {
        "status": "available",
        "items": [
          {
            "id": "77777777-7777-4777-8777-777777777777",
            "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", "severity": "info",
            "source": "inventory", "message": "Inventory retry started",
            "occurred_at": "2026-08-03T11:59:58Z", "service_name": "checkout-api",
            "trace_id": null, "span_id": null, "environment": "production",
            "release": "checkout@1.2.3", "relationship": "nearby_scope"
          }
        ],
        "truncated": false
      },
      "actions": {"status": "not_linked", "items": [], "truncated": false},
      "metrics": {"status": "not_linked", "items": [], "truncated": false},
      "release": {
        "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", "release": "checkout@1.2.3",
        "environment": "production", "service_name": "checkout-api"
      }
    },
    "timeline": {
      "items": [
        {
          "id": "77777777-7777-4777-8777-777777777777", "kind": "log",
          "relationship": "nearby_scope", "occurred_at": "2026-08-03T11:59:58Z",
          "name": "inventory", "message": "Inventory retry started",
          "service_name": "checkout-api", "span_id": null, "severity": "info", "status": null,
          "duration_ms": null
        },
        {
          "id": "66666666-6666-4666-8666-666666666666", "kind": "log",
          "relationship": "subject", "occurred_at": "2026-08-03T12:00:00Z",
          "name": "inventory", "message": "Inventory update delayed",
          "service_name": "checkout-api", "span_id": null, "severity": "warning",
          "status": null, "duration_ms": null
        }
      ],
      "truncated": false
    },
    "evidence": {
      "status": "partial",
      "captured_fields": [
        "attributes", "attributes.retry_count", "correlations.nearby_logs",
        "correlations.release", "subject.content_trust", "subject.environment", "subject.id",
        "subject.message", "subject.occurred_at", "subject.project_id", "subject.release",
        "subject.sdk.name", "subject.sdk.version", "subject.service_name", "subject.severity",
        "subject.source", "timeline"
      ],
      "missing_fields": ["context", "correlations.trace.trace_id"],
      "redacted_fields": [],
      "truncated_fields": []
    },
    "next_actions": [
      {
        "priority": 1, "code": "review_nearby_logs", "target": "telemetry_logs",
        "reason": "nearby_logs_available", "issue_id": null, "trace_id": null,
        "span_id": null
      },
      {
        "priority": 2, "code": "improve_capture", "target": "sdk_configuration",
        "reason": "evidence_incomplete", "issue_id": null, "trace_id": null, "span_id": null
      },
      {
        "priority": 3, "code": "compare_release", "target": "release_investigation",
        "reason": "release_identity_available", "issue_id": null, "trace_id": null,
        "span_id": null
      }
    ]
  }
  ```
</Accordion>

| Feld | Bedeutung |
| - | - |
| `attributes` | Die begrenzten strukturierten Attribute. `values` schließt `context` aus. Dieser Wert steht im Feld `context` auf oberster Ebene. |
| `analysis.status` | `critical_evidence`, `error_evidence`, `warning_evidence` oder `no_failure_observed`. |
| `correlations.trace` | Die Trace-ID, die Span-ID, `exact_span` und die `summary` des Trace. |
| `correlations.trace_logs` | Logs mit derselben Trace-ID. `relationship` ist `exact_trace`. |
| `correlations.nearby_logs` | Logs desselben Dienstes im Zeitraum. `relationship` ist `nearby_scope`. Ohne den Gegenstand und ohne die Logs des genauen Trace. |
| `correlations.issues`, `actions`, `metrics` | Signale mit derselben Trace-ID. |
| `correlations.release` | Der Release-Bereich für eine Release-Untersuchung. Er enthält keinen Vergleich. |
| `timeline[].relationship` | `subject`, `exact_span`, `exact_trace` oder `nearby_scope`. |

Eine Trace-ID kann vorhanden sein, auch wenn der Trace-Status `not_found`
oder `unavailable` ist. Eine verfügbare Trace-Zusammenfassung garantiert kein
`exact_span`.

### Antwort der Aktions-Untersuchung

Mit `GET /api/telemetry/actions/{action_id}/investigation` lesen Sie eine
Produktaktion, ihren gemeldeten Status und zugehörige Belege. Diese Route hat
keine Abfrageschlüssel. Zugehörige Lesezugriffe verwenden denselben Zeitraum
und dieselben Bereiche wie eine Log-Untersuchung.

```bash theme={null}
curl --fail-with-body -sS \
  "https://api.logbrew.co/api/telemetry/actions/$ACTION_ID/investigation" \
  -H "Authorization: Bearer $LOGBREW_TOKEN"
```

`correlations`, `timeline` und `next_actions` verwenden die Strukturen der
Log-Untersuchung. Zugehörige Aktionen schließen die untersuchte Aktion aus.

<Accordion title="Beispiel einer Aktions-Untersuchung">
  Diese synthetische Antwort beschreibt eine fehlgeschlagene Checkout-Aktion
  eines angemeldeten Nutzers. Die Aktion hat keine Trace-ID.

  ```json theme={null}
  {
    "schema_version": 1,
    "subject": {
      "kind": "action",
      "id": "14141414-1414-4141-8141-141414141414",
      "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
      "name": "checkout.submit",
      "status": "failure",
      "content_trust": "untrusted_telemetry",
      "occurred_at": "2026-08-03T11:05:00Z",
      "service_name": "checkout-api",
      "environment": "production",
      "release": "checkout@1.2.3",
      "sdk": {"name": "@logbrew/node", "version": "0.1.11"},
      "subject_classification": "user",
      "session_captured": true
    },
    "context": null,
    "properties": {
      "values": {"plan": "team", "step": "payment"},
      "included_leaf_count": 2,
      "redacted": false,
      "truncated": false
    },
    "analysis": {
      "status": "subject_failure",
      "causality": "evidence_only",
      "observations": ["subject_failure"]
    },
    "correlations": {
      "trace": {
        "status": "not_linked", "trace_id": null, "span_id": null, "exact_span": null,
        "summary": null, "truncated": false
      },
      "issues": {"status": "not_linked", "items": [], "truncated": false},
      "trace_logs": {"status": "not_linked", "items": [], "truncated": false},
      "nearby_logs": {"status": "not_found", "items": [], "truncated": false},
      "actions": {"status": "not_linked", "items": [], "truncated": false},
      "metrics": {"status": "not_linked", "items": [], "truncated": false},
      "release": {
        "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", "release": "checkout@1.2.3",
        "environment": "production", "service_name": "checkout-api"
      }
    },
    "timeline": {
      "items": [
        {
          "id": "14141414-1414-4141-8141-141414141414", "kind": "action",
          "relationship": "subject", "occurred_at": "2026-08-03T11:05:00Z",
          "name": "checkout.submit", "message": null, "service_name": "checkout-api",
          "span_id": null, "severity": null, "status": "failure", "duration_ms": null
        }
      ],
      "truncated": false
    },
    "evidence": {
      "status": "partial",
      "captured_fields": [
        "correlations.nearby_logs", "correlations.release", "properties.metadata",
        "properties.metadata.plan", "properties.metadata.step", "subject.content_trust",
        "subject.environment", "subject.id", "subject.name", "subject.occurred_at",
        "subject.project_id", "subject.release", "subject.sdk.name", "subject.sdk.version",
        "subject.service_name", "subject.session_captured", "subject.status",
        "subject.subject_classification", "timeline"
      ],
      "missing_fields": ["context", "correlations.trace.trace_id"],
      "redacted_fields": ["subject.distinct_id", "subject.session_id"],
      "truncated_fields": []
    },
    "next_actions": [
      {
        "priority": 1, "code": "inspect_analytics_paths", "target": "analytics_paths",
        "reason": "session_captured", "issue_id": null, "trace_id": null, "span_id": null
      },
      {
        "priority": 2, "code": "improve_capture", "target": "sdk_configuration",
        "reason": "evidence_incomplete", "issue_id": null, "trace_id": null, "span_id": null
      },
      {
        "priority": 3, "code": "compare_release", "target": "release_investigation",
        "reason": "release_identity_available", "issue_id": null, "trace_id": null,
        "span_id": null
      }
    ]
  }
  ```
</Accordion>

| Feld | Bedeutung |
| - | - |
| `subject.status` | `queued`, `running`, `success`, `failure` oder `null`, wenn kein unterstützter Status erfasst wurde. |
| `subject.subject_classification` | `user`, `anonymous`, `legacy_unknown`, `missing`, `historical_unindexed` oder `unsupported`. |
| `subject.session_captured` | Ob die Aktion eine Sitzung hatte. Die Antwort gibt die Sitzungs-ID nie zurück. |
| `properties` | Das begrenzte Objekt `metadata` der Aktion. |
| `analysis.status` | `subject_failure`, `correlated_failure_evidence`, `in_progress`, `success_observed` oder `status_not_captured`. |

Die Antwort gibt nie Subjekt- oder Sitzungskennungen zurück. Die
Belegübersicht listet `subject.distinct_id` immer als geschwärzt auf, und
`subject.session_id`, wenn eine Sitzung erfasst wurde. Deshalb ist jedes
Aktionspaket `partial` und enthält `improve_capture`. Entfernen Sie keine
Datenschutzeinstellungen, um diesen Schritt zu erfüllen.

### Antwort der Metrik-Untersuchung

Mit `GET /api/telemetry/metrics/investigation` lesen Sie einen Metriknamen in
einem Projekt und einem Zeitraum. Die Antwort enthält die aktuelle Zeitreihe,
einen Vergleich mit dem gleich langen vorherigen Zeitraum, den jüngsten
Messwert, Trace-Exemplare und abgeschlossene Bereitstellungen. Version 2 ergänzt
die Beschreibung der Metrik aus dem jüngsten gespeicherten Messwert. Version 1
meldet immer `description_status: "not_captured"`.

```bash theme={null}
curl --fail-with-body -sS -G \
  "https://api.logbrew.co/api/telemetry/metrics/investigation" \
  -H "Authorization: Bearer $LOGBREW_TOKEN" \
  --data-urlencode "project_id=$PROJECT_ID" \
  --data-urlencode "name=http.server.duration" \
  --data-urlencode "since=2026-08-02T12:00:00Z" \
  --data-urlencode "until=2026-08-03T12:00:00Z" \
  --data-urlencode "interval=5m" \
  --data-urlencode "group_by=service_name" \
  --data-urlencode "environment=production" \
  --data-urlencode "series_limit=12" \
  --data-urlencode "response_version=2"
```

`project_id`, `name` und `since` sind Pflicht. `since` ist inklusiv, `until`
ist exklusiv. Ohne Wert ist `until` der aktuelle Zeitpunkt. Der Vergleich liest
außerdem den gleich langen vorherigen Zeitraum.

<Accordion title="Beispiel einer Metrik-Untersuchung in Version 2">
  Dieses synthetische Histogramm hat 5 Messwerte in zwei Zeitfenstern von
  5 Minuten. Das jüngste Zeitfenster hat ein p95 von 48 ms. Das jüngste
  Zeitfenster des vorherigen Zeitraums hat ein p95 von 24 ms.

  ```json theme={null}
  {
    "schema_version": 2,
    "subject": {
      "kind": "metric", "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
      "name": "http.server.duration", "description_status": "captured",
      "description": "Duration of one completed server request."
    },
    "query": {
      "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", "name": "http.server.duration",
      "since": "2026-08-02T12:00:00Z", "until": "2026-08-03T12:00:00Z", "interval": "5m",
      "interval_seconds": 300, "group_by": "service_name", "environment": "production",
      "series_limit": 12
    },
    "purpose": "Explains one metric's latest application-supplied description and bounded change, compares the immediately preceding equal window, exposes one privacy-bounded latest-sample capture context, exact trace/span exemplars, and nearby completed deployments, and keeps every correlation evidence-only rather than claiming an anomaly or root cause.",
    "content_trust": "untrusted_telemetry",
    "analysis": {
      "status": "change_observed",
      "causality": "evidence_only",
      "focus": {
        "comparison_index": 0, "selection": "largest_absolute_relative_change",
        "direction": "increased", "absolute_change": 24.0, "relative_change_percent": 100.0
      }
    },
    "coverage": {
      "samples": 5, "series": 1, "returned_series": 1, "points": 2,
      "expected_buckets_per_series": 288, "first_seen_at": "2026-08-03T11:00:10Z",
      "last_seen_at": "2026-08-03T11:09:50Z", "truncated": false
    },
    "series": [
      {
        "identity": {
          "kind": "histogram", "unit": "ms", "temporality": "delta",
          "group_by": "service_name", "group_value": "checkout-api"
        },
        "status": "ready",
        "aggregation": {
          "code": "distribution_p95",
          "description": "Primary value is the approximate p95 of raw observations in each bucket; p50, p99, range, average, count, and sum preserve distribution context."
        },
        "sample_count": 5,
        "points": [
          {
            "bucket_start": "2026-08-03T11:00:00Z", "bucket_end": "2026-08-03T11:05:00Z",
            "sample_count": 2, "value": 42.0, "min": 42.0, "max": 42.0, "average": 42.0,
            "sum": 84.0, "p50": 42.0, "p95": 42.0, "p99": 42.0, "trace_exemplars": []
          },
          {
            "bucket_start": "2026-08-03T11:05:00Z",
            "bucket_end": "2026-08-03T11:10:00Z",
            "sample_count": 3,
            "value": 48.0,
            "min": 48.0,
            "max": 48.0,
            "average": 48.0,
            "sum": 144.0,
            "p50": 48.0,
            "p95": 48.0,
            "p99": 48.0,
            "trace_exemplars": ["4bf92f3577b34da6a3ce929d0e0e4736"]
          }
        ]
      }
    ],
    "comparison": {
      "status": "available",
      "method": "adjacent_equal_window_latest_bucket",
      "previous_since": "2026-08-01T12:00:00Z",
      "previous_until": "2026-08-02T12:00:00Z",
      "items": [
        {
          "identity": {
            "kind": "histogram", "unit": "ms", "temporality": "delta",
            "group_by": "service_name", "group_value": "checkout-api"
          },
          "aggregation": "distribution_p95",
          "current": {
            "bucket_start": "2026-08-03T11:05:00Z", "bucket_end": "2026-08-03T11:10:00Z",
            "sample_count": 3, "value": 48.0
          },
          "previous": {
            "bucket_start": "2026-08-02T11:55:00Z", "bucket_end": "2026-08-02T12:00:00Z",
            "sample_count": 2, "value": 24.0
          },
          "direction": "increased",
          "absolute_change": 24.0,
          "relative_change_percent": 100.0
        }
      ],
      "truncated": false,
      "limitation": "Each item compares the latest non-empty semantic bucket in adjacent equal-length windows. It is an observed value change, not seasonality-aware anomaly detection or evidence that a deployment caused the change."
    },
    "latest_sample": {
      "status": "available",
      "sample": {
        "id": "dddddddd-dddd-4ddd-8ddd-dddddddddddd",
        "kind": "histogram",
        "value": 48.0,
        "unit": "ms",
        "temporality": "delta",
        "occurred_at": "2026-08-03T11:09:50Z",
        "service_name": "checkout-api",
        "environment": "production",
        "release": "checkout@1.2.3",
        "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
        "span_id": "00f067aa0ba902b7",
        "sdk": {"name": "@logbrew/node", "version": "0.1.11"},
        "context": null,
        "metadata": {"values": {}, "included_leaf_count": 0, "redacted": false, "truncated": false}
      }
    },
    "exemplars": {
      "status": "available",
      "coverage": {
        "matching_samples": 5, "trace_linked_samples": 1, "span_linked_samples": 1,
        "returned_exemplars": 1
      },
      "items": [
        {
          "id": "dddddddd-dddd-4ddd-8ddd-dddddddddddd",
          "value": 48.0,
          "occurred_at": "2026-08-03T11:09:50Z",
          "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
          "span_id": "00f067aa0ba902b7",
          "service_name": "checkout-api",
          "environment": "production",
          "release": "checkout@1.2.3",
          "sdk": {"name": "@logbrew/node", "version": "0.1.11"}
        }
      ],
      "truncated": false
    },
    "deployments": {
      "status": "available",
      "items": [
        {
          "deployment_id": "deploy-123", "release": "checkout@1.2.3",
          "environment": "production", "service_name": "checkout-api", "status": "succeeded",
          "started_at": "2026-08-03T11:02:00Z", "finished_at": "2026-08-03T11:03:00Z",
          "commit_sha": "0123456789abcdef"
        }
      ],
      "truncated": false
    },
    "timeline": {
      "items": [
        {
          "id": "deploy-123", "kind": "deployment_finished",
          "occurred_at": "2026-08-03T11:03:00Z", "value": null, "trace_id": null,
          "span_id": null, "release": "checkout@1.2.3", "service_name": "checkout-api"
        },
        {
          "id": "dddddddd-dddd-4ddd-8ddd-dddddddddddd", "kind": "metric_exemplar",
          "occurred_at": "2026-08-03T11:09:50Z", "value": 48.0,
          "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "span_id": "00f067aa0ba902b7",
          "release": "checkout@1.2.3", "service_name": "checkout-api"
        }
      ],
      "truncated": false
    },
    "evidence": {
      "status": "partial",
      "captured_fields": [
        "metric.current_window_coverage", "metric.deployment_overlays", "metric.description",
        "metric.identity", "metric.latest_sample", "metric.latest_sample.kind",
        "metric.latest_sample.occurred_at", "metric.latest_sample.scope",
        "metric.latest_sample.sdk.name", "metric.latest_sample.sdk.version",
        "metric.latest_sample.span_id", "metric.latest_sample.trace_id",
        "metric.latest_sample.value", "metric.prior_window_comparison", "metric.query_scope",
        "metric.series_semantics", "metric.span_exemplars", "metric.trace_exemplars"
      ],
      "missing_fields": ["metric.latest_sample.context", "metric.latest_sample.metadata"],
      "redacted_fields": [],
      "truncated_fields": []
    },
    "next_actions": [
      {
        "priority": 1,
        "code": "inspect_exact_span",
        "target": "span_investigation",
        "reason": "Inspect the exact span that emitted a retained metric exemplar, then review its failure, latency, log, issue, action, and trace evidence.",
        "context": {
          "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
          "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "span_id": "00f067aa0ba902b7",
          "environment": "production", "release": "checkout@1.2.3",
          "service_name": "checkout-api"
        }
      },
      {
        "priority": 2,
        "code": "review_deployment",
        "target": "release_investigation",
        "reason": "Review release-scoped telemetry for a completed deployment inside the compared evidence window without treating temporal proximity as causality.",
        "context": {
          "project_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", "trace_id": null,
          "span_id": null, "environment": "production", "release": "checkout@1.2.3",
          "service_name": "checkout-api"
        }
      }
    ]
  }
  ```
</Accordion>

| Feld | Bedeutung |
| - | - |
| `subject.description_status` | `captured`, `not_captured` oder `unavailable`. |
| `query` | Die normalisierte Abfrage. `service_name`, `release` und `environment` erscheinen nur, wenn sie gesendet wurden. |
| `analysis.status` | `no_samples`, `change_observed`, `no_change_observed`, `baseline_not_found` oder `comparison_unavailable`. |
| `analysis.focus` | Der Vergleichseintrag mit der größten relativen Änderung, oder mit der größten absoluten Änderung, wenn es keine relative Änderung gibt. `null`, wenn kein Eintrag vergleichbar ist. |
| `series[].aggregation.code` | `gauge_last`, `delta_sum`, `distribution_p95`, `raw_cumulative_last` oder `raw_last`. |
| `comparison.status` | `available`, `partial`, `not_found`, `unavailable` oder `no_current_samples`. |
| `comparison.items[]` | Das jüngste nicht leere Zeitfenster jedes Zeitraums für dieselbe Identität der Zeitreihe. |
| `latest_sample` | Der jüngste rohe Messwert, mit SDK, `context`, `metadata` und Trace-Link. |
| `exemplars` | Rohe Messwerte mit einer Trace-ID. `coverage` zählt die verknüpften Messwerte. |
| `deployments` | Abgeschlossene Bereitstellungen vom Beginn des vorherigen Zeitraums bis `until`. |
| `next_actions[]` | `code`, `target`, ein `reason` als Klartext und ein `context`-Bereich für den nächsten Lesezugriff. |

`relative_change_percent` ist `(current - previous) / abs(previous) * 100`.
Der Wert ist `null`, wenn der vorherige Wert null ist oder fehlt.
`expected_buckets_per_series` zählt mögliche Zeitfenster, nicht Zeitfenster
mit Daten. Zeichnen Sie leere Zeitfenster nicht als null. Eine Bereitstellung in
der Nähe einer Änderung beweist nicht, dass sie die Änderung verursacht hat.

Ein Projekt, das das Konto nicht lesen kann, gibt `200 OK` mit
`analysis.status: "no_samples"` zurück, nicht `404`. Ein leeres Ergebnis sagt
nichts über andere Signaltypen aus.

Grenzen für Metriken: Der Zeitraum umfasst höchstens 31 Tage. Jede Zeitreihe
hat höchstens 500 Zeitfenster. `series_limit` ist 1 bis 20, Standardwert 10.
Die Antwort gibt höchstens 20 Exemplare und 20 Bereitstellungen zurück.

| HTTP | `error` | Wiederherstellung |
| - | - | - |
| `422` | `metric investigation response_version must be 1 or 2` | Lassen Sie `response_version` weg oder senden Sie `2`. |
| `422` | `metric series project_id is required` | Senden Sie eine lesbare Projekt-ID. |
| `422` | `metric series name is required` | Kopieren Sie den Namen aus der Metrikliste. |
| `422` | `metric series since is required` | Senden Sie einen Wert wie `24h` oder einen Zeitstempel nach RFC 3339. |
| `422` | `metric series range must not exceed 31 days` | Verwenden Sie einen kürzeren Zeitraum. |
| `422` | `metric series interval would exceed 500 buckets` | Verwenden Sie `interval=auto` oder ein breiteres Intervall. |
| `422` | `metric series_limit must be between 1 and 20` | Senden Sie einen Wert von 1 bis 20. |

`interval` ist `auto`, `1m`, `5m`, `15m`, `1h`, `6h` oder `1d`. `group_by`
ist `none`, `service_name`, `release` oder `environment`. Andere Werte geben
`422` zurück.

### Fehler bei Untersuchungen

| HTTP | Route | `error` |
| - | - | - |
| `404` | Log | `log not found` |
| `404` | Aktion | `action not found` |
| `404` | Trace | `trace not found` |
| `422` | Trace | `trace investigation response_version must be 1, 2, or 3` |
| `400` | Log, Aktion, Issue | `invalid URL path parameters`, wenn die ID im Pfad keine UUID ist |
| `422` | Issue, Trace, Span, Metrik | `invalid query parameters` bei einem unbekannten Schlüssel oder einem Wert vom falschen Typ |

Ein `404` bedeutet, dass kein lesbares Projekt den Datensatz hat. Jede Route
gibt außerdem `401` ohne gültige Authentifizierung zurück und `405` bei einer
anderen Methode als `GET`. Unter [API-Fehler](/de/reference/api-errors) finden
Sie die Antworten zu
[nicht gefunden](/de/reference/api-errors#resource-not-found),
[Pfad](/de/reference/api-errors#invalid-path-value),
[Authentifizierung](/de/reference/api-errors#authentication-failure) und
[Methode](/de/reference/api-errors#unsupported-method).

Ein optionaler Lesezugriff auf Belege kann innerhalb einer Antwort `200 OK`
fehlschlagen. Die Sammlung meldet dann `unavailable`. Zeigen Sie sie nicht als
`not_found` und nicht als null Datensätze an.

## <span id="severity-values">Schweregrade</span>

Für Nutzer sichtbare Schweregrade sind `info`, `warning`, `error` und
`critical`. SDKs und Laufzeiten können gängige Aliasse wie `trace`, `debug`,
`warn` oder `fatal` senden. REST- und Live-Antworten geben immer den
kanonischen Wert zurück. LogBrew akzeptiert zum Beispiel `warn` als Eingabe
und gibt `warning` zurück. Die Signalaufnahme lehnt unbekannte Schweregrade
ab.

| Alias | Kanonischer Wert |
| - | - |
| `trace`, `debug` | `info` |
| `warn` | `warning` |
| `fatal` | `critical` |

## <span id="severity-rule-responses">Antworten zu Schweregrad-Regeln</span>

Eine Schweregrad-Regel ändert, wie LogBrew ein Log oder ein Issue anzeigt. Sie
ändert nicht den Schweregrad, den die Anwendung erfasst hat. Logs und Issues
geben ein Objekt `triage` zurück:

| Feld | Bedeutung |
| - | - |
| `effective_severity` | Der anzuzeigende Schweregrad. Ohne Regel ist er gleich `severity`. |
| `ignored` | `true`, wenn eine Log-Regel das Log ignoriert oder wenn das Issue archiviert ist. |
| `rule_applied` | `true`, wenn eine Schweregrad-Regel oder der ignorierte Zustand gilt. `false` ist der Standardwert, keine fehlenden Daten. |

Verwenden Sie `triage.effective_severity` für die Anzeige. Behalten Sie
`severity` als erfassten Wert. Standardmäßig lässt die Log-Liste ignorierte
Logs weg. Senden Sie `status=ignored` oder `status=all` an `GET /api/logs`, um
sie einzuschließen.

Das Konto braucht die Berechtigung, Issues im Projekt zu verwalten.
Lesezugriff reicht nicht. Ohne diese Berechtigung gibt eine Regeländerung
`403` mit `code: forbidden` zurück.

### Eine Log-Regel ändern

`PUT /api/logs/{log_id}/triage-rule` setzt die Regel für das Log und für
spätere Logs mit derselben Signatur. Der Anfrage-Body braucht `severity` und
`ignored`:

```bash theme={null}
curl --request PUT "https://api.logbrew.co/api/logs/$LOG_ID/triage-rule" \
  --header "Authorization: Bearer $LOGBREW_ACCOUNT_BEARER" \
  --header "Content-Type: application/json" \
  --data '{ "severity": "info", "ignored": true }'
```

Eine Antwort `200 OK` enthält das vollständige [Log](#log-response). Sein
`severity` bleibt `warning`. Sein `triage` zeigt die Regel:

```json theme={null}
{
  "severity": "warning",
  "triage": {
    "effective_severity": "info",
    "ignored": true,
    "rule_applied": true
  }
}
```

Dieser Ausschnitt zeigt nur die geänderten Felder. `severity` in der Anfrage
ist `source`, `info`, `warning`, `error` oder `critical`. `source` stellt den
erfassten Schweregrad wieder her. Es macht ein ignoriertes Log nicht wieder
aktiv. Um das Log wieder anzuzeigen, senden Sie `"ignored": false`.

### Eine Issue-Regel ändern

`PUT /api/telemetry/issues/{issue_id}/triage-rule` setzt den angezeigten
Schweregrad eines gruppierten Issues und seiner späteren Vorkommen. Der
Anfrage-Body akzeptiert nur `severity`:

```bash theme={null}
curl --request PUT "https://api.logbrew.co/api/telemetry/issues/$ISSUE_ID/triage-rule" \
  --header "Authorization: Bearer $LOGBREW_ACCOUNT_BEARER" \
  --header "Content-Type: application/json" \
  --data '{ "severity": "warning" }'
```

Eine Antwort `200 OK` enthält das vollständige [Issue](#issue-response) in
Version 1. Die erfassten Werte `severity` und `status` ändern sich nicht:

```json theme={null}
{
  "severity": "error",
  "status": "unresolved",
  "triage": {
    "effective_severity": "warning",
    "ignored": false,
    "rule_applied": true
  }
}
```

Dieser Ausschnitt zeigt nur einige Felder. Eine Regel löst, archiviert oder
öffnet ein Issue nicht wieder. Verwenden Sie dafür die
[Statusänderung](#issue-status-response-examples). Eine abgeleitete Priorität
folgt dem neuen effektiven Schweregrad. Lesen Sie das Issue mit
`response_version=2` oder `3`, um sie zu sehen.

Ein nicht unterstützter Schweregrad gibt `422` zurück:

```json theme={null}
{
  "error": "triage severity must be source, info, warning, error, or critical",
  "code": "validation_failed",
  "next": "use source to restore captured severity, or choose info, warning, error, or critical",
  "next_action": {
    "code": "fix_request",
    "target": "request"
  }
}
```

Ein unbekanntes Feld im Anfrage-Body, zum Beispiel `status` bei einer
Issue-Regel, gibt `422` mit `code: invalid_json` zurück. Ein fehlendes oder
nicht lesbares Log oder Issue gibt `404` mit `code: not_found` zurück. Geht die
Antwort verloren, lesen Sie das Log oder Issue erneut, bevor Sie die Regel
noch einmal senden.

## Format von Fehlerantworten

Anwendungsfehler von LogBrew geben einen JSON-Umschlag zurück. Dieses
Beispiel zeigt eine abgelehnte Anfrage. Der Text in `error` und `next` hängt
vom Problem ab:

```json theme={null}
{
  "error": "<what is wrong>",
  "code": "validation_failed",
  "next": "<how to fix it>",
  "next_action": {
    "code": "fix_request",
    "target": "request"
  }
}
```

Verwenden Sie `code` für Verzweigungen im Programm und `next_action` für
Automatisierung. Zeigen Sie `error` und `next` Menschen als Klartext an.
Werten Sie ihren Wortlaut nicht maschinell aus. Manche Fehler ergänzen Felder
wie `limit`, `reset_at` oder `retry_after_seconds`. Eine Antwort ohne
JSON-Body hat keinen `code` von LogBrew. Alle Codes finden Sie unter
[API-Fehler](/de/reference/api-errors).

## Daten mit der CLI lesen

Die CLI liest dieselben Routen und gibt mit `--json` dasselbe JSON zurück.
Beginnen Sie breit und grenzen Sie dann ein:

```bash theme={null}
logbrew read releases --environment production --json
logbrew read issues --release api@1.2.3 --status unresolved --json
logbrew read logs --release api@1.2.3 --since 24h --json
logbrew read actions --name checkout_failed --since 24h --json
logbrew read traces --status error --since 24h --json
logbrew read trace <trace_id> --json
```

Fügen Sie `--pagination cursor` hinzu, um den Cursor-Umschlag zu erhalten. Die
CLI fordert die Issue-Antwortversion 4 an. Siehe
[Die nächste Seite lesen](/de/reference/cli#read-the-next-page) und
[Live-Beobachtung](/de/reference/cli#live-watch).


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