> ## 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.

# Formato delle risposte API ed esempi di risposte JSON

> Leggi le risposte dell'API LogBrew per liste di telemetria, pagine con cursore, eventi in tempo reale, modifiche, stati di successo e di errore.

Questa pagina mostra un esempio per ogni famiglia di risposte della
[API di telemetria](/it/reference/telemetry-api). Tutti i valori sono fittizi. Per i
codici di errore e il ripristino, vedi [Errori API](/it/reference/api-errors).

## Leggi una risposta

Leggi ogni risposta in questo ordine:

1. Leggi lo stato HTTP.
2. Verifica che il corpo abbia la forma prevista dalla route.
3. Verifica che ogni `project_id` rientri nell'ambito di progetti richiesto.
4. Lascia invariati i valori enum canonici e gli identificatori.
5. Segui `next_action` solo se il client supporta il suo `code` e il suo
   `target`.
6. Tratta `null`, un campo omesso e una lista vuota come stati diversi.

Un `200 OK` può contenere una lista vuota. Una lista di log vuota significa
che nessun log corrisponde alla richiesta. Non significa che anche problemi,
tracce o azioni siano vuoti. Non collegare segnali solo perché i loro
timestamp sono vicini. Segui una traccia solo quando la risposta contiene il
suo `trace_id` esatto.

Un `404` e una lista vuota sono risultati diversi. Una route di lista
restituisce `[]` quando nessun record corrisponde. Una route di dettaglio
restituisce `404` con `code: not_found` quando non trova un record leggibile.
Nessuno dei due risultati dimostra che l'ingestione non è riuscita.

## Cosa inviare

Le risposte sono utili quanto la telemetria che invii. Invia questi valori in
ogni envelope o configurazione dell'SDK:

* `release` e `environment`.
* Nomi stabili per servizi, azioni e metriche.
* Il contesto di traccia quando log, span, azioni e problemi appartengono alla
  stessa richiesta.
* Valori di gravità canonici: `info`, `warning`, `error` e `critical`.
* Attributi utili al debug, senza segreti né dati personali superflui.

Vedi [Invia telemetria con l'SDK](/it/guides/sdk-ingestion) e
[Controlla i dati acquisiti](/it/guides/safe-capture).

## Risposta di ingestione

Gli SDK pubblici leggono la risposta di `POST /v1/events` al posto tuo. Il
codice dell'applicazione non deve gestirla.

### Risposta a un batch dell'SDK

Un batch dell'SDK riuscito restituisce `200 OK` con il numero di elementi
accettati per ogni flusso:

```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"
  }
}
```

| Campo | Significato |
| - | - |
| `issues`, `logs`, `trace_spans`, `actions`, `metrics` | Eventi di questo batch accettati da LogBrew. |
| `already_accepted` | Eventi con un ID che LogBrew ha già accettato in precedenza. LogBrew non li memorizza di nuovo. |
| `context_updated` | `true` quando il batch ha aggiornato il contesto di release o di ambiente. |

I conteggi riguardano solo questo batch. Un nuovo tentativo con un batch che
LogBrew ha già accettato restituisce `0` per ogni flusso e il numero di eventi
in `already_accepted`. Mantieni gli ID originali degli eventi quando riprovi.

### Risposta all'envelope nativo

`POST /api/telemetry/ingest` restituisce `200 OK` con il numero di elementi
accettati per ogni flusso:

```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"
  }
}
```

La risposta nativa non ha i campi `metrics` e `context_updated`. Non
aggiungerli. `already_accepted` conta gli elementi il cui `id` LogBrew ha già
accettato in precedenza per il progetto. Vedi l'[envelope nativo diretto](/it/guides/sdk-ingestion#required-envelope-fields).

### Errori di ingestione

Un `401` con `code: ingest_key_invalid` significa che il token bearer di
ingestione è revocato, scaduto o non valido per il progetto. Su
`POST /v1/events`, un token bearer mancante o che non è una chiave di
ingestione restituisce `401` con `code: unauthorized`. Usa il token bearer di
ingestione attuale, limitato al progetto. Non riprovare con un token bearer
dell'account.

Un batch dell'SDK rifiutato restituisce `422` con `code: validation_failed`:

```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"
  }
}
```

Altri valori di `error` sono `SDK event batch requires at least one event` e
`SDK event type is not supported by this ingest route`. Controlla la versione
dell'SDK e la configurazione del trasporto. Non inviare un batch vuoto. Non
cambiare tipi o ID degli eventi solo per far superare la validazione al batch.

Una richiesta con un metodo diverso da `POST` restituisce `405` con
`code: method_not_allowed`. Un corpo JSON illeggibile restituisce
`code: invalid_json`.

## Formato delle risposte di lista della telemetria

Per impostazione predefinita, le route di lista restituiscono un array JSON
semplice. Una lista vuota riuscita è `[]`.

Con `pagination=cursor`, la route restituisce un envelope. La chiave della
collezione corrisponde al segnale:

| Route | Chiave della collezione |
| - | - |
| `/api/logs` | `logs` |
| `/api/telemetry/issues` | `issues` |
| `/api/telemetry/issues/{issue_id}/events` | `events`, con un `issue_id` di primo livello |
| `/api/telemetry/actions` | `actions` |
| `/api/telemetry/metrics` | `metrics` |
| `/api/telemetry/releases` | `releases` |
| `/api/telemetry/traces` | `traces`, con un `naming_quality` di primo livello |

`next_cursor` è un oggetto con i campi per continuare, oppure `null`
sull'ultima pagina. Le righe vanno dalla più recente alla meno recente. Vedi
[paginazione con cursore](/it/reference/telemetry-api-filters#cursor-pagination).

### <span id="log-response">Risposta dei log</span>

Una pagina con cursore di log con `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"
  }
}
```

I log includono `level` per compatibilità e `severity` per la
visualizzazione. Entrambi contengono il valore canonico. `triage` contiene il
risultato di una regola di gravità. Vedi
[risposte delle regole di gravità](#severity-rule-responses).

`trace_id` e `span_id` sono `null` quando il log non ha un collegamento a una
traccia. In quel caso `next_action` è `inspect_related_logs` con target
`telemetry_logs`. Log, problemi e azioni usano le stesse 2 coppie di
`next_action`.

`GET /api/logs/{log_id}` restituisce un log con la stessa forma.

### <span id="issue-response">Risposta dei problemi</span>

`GET /api/telemetry/issues/{issue_id}` restituisce un problema raggruppato. La
lista restituisce gli stessi oggetti. Questo esempio usa la versione di
risposta predefinita 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"
}
```

Nella versione 1, `status` è `unresolved`, `resolved` o `ignored`. Per un
problema archiviato, `triage.ignored` è `true`. Per le coppie di `next_action`
e le letture che seguono, vedi
[Indaga su un problema](/it/guides/investigate-an-issue).

`first_seen_at` e `last_seen_at` sono gli orari della prima e dell'ultima
occorrenza. Non cambiano quando cambia lo stato.

Alcuni campi compaiono solo quando LogBrew ha i dati:

| Campo | Quando compare |
| - | - |
| `span_id` | Il problema ha un collegamento a uno span. Altrimenti il campo è omesso. |
| `diagnostics` | L'ultima occorrenza ha un tipo di eccezione o dei breadcrumb. Vedi [cronologia delle occorrenze di un problema](#issue-occurrence-history). |
| `symbolication` | Solo su `GET /api/telemetry/issues/{issue_id}`, quando il problema ha un'identità di artefatto di release. Vedi [Source map](/it/guides/source-maps). |

`symbolication.status` è `resolved`, `invalid_metadata`,
`artifact_not_found`, `source_not_resolved` o `unavailable`. La lista, i
cambi di stato e le modifiche alle regole non restituiscono `symbolication`.

Con `response_version=2`, il problema ha gli stessi campi, con queste
modifiche:

| Campo | Valore nella versione 2 |
| - | - |
| `status` | `unresolved`, `resolved` o `archived`. La versione 1 mostra `archived` come `ignored`. |
| `priority` | `high`, `medium` o `low`. |
| `priority_source` | `manual` quando una persona ha impostato la priorità. `derived` quando la priorità segue la gravità effettiva. |

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

Questo esempio mostra solo alcuni campi. Una priorità derivata è `high` per
`error` e `critical`, `medium` per `warning` e `low` per `info`. Usa
`triage.effective_severity`, quindi una regola di gravità per i problemi può
cambiarla.

Con `response_version=3`, il problema ha tutti i campi della versione 2 e
`assignee`. `assignee` è `null` quando il problema non ha un assegnatario:

```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"
  }
}
```

| Campo | Significato |
| - | - |
| `assignee.user_id` | ID utente dell'assegnatario. Invialo come `assignee` in un filtro o in una modifica. |
| `assignee.name` | Nome dell'assegnatario, oppure `null` quando l'account non ha un nome. |
| `assignee.email` | Indirizzo email dell'assegnatario. |

Un problema non mostra alcun assegnatario quando il membro assegnato non può
più leggere il progetto.

Con `response_version=4`, `assignee` ha anche `type`. Un assegnatario `user`
ha `user_id`, `name` ed `email`, come nella versione 3. Un assegnatario `team`
ha `team_id`, `slug` e `name`. La versione 3 mostra un team assegnatario come
`null`. La CLI richiede la versione 4:

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

Qualsiasi altro `response_version` restituisce `422` con
`code: validation_failed`. Una pagina con cursore usa la stessa versione per
ogni problema in `issues`.

### <span id="assignee-list-response">Risposta della lista degli assegnatari</span>

`GET /api/telemetry/issues/assignees?project_id=<project_id>` restituisce ogni
account a cui si possono assegnare problemi nel progetto:

```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"
    }
  ]
}
```

Aggiungi `response_version=2` per ottenere anche `teams`: ogni team
dell'organizzazione del progetto, con `team_id`, `slug` e `name`.

Se l'account non può leggere il progetto, la route restituisce `404` con
`code: not_found`.

### <span id="action-response">Risposta delle azioni</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` segue un attore o una sessione. Tratta `distinct_id` e
`session_id` come identificatori opachi. `session_id` e `trace_id` sono `null`
quando mancano. `span_id` è omesso quando manca. Un'azione non ha gravità.
Vedi [Eventi di prodotto](/it/guides/product-events).

### Risposta delle metriche

```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"
}
```

Ogni elemento è un campione. Non usare il numero di campioni come conteggio di
eventi o di utenti. `unit`, `temporality`, `trace_id` e `span_id` sono `null`
quando mancano. Un valore `null` non è zero.

### Risposta delle release

```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"
  }
}
```

Una riga copre un progetto, una release, un ambiente e un servizio. I suoi
conteggi descrivono solo quella riga.

`trace_health.status` è `unknown` quando la riga non ha tracce, altrimenti
`no_errors_observed` o `errors_observed`. `error_rate_basis_points` è la quota
di tracce con uno span di errore, da `0` a `10000`. Non è un tasso di errore
su tutte le richieste.

`next_action` punta al primo tipo di segnale che ha dati, in questo ordine:

| `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` |

Vedi [Release](/it/concepts/releases).

### Risposta della ricerca di tracce

`GET /api/telemetry/traces?pagination=cursor` restituisce una riga per ogni
traccia, più un resoconto `naming_quality` per la pagina restituita:

```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` copre solo la pagina restituita. Non è un punteggio
dell'intero account. `truncated: true` significa che esiste un'altra pagina.
Quando la pagina ha un nome generico, una route non riconosciuta o
un'operazione generica, `next_action` è `improve_trace_naming` con target
`sdk_configuration`. Senza `pagination=cursor`, la route restituisce un array
semplice di tracce, senza `naming_quality`.

`next_cursor` contiene `time` e `trace_id`. Inviali come `cursor_time` e
`cursor_trace_id`.

`GET /api/telemetry/traces/{trace_id}` restituisce gli span di una traccia.
`GET /api/telemetry/traces/{trace_id}/summary` restituisce lo span radice, gli
span di errore, i servizi, la durata e il percorso più lento, senza gli
attributi grezzi degli span. Un `404` sul riepilogo significa che nessuna
traccia corrisponde all'ambito completo. Non riprovare senza i filtri. Vedi
[risposte degli span e del riepilogo di una traccia](#trace-spans-and-summary-responses).

### Liste vuote e record mancanti

Una lettura di lista può non avere corrispondenze. Una lettura di dettaglio
segue un contratto diverso:

| Richiesta | Successo | Nessun record leggibile |
| - | - | - |
| `GET /api/logs/{log_id}` | `200` con un [log](#log-response) | `404` con `code: not_found` |
| `GET /api/telemetry/issues/{issue_id}` | `200` con un [problema](#issue-response) | `404` con `code: not_found` |
| `GET /api/telemetry/issues/{issue_id}/events` | `200` con le occorrenze | `404` con `code: not_found` sulla prima pagina |
| `GET /api/telemetry/traces/{trace_id}` | `200` con gli span | `200` con `[]` |
| `GET /api/telemetry/traces/{trace_id}/summary` | `200` con un riepilogo | `404` con `code: not_found` |

Un log mancante restituisce questo `404`:

```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"
  }
}
```

Un problema mancante usa `"error": "issue not found"`. Un riepilogo di traccia
mancante usa `"error": "trace not found"`. Un ID sconosciuto e un ID che
l'account non può leggere restituiscono la stessa risposta.

Una lista con un `project_id` che l'account non può leggere restituisce `200`
con una lista vuota. Controlla l'ID del progetto prima di segnalare che non
esistono dati.

### Selezioni di progetti rifiutate

Le liste di log, problemi, azioni, metriche, release e tracce accettano un
progetto con `project_id` oppure da 2 a 50 progetti con `project_ids`. Il
catalogo degli attributi dei log accetta gli stessi selettori. La cronologia
delle occorrenze di un problema non li accetta.

Una richiesta con sia `project_id` sia `project_ids` restituisce `422`:

```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"
  }
}
```

Anche `project_ids` con un UUID non valido, un ID ripetuto, meno di 2 o più di
50 ID restituisce `422` con `code: validation_failed`.

Se l'account non può leggere uno dei progetti di un insieme `project_ids`,
l'intera richiesta restituisce `404`. Non restituisce gli altri progetti come
risultato parziale:

```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"
  }
}
```

Mostra l'errore, non una lista vuota o un conteggio pari a zero. Leggi di
nuovo la lista dei progetti. Non rimuovere un progetto in silenzio e non
riprovare su tutti i progetti. Una credenziale delegata, come una connessione
MCP, restituisce `403` con `code: forbidden` per un progetto fuori dalla sua
connessione. Vedi
[ambito del progetto](/it/reference/telemetry-api-filters#project-scope).

### <span id="cursor-errors">Errori del cursore</span>

Log, problemi, azioni, metriche e occorrenze dei problemi usano `cursor_time` e
`cursor_id`. Un cursore rifiutato restituisce `422` con
`code: validation_failed`. Questi errori non significano che la lista sia
vuota.

| Richiesta | `error` |
| - | - |
| `pagination=cursor` con solo 1 dei 2 campi del cursore | `cursor_time and cursor_id must be sent together` |
| `cursor_time` che non è un timestamp RFC3339 | `cursor_time must be an RFC3339 timestamp` |
| Campi del cursore senza `pagination=cursor`, oppure con un altro valore di `pagination` | `pagination must be cursor when cursor pagination is requested` |

Per esempio:

```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"
  }
}
```

Copia l'intero `next_cursor` dalla pagina precedente. Non sostituire
`cursor_time` con l'ora attuale. Se hai perso il cursore, ricomincia con
`pagination=cursor` e i filtri originali. Una chiave di query sconosciuta o un
valore del tipo sbagliato restituisce `422` con
`"error": "invalid query parameters"`.

### Risposte del cursore delle release

Un cursore delle release ha 5 campi. Una richiesta riuscita senza
corrispondenze restituisce `200`:

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

Quando `next_cursor` non è `null`, invia tutti e 5 i valori nella richiesta
successiva:

| Campo di `next_cursor` | Parametro di query |
| - | - |
| `time` | `cursor_time` |
| `project_id` | `cursor_project_id` |
| `release` | `cursor_release` |
| `environment` | `cursor_environment` |
| `service_name` | `cursor_service_name` |

`cursor_project_id` indica una posizione. Non sostituisce `project_id` o
`project_ids`. Mantieni i parametri originali di progetto e di filtro. Codifica
ogni valore per l'URL.

Con `pagination=cursor`, un cursore parziale o un valore vuoto per release,
ambiente o servizio restituisce `422` con
`"error": "all release cursor fields must be sent together"`. Un
`cursor_time` non valido e un `pagination=cursor` mancante restituiscono gli
stessi errori degli [altri cursori](#cursor-errors).

### Errori della ricerca di tracce

Questi errori riguardano `GET /api/telemetry/traces`. Ognuno restituisce `422`
con `code: validation_failed`. Una richiesta rifiutata non è un risultato
vuoto.

| Richiesta | `error` |
| - | - |
| `status` diverso da `error` o `ok` | `trace status must be error or ok` |
| `min_duration_ms` sotto `0` | `minimum trace duration must not be negative` |
| Solo 1 campo del cursore, oppure un `cursor_trace_id` vuoto | `cursor_time and cursor_trace_id must be sent together` |
| `cursor_time` che non è un timestamp RFC3339 | `cursor_time must be an RFC3339 timestamp` |
| Campi del cursore senza `pagination=cursor` | `pagination must be cursor when cursor pagination is requested` |

Per includere entrambi gli stati delle tracce, ometti `status`. Per la pagina
successiva, copia `next_cursor.time` in `cursor_time` e `next_cursor.trace_id`
in `cursor_trace_id`. Non inviare `cursor_id` per una pagina di tracce. Vedi
[filtri delle tracce](/it/reference/telemetry-api-filters#trace-filters).

### <span id="issue-occurrence-history">Cronologia delle occorrenze di un problema</span>

`GET /api/telemetry/issues/{issue_id}/events` legge le occorrenze di un
problema raggruppato. Usa un token bearer dell'account e l'ID del problema
raggruppato. La route accetta solo `pagination`, `cursor_time`, `cursor_id` e
`limit`. Non accetta filtri di progetto, tempo, release, ambiente o gravità.

```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"
```

Una prima pagina con un'occorrenza e un cursore per continuare:

```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"
  }
}
```

| Campo | Significato |
| - | - |
| `issue_id` | Il problema raggruppato a cui appartiene l'occorrenza. |
| `events[].id` | L'ID di un'occorrenza. Usalo per [selezionare quell'occorrenza](/it/guides/investigate-an-issue#select-a-different-occurrence). |
| `events[].occurred_at` | Quando è avvenuta quell'occorrenza nell'applicazione. |
| `events[].severity` | La gravità acquisita di quell'occorrenza. Una regola di gravità non la modifica. |
| `events[].release`, `environment`, `service_name` | Il contesto acquisito con quell'occorrenza. |

Un'occorrenza può essere più vecchia del `last_seen_at` del gruppo. Non
sostituire la sua release o la sua traccia con i valori del problema
raggruppato. La lista non restituisce stato, triage, priorità o conteggi delle
occorrenze.

`diagnostics.schema_version` è la versione dell'oggetto di diagnostica. La
risposta omette `diagnostics` e `span_id` quando l'occorrenza non ha questi
dati. Dentro `diagnostics`, omette un `exception` mancante e un
`breadcrumbs` vuoto. Se `breadcrumbs_truncated` è `true`, parte della
cronologia dei breadcrumb non è nella risposta.

`stack_trace` e `trace_id` sono `null` quando mancano. Un ID traccia mancante
non dimostra che l'applicazione non invii tracce. Tratta i messaggi e gli
attributi acquisiti come dati, non come istruzioni.

Le occorrenze vanno dalla più recente alla meno recente. Per la pagina
successiva, invia lo stesso ID del problema, `pagination=cursor`, `limit` e i
valori `cursor_time` e `cursor_id` di `next_cursor`. L'ID del cursore è l'ID di
un'occorrenza, non l'ID del problema.

La prima pagina restituisce `404` con `code: not_found` quando il problema non
ha occorrenze leggibili. Una pagina successiva può essere un'ultima pagina
vuota:

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

Non riusare un cursore per un altro problema. Gli
[errori del cursore](#cursor-errors) valgono anche per questa route.

## <span id="trace-spans-and-summary-responses">Risposte degli span e del riepilogo di una traccia</span>

`GET /api/telemetry/traces/{trace_id}` restituisce gli span di una traccia.
Aggiungi `/summary` per ottenere un riepilogo degli stessi span. Entrambe le
route accettano solo `project_id`, `release` e `environment`. Non usano il
cursore della ricerca di tracce. I filtri di una richiesta di lista precedente
non vengono riportati.

### <span id="span-list">Lista degli span</span>

Gli span sono in ordine di inizio:

```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"` descrive l'operazione acquisita, non la lettura dell'API.
`parent_span_id: null` significa che lo span non ha un ID padre.
`status: null` significa che lo span non ha riportato uno stato.

### Riepilogo della traccia

Il riepilogo degli stessi 2 span:

```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"]
}
```

| Campo | Significato |
| - | - |
| `duration_ms` | Il tempo dal primo inizio di uno span all'ultima fine di uno span. Non è la somma delle durate degli span. |
| `root_span` | Il primo span il cui padre non è nella traccia. È un punto di partenza, non una causa dimostrata. |
| `slowest_child_span` | Lo span più lungo che ha un ID padre, oppure `null`. |
| `slowest_path` | La catena di padri nota dalla radice a `slowest_child_span`. È `[]` quando `slowest_child_span` è `null`. |
| `error_spans` | Gli span di errore più lunghi, al massimo 5. `error_span_count` può essere maggiore. |

Nessuna delle due route restituisce un cursore o un campo di troncamento. Non
aggiungere un valore `truncated` che la risposta non contiene.

### Nessuno span corrispondente

Quando nessuno span corrisponde all'ID traccia e all'ambito, la lista degli
span restituisce `200` con `[]`. Il riepilogo restituisce `404` con
`"error": "trace not found"` e `code: not_found`. Controlla l'ID traccia e
l'ambito. Non rimuovere i filtri per far comparire un risultato. Nessuno dei
due risultati dimostra che l'applicazione non abbia inviato telemetria.

## <span id="live-event-response-format">Formato delle risposte degli eventi in tempo reale</span>

Il flusso in tempo reale invia i nuovi eventi. Non ripropone gli eventi persi
dal client mentre era disconnesso. Usa le route di lista per leggere i record
esistenti.

### Crea un ticket di connessione

Invia `POST /api/feed/ticket` con un token bearer dell'account. La richiesta
non ha corpo.

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

Una risposta `200 OK` contiene il ticket nel campo `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"
  }
}
```

Il ticket è una credenziale di breve durata. Non scriverlo nei log e non
metterlo nel prompt di un agente. Apri la connessione prima che finisca
`expires_in_seconds`. La scadenza limita il momento in cui la connessione può
iniziare, non quanto resta aperta.

Un `401` significa che l'accesso dell'account non è valido. Accedi di nuovo
prima di richiedere un ticket. Un metodo diverso da `POST` restituisce `405`
con `code: method_not_allowed`.

### Apri la connessione

Collega un client WebSocket a
`wss://api.logbrew.co/api/feed/live?ticket=<feed-ticket>`. Codifica il ticket
per l'URL. Non mettere nell'URL un token bearer dell'account o un token bearer
di ingestione. Un `401` significa che il ticket o l'accesso dell'account non
è valido. Crea un nuovo ticket dopo aver eseguito di nuovo l'accesso.

| Risposta | Causa | Passo successivo |
| - | - | - |
| `422` con `"error": "feed ticket is required"` | Il valore di query `ticket` manca o è vuoto. | Crea un ticket e connettiti con quello. |
| `401` con `code: unauthorized` | Il ticket è scaduto o non è valido. | Crea un nuovo ticket. Non riprovare con lo stesso ticket. |
| `code: invalid_websocket_upgrade` | La richiesta non è un upgrade WebSocket valido. | Usa un client WebSocket. |
| `405` con `code: method_not_allowed` | La richiesta non usa `GET`. | Usa `GET` per la connessione. |

Attendi prima di riconnetterti dopo un errore. Non riconnetterti in un ciclo
stretto.

### Leggi i messaggi

Ogni messaggio è un envelope `{ "type": "...", "data": ... }`. Leggi `type`
prima di analizzare `data`. Salta i tipi che il client non supporta.

| Tipo di evento | Payload dei dati |
| - | - |
| `native_log` | Dati del log, con la forma della [risposta dei log](#log-response). |
| `native_issue` | Dati del problema raggruppato, con la forma della [risposta dei problemi](#issue-response) nella versione 1. |
| `native_trace_span` | Uno span, con la forma di un elemento della [lista degli span](#span-list). |
| `native_action` | Dati dell'azione di prodotto, con la forma della [risposta delle azioni](#action-response). |
| `project_created`, `project_updated`, `project_catalog_changed` | Dati del progetto. Leggi di nuovo la lista dei progetti quando cambia. |
| `usage_updated`, `usage_limit_warning`, `usage_limit_blocked` | Utilizzo dell'account, con la forma di [utilizzo dell'account](/it/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"
    }
  }
}
```

Un evento `native_issue` usa la versione 1 della risposta dei problemi: un
problema archiviato mostra `ignored` e l'evento non ha priorità. Metriche e
release non sono tipi di eventi in tempo reale. Leggile con le loro route di lista. Il
ticket non seleziona un progetto. Controlla il `project_id` di ogni evento
prima di mostrarlo nella vista di un progetto. `logbrew watch --json` usa
questo flusso. Vedi il [riferimento della CLI](/it/reference/cli).

### Gestisci una connessione chiusa

| Codice di chiusura | Motivo | Passo successivo |
| - | - | - |
| `1013` | `live feed fell behind; reconnect to resync` | Attendi, poi riconnettiti con un nuovo ticket. Leggi di nuovo le route di lista per recuperare i record persi. |
| `1008` | `live feed access changed; sign in again` | Smetti di riconnetterti. Accedi di nuovo prima di creare un nuovo ticket. |

Altre disconnessioni possono non avere un motivo LogBrew. Dopo esserti
riconnesso, leggi di nuovo le route di lista e abbina i record per ID.

## <span id="issue-status-response-examples">Esempi di risposte sullo stato dei problemi</span>

`PATCH /api/telemetry/issues/{issue_id}` con `{ "status": "resolved" }`
restituisce `200 OK` con il problema raggruppato aggiornato, con la stessa
forma della [risposta dei problemi](#issue-response). La chiave di query
`response_version` seleziona la versione. Non restituisce un flag di successo.

Il corpo imposta 1 o più campi tra `status`, `priority` e `assignee`. `status`
accetta `unresolved`, `resolved` o `archived`. `ignored` è un vecchio nome di
`archived`. Vedi [Aggiorna un problema](/it/reference/telemetry-api#update-one-issue).

Controlla `id`, `status` e `priority` restituiti prima di mostrare il
successo. Non costruire il risultato dai valori inviati. Un cambio di stato
non elimina occorrenze e non cambia `first_seen_at` e `last_seen_at`. Non
cambia `severity` né una regola di gravità.

Una modifica rifiutata restituisce `422` con `code: validation_failed`:

```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"
  }
}
```

| Risultato | Causa |
| - | - |
| `422`, `issue update requires status, priority, or assignee` | Il corpo non ha nessuno dei 3 campi. |
| `422`, `issue priority must be high, medium, or low` | Il valore della priorità non è supportato. |
| `422`, `issue assignee must be me, none, a user ID, or team:<team_id>` | Il valore dell'assegnatario non è supportato. |
| `422`, `issue assignee cannot read this project` | L'assegnatario non ha accesso al progetto. LogBrew non cambia nulla. |
| `422`, `issue assignee team is not a team of this project's organization` | Il team non appartiene all'organizzazione del progetto. LogBrew non cambia nulla. |
| `403` con `code: forbidden` | L'account non può gestire i problemi del progetto. |
| `404` con `code: not_found` | L'account non può leggere il problema, oppure il problema non esiste. |

Un campo che ha già il valore richiesto non cambia. Dopo un timeout o una
risposta persa, invia di nuovo la stessa richiesta oppure leggi prima il
problema. Non inviare una modifica diversa prima di aver letto lo stato
attuale. Vedi [Scritture](/it/reference/api-errors#writes).

`POST /api/telemetry/issues/bulk` restituisce `200 OK` con 1 risultato per
ogni ID di problema richiesto, nell'ordine della richiesta. Ogni problema
trovato usa la forma della versione 3. Un risultato `not_found` ha
`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
    }
  ]
}
```

Questo esempio mostra solo alcuni campi del problema. `outcome` è `updated`,
`unchanged` o `not_found`. Una richiesta ripetuta restituisce `unchanged` e
non cambia nulla. Vedi
[Aggiorna più problemi insieme](/it/reference/telemetry-api#update-issues-in-bulk).

Una richiesta multipla fallisce per intero in questi casi:

| Risultato | Causa |
| - | - |
| `422`, `issue_ids must name 1 to 100 issues` | La lista è vuota o ha più di 100 ID. |
| `422`, `issue_ids must not contain duplicates` | Un ID compare più di una volta. |
| `422` con `code: invalid_json` | Il corpo ha un campo sconosciuto. |
| `403` con `code: forbidden` | L'account non può gestire i problemi del progetto. |
| `404`, `project not found` | L'account non può leggere il progetto. |

## Ambito delle richieste di analisi

Le route di analisi, la route delle serie di metriche e la route del volume
dei segnali leggono un progetto e un intervallo di tempo. Ogni richiesta
richiede `project_id` e `since`. `since` accetta una durata compatta come
`24h` o `7d`, oppure un timestamp RFC3339. `until` accetta un timestamp
RFC3339 e per impostazione predefinita è l'ora della richiesta. L'intervallo
include `since`, esclude `until` e non può superare 31 giorni.

`service_name`, `release` e `environment` sono filtri esatti facoltativi. Ogni
valore deve avere da 1 a 256 caratteri dopo che LogBrew ha rimosso gli spazi
iniziali e finali. La route di confronto dei segmenti mette questi filtri
dentro ogni segmento, non al primo livello.

Se l'account non può leggere il progetto, queste route restituiscono `200 OK`
con conteggi a zero. Non restituiscono `404`. Un risultato vuoto non conferma
l'accesso al progetto. Confronta `project_id` con i progetti che l'account può
leggere. Una richiesta tramite una connessione MCP che non include il progetto
restituisce `403` e `forbidden`.

| Route | Valori di `response_version` | Predefinito |
| - | - | - |
| `GET /api/telemetry/analytics/overview` | `1`, `2` o `3` | `1` |
| `GET /api/telemetry/analytics/properties` | `1` o `2` | `1` |
| `POST /api/telemetry/analytics/segments/compare` | `1` o `2` | `1` |
| `POST /api/telemetry/analytics/retention` | `1` o `2` | `1` |
| `POST /api/telemetry/analytics/lifecycle` | `1` o `2` | `1` |
| `POST /api/telemetry/analytics/funnel` | Non accettato | Schema `1` |
| `POST /api/telemetry/analytics/paths` | Non accettato | Schema `1` |
| `GET /api/telemetry/metrics/series` | Non accettato | Schema `1` |
| `GET /api/telemetry/summary/volume` | `1` | `1` |

Ogni risposta inizia con `schema_version`, `query` e `purpose`. `query` riporta
l'ambito effettivo. Omette i filtri che non hai inviato. `purpose` è un testo
semplice che spiega a quale domanda risponde la route.

Un tasso è omesso quando il suo denominatore è zero. Un tasso omesso non è `0`
e non è `null`. Leggi `coverage` prima di fidarti di un tasso.

### <span id="shared-scope-errors">Errori comuni dell'ambito</span>

Questi errori usano HTTP `422` e `validation_failed`:

| Causa | `error` |
| - | - |
| Nessun `project_id` | `product analytics project_id is required` |
| Nessun `since` | `product analytics since is required` |
| `since` non è una durata o un timestamp RFC3339 | `invalid since value` |
| `until` non è un timestamp RFC3339 | `product analytics until must be an RFC3339 timestamp` |
| `since` non è precedente a `until` | `product analytics since must be earlier than until` |
| L'intervallo supera i 31 giorni | `product analytics range must not exceed 31 days` |
| Un filtro vuoto o più lungo di 256 caratteri | `product analytics context filters must be non-empty and at most 256 characters` |

Per esempio, una richiesta senza `project_id` restituisce:

```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" }
}
```

Le route delle serie di metriche e del volume dei segnali usano le stesse
regole di ambito, con un proprio testo di `error`. Le loro sezioni più sotto
elencano questi errori.

Una chiave di query sconosciuta restituisce `422` come descritto in [Parametri di query non validi](/it/reference/api-errors#invalid-query-parameters).
Un campo JSON sconosciuto, un campo JSON obbligatorio mancante o un valore
enum non supportato restituisce `invalid_json`. Vedi
[JSON non valido](/it/reference/api-errors#invalid-json). Una richiesta con il
metodo HTTP sbagliato restituisce `405` e `method_not_allowed`. Il suo testo
`next` indica il metodo e i campi supportati. Vedi
[Metodo non supportato](/it/reference/api-errors#unsupported-method).

## Risposta della panoramica di analisi di prodotto

`GET /api/telemetry/analytics/overview` mostra l'attività di un progetto:
volume delle azioni, utenti, sessioni, una serie temporale, le azioni
principali e le visualizzazioni di pagina, le visualizzazioni di schermata e
le interazioni classificate. Usala per trovare i nomi esatti degli eventi da
usare nelle altre route di analisi.

Invia `response_version=3`. Le versioni 1 e 2 restituiscono gli stessi
conteggi, ma il loro valore `estimation.method` è un token più vecchio. La
versione 1 non controlla il tipo di soggetto quando conta gli utenti
identificati. Le versioni 2 e 3 contano solo i soggetti di tipo `user` e
aggiungono i conteggi dei soggetti anonimi e `subject_coverage`.

Questa richiesta legge un'ora in fasce temporali di cinque minuti e
restituisce due righe in ogni lista dei principali:

```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"
```

### Panoramica riuscita

In questo risultato fittizio, il progetto ha 120 azioni in due delle dodici
fasce temporali. Venti azioni provengono da soggetti anonimi. Ogni azione ha
un ID di sessione. Metà delle azioni ha un ID traccia.

```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."
  }
}
```

### Leggi la panoramica

I cinque conteggi di `subject_coverage` sommati danno il totale degli eventi
della loro sezione. Solo `identified_user_events` conta per gli utenti.
`anonymous_actions` è `summary.actions` meno `identified_actions`.

`series` contiene solo le fasce temporali con attività. `expected_buckets` è
il numero di fasce temporali possibili nell'intervallo. Non disegnare una
fascia mancante come uno zero misurato, a meno che il grafico non dichiari
questa regola. Le fasce temporali sono allineate ai confini degli intervalli
UTC. Un intervallo che inizia dentro una fascia include quella fascia
parziale.

`classified_activity` conta visualizzazioni di pagina, visualizzazioni di
schermata e interazioni. Anche le visualizzazioni di schermata e le
interazioni sono azioni. Le visualizzazioni di pagina no. Non sommare
`summary.actions` a `classified_activity.summary.events`.

Copia `kind` e `event_name` da `classified_activity.top_events` nei passaggi
del funnel, nei selettori di fidelizzazione, nei selettori del ciclo di vita,
negli ancoraggi dei percorsi e nei target dei segmenti. Un valore `true` in
`top_events_truncated` significa che esistono nomi con volume più basso.
Aumenta `top_limit` fino a 20 per vederne altri.

`analysis_level` è `no_data`, `event_only`, `user_level` o
`user_and_session`. Se il progetto non ha azioni né eventi classificati,
`next_action.code` è `capture_product_activity`. Vedi
[Analisi di prodotto](/it/concepts/product-analytics#use-the-analytics-api).

### <span id="overview-errors">Errori della panoramica</span>

Oltre agli [errori comuni dell'ambito](#shared-scope-errors), la panoramica
restituisce `422` e `validation_failed` per questi valori:

| Valore | `error` |
| - | - |
| `response_version` diverso da `1`, `2` o `3` | `product analytics response_version must be 1, 2, or 3` |
| `top_limit` non compreso tra `1` e `20` | `product analytics top_limit must be between 1 and 20` |
| `interval` diverso da `auto`, `1m`, `5m`, `15m`, `1h`, `6h` o `1d` | `product analytics interval is not supported` |
| Un `interval` esplicito che richiede più di 500 fasce temporali | `product analytics interval would exceed 500 buckets` |

L'`interval` predefinito è `auto`. Seleziona l'intervallo più piccolo che
richiede al massimo 300 fasce temporali. Il `top_limit` predefinito è `10`.

## <span id="ordered-funnel-response">Risposta del funnel ordinato</span>

`POST /api/telemetry/analytics/funnel` misura il completamento in ordine di un
percorso da 2 a 8 passaggi. Copia ogni `kind` e `event_name` esatto da
`classified_activity.top_events` nella panoramica. Un nome di azione simile
non è una corrispondenza. Questo corpo della richiesta conta le sessioni che
visualizzano `/pricing` e poi completano la registrazione entro un'ora:

```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` è `session` o `identified_user`. Il valore predefinito è
`session`. Il `kind` di un passaggio è `page_view`, `screen_view` o
`interaction`. La route del funnel non accetta `response_version`.

### Funnel riuscito

Una risposta `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."
  }
}
```

I tassi sono frazioni da 0 a 1. Leggi `coverage` prima di fidarti di un tasso.
`selected_unit_coverage_rate` è la quota di eventi dei passaggi selezionati
che LogBrew ha potuto usare. La risposta non restituisce identità grezze. Vedi
[Analisi di prodotto](/it/concepts/product-analytics#measure-a-funnel).

### Leggi conversione e copertura

`entry_rate` è `entered_units` diviso `candidate_units`: 50 su 60.
`overall_conversion_rate` è `completed_units` diviso `entered_units`: 15 su
50, cioè il 30%. Non è 15 diviso tutti i candidati. Questi conteggi non
spiegano perché le unità si sono fermate.

La copertura conta eventi, non sessioni. Qui 120 eventi corrispondono a un
passaggio e 20 di questi non hanno un ID di sessione. Il risultato esclude
quei 20 eventi dai conteggi delle sessioni. Non trattarli come 20 sessioni
fallite.

Il primo passaggio non ha `conversion_from_previous`. L'ultimo passaggio non
ha `drop_off_to_next_units` né `drop_off_to_next_rate`.

Un'unità raggiunge un passaggio successivo solo quando gli orari dei passaggi
sono strettamente crescenti. Eventi con lo stesso timestamp non
possono soddisfare due passaggi consecutivi. L'ultimo passaggio deve avvenire
entro `conversion_window_seconds` dal primo.

La modalità per sessione conta sessioni, non persone. Usa `identified_user`
solo per eventi che portano un ID soggetto opaco di tipo `user`. Questa
modalità può unire eventi di sessioni diverse dentro la finestra di
conversione. Mantieni la stessa unità e gli stessi passaggi quando confronti i
risultati.

Il `conversion_window_seconds` predefinito è 24 ore oppure la durata
dell'intervallo, se più breve. Il massimo è la durata dell'intervallo in
secondi interi, arrotondata per eccesso.

### Risultati vuoti del funnel

Una risposta vuota riuscita elenca comunque i passaggi richiesti con `units`
a zero. Se non ci sono unità candidate, `summary` omette `entry_rate` e
`overall_conversion_rate`. La route non restituisce `404` perché nessun
evento corrisponde.

Leggi `coverage` e `next_action` per trovare la causa:

| `next_action.code` | Causa |
| - | - |
| `capture_product_activity` | Non esistono eventi classificati nell'ambito. |
| `choose_captured_funnel_steps` | Nessun evento corrisponde a un passaggio richiesto. |
| `sessionize_product_activity` | Esistono eventi dei passaggi, ma nessuno ha un ID di sessione. |
| `identify_product_users` | Esistono eventi dei passaggi, ma nessuno ha un soggetto di tipo `user`. |
| `verify_funnel_entry` | Nessuna unità è entrata al passaggio 1. |
| `investigate_funnel_drop_off` | Alcune unità sono entrate, ma nessuna ha completato tutti i passaggi. |
| `compare_funnel_contexts` | Almeno un'unità ha completato il funnel. |

### Richieste di funnel rifiutate

Oltre agli [errori comuni dell'ambito](#shared-scope-errors), queste richieste
restituiscono `422` e `validation_failed`. Meno di 2 o più di 8 passaggi:

```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" }
}
```

Un `conversion_window_seconds` pari a `0`, o un valore oltre la durata
dell'intervallo:

```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" }
}
```

Un `event_name` vuoto, più lungo di 256 caratteri o che contiene un carattere
di controllo restituisce
`product analytics funnel event_name must be non-empty, control-free, and at most 256 characters`.
Un passaggio `interaction` deve anche essere un nome di azione valido.
Altrimenti l'errore è `product analytics interaction event_name must be a bounded stable action name`.

Correggi la richiesta prima di inviarla di nuovo. Non rimuovere passaggi e non
cambiare l'unità di analisi solo per ottenere un risultato non vuoto.

## Analisi per eventi esatti e automatica

Fidelizzazione e ciclo di vita accettano due forme di richiesta. Usa
`response_version` per scegliere la forma che risponde alla tua domanda:

| Analisi | `response_version` | Selettori di eventi |
| - | - | - |
| Fidelizzazione per eventi esatti | `1`, oppure omesso | Invia sia `start_event` sia `return_event`. |
| Ciclo di vita per un evento esatto | `1`, oppure omesso | Invia `event`. |
| Fidelizzazione o ciclo di vita automatici | `2` | Non inviare selettori di eventi. |

Un selettore esatto contiene `kind` e `event_name`. `kind` è `page_view`,
`screen_view` o `interaction`. Copia `event_name` da
`classified_activity.top_events`. Non indovinare il nome di un evento
dall'etichetta di un pulsante.

Entrambe le forme contano solo gli utenti: ID soggetto opachi di tipo `user`.
I soggetti anonimi e gli eventi senza un ID soggetto utilizzabile non contano
come utenti. Le risposte non restituiscono mai ID soggetto.

Gli intervalli fissi sono `hour`, `day`, `week` e `thirty_day`. Sono durate
fisse. `thirty_day` è 30 giorni, non un mese di calendario. Se ometti
`interval`, l'API usa `hour` per un intervallo di 48 ore o meno e `day` per un
intervallo più lungo.

### Richiesta di fidelizzazione per eventi esatti

Invia questo corpo a `POST /api/telemetry/analytics/retention`. Chiede se gli
utenti completano un altro checkout dopo il loro primo checkout
nell'intervallo:

```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" }
}
```

Il primo evento iniziale corrispondente nell'intervallo fa da ancoraggio per
ogni utente. Un ritorno deve avvenire strettamente dopo quell'ancoraggio e
prima di `until`. Entrambi i selettori possono indicare lo stesso evento.

| Campo | Valori | Predefinito |
| - | - | - |
| `interval_count` | Da `1` a `31` periodi | `10` |
| `mode` | `return_on` conta un ritorno dentro ogni periodo esatto. `return_on_or_after` conta un ritorno all'inizio di ogni periodo o dopo. | `return_on` |
| `cohort_mode` | `first_in_range` | `first_in_range` |

### Fidelizzazione per eventi esatti riuscita

In questo esempio fittizio, due utenti completano il checkout. Il primo
utente completa il checkout alle 12:00 del 1° giugno e di nuovo alle 13:00. Il
secondo utente completa il checkout alle 12:00 del 2 giugno. Alle 13:00 del 2
giugno, il secondo utente visualizza una pagina ma non completa un altro
checkout.

```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."
  }
}
```

### Leggi la fidelizzazione

La copertura conta tutti e quattro gli eventi classificati, ma solo tre
corrispondono a ciascun selettore di checkout. La visualizzazione di pagina
non conta come ritorno. Uno dei due utenti ripete il checkout, quindi
`return_rate_after_start` è `0.5`.

Solo il primo utente ha un giorno intero di osservazione dopo l'ancoraggio.
Quell'utente ritorna entro il giorno, quindi il tasso della curva è `1.0`. Il
secondo utente ha solo 12 ore di osservazione. Quell'utente non è idoneo per
il periodo 0, quindi la cella della seconda coorte omette `retention_rate`.
Non contare quell'utente come perso.

`weighted_retention_rate` divide tutti gli utenti fidelizzati per tutti gli
utenti idonei. `fully_observed_cohort_average_rate` è la media semplice dei
tassi delle coorti in cui ogni utente è idoneo. Le coorti sono fasce
temporali fisse che iniziano da `since`. `cohorts` contiene solo le coorti che
hanno utenti.

Con `mode: "return_on_or_after"`, la curva omette `window_end_seconds`.

### Fidelizzazione automatica

Invia `response_version: 2` senza `start_event` né `return_event`. Ogni
visualizzazione di pagina, visualizzazione di schermata e interazione
supportata conta come inizio e come ritorno. Questa versione seleziona un
insieme di eventi. Non seleziona un formato di acquisizione dell'SDK.

```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"
}
```

La risposta ha le stesse forme di `summary`, `curve`, `cohorts` e
`next_action` della risposta per eventi esatti. Questo estratto mostra i campi
che cambiano. In questo esempio, gli stessi due utenti hanno tre eventi e
nessuna visualizzazione di pagina:

```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."
    ]
  }
}
```

In modalità automatica, `start_events` e `return_events` sono entrambi uguali
a `classified_events`. Questi conteggi sono eventi, non utenti.

### Fidelizzazione senza utenti idonei

Un risultato riuscito può non avere utenti nelle coorti. Questo estratto
mostra un periodo richiesto senza coorti:

```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": []
}
```

Leggi `coverage` e `next_action`. Distinguono un ambito senza eventi
classificati (`capture_product_activity`) da eventi senza utenti
(`identify_product_users` o `identify_returning_users`). Un tasso mancante non
è uno zero misurato.

### Errori di fidelizzazione

Oltre agli [errori comuni dell'ambito](#shared-scope-errors), queste richieste
restituiscono `422` e `validation_failed`:

| Causa | `error` |
| - | - |
| Versione 1 senza entrambi i selettori, versione 2 con un selettore o un'altra versione | `product analytics retention activity selection is contradictory` |
| `interval_count` non compreso tra `1` e `31` | `product analytics retention interval_count must be between 1 and 31` |
| Le fasce temporali delle coorti moltiplicate per `interval_count` superano 500 | `product analytics retention interval and interval_count would exceed 500 cohort matrix cells` |

Il limite di celle dipende dall'intervallo e dai periodi, non dal numero di
utenti. Un intervallo di 30 giorni con `interval: "hour"` ha 720 fasce
temporali di coorte. Con `interval_count: 1`, sono 720 celle, cioè più di 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" }
}
```

Per usare la fidelizzazione automatica, rimuovi entrambi i selettori. Non
modificare l'SDK per correggere questa richiesta di lettura.

### Richiesta del ciclo di vita per un evento esatto

Invia questo corpo a `POST /api/telemetry/analytics/lifecycle`. Classifica gli
utenti in base a un evento, non a tutta l'attività del progetto:

```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` imposta i periodi completi prima di `since` che LogBrew
legge come cronologia. Accetta da `2` a `31`. Il valore predefinito è `2`. Un
utente può essere inattivo per questo evento mentre svolge altre attività.

### Ciclo di vita per un evento esatto riuscito

Questo esempio fittizio usa due giorni di cronologia e due giorni di analisi.
Le lettere identificano solo gli utenti dell'esempio. La risposta non
restituisce ID utente.

| Data, UTC | Utenti che completano il checkout |
| - | - |
| 30 maggio, cronologia | B |
| 31 maggio, cronologia | A e D |
| 1° giugno, analisi | A, B e C |
| 2 giugno, analisi | A e B |

Il 2 giugno C visualizza anche una pagina. Quell'evento non corrisponde al
selettore di checkout.

```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."
  }
}
```

### Leggi il ciclo di vita

Il 1° giugno A è di ritorno, B è riattivato, C è nuovo e D è inattivo. Il 2
giugno A e B sono di ritorno, mentre C è inattivo per il checkout nonostante
la visualizzazione di pagina. La variazione netta del 2 giugno è
`2 - 3 = -1`.

In ogni fascia temporale, gli utenti nuovi, di ritorno e riattivati sommati
danno `active_subjects`. `returning_subjects` più `dormant_subjects` è uguale a
`previous_active_subjects`. `net_active_change` è `active_subjects` meno
`previous_active_subjects`.

Non sommare i conteggi giornalieri degli attivi per ottenere gli utenti
distinti. Qui i conteggi giornalieri sommati danno 5, ma
`analysis_active_subjects` è 3. Tra cronologia e analisi compaiono quattro
utenti distinti.

`fully_observed` è `false` per un'ultima fascia temporale che termina dopo
`until`. I suoi conteggi possono cambiare quando l'intero periodo diventa
osservabile. Il `next_action` suggerisce un'indagine. Non mostra una causa.

### Ciclo di vita automatico

Invia `response_version: 2` senza il selettore `event`. Ogni visualizzazione
di pagina, visualizzazione di schermata e interazione supportata conta come
attività:

```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
}
```

La risposta ha le stesse forme di `summary`, `buckets` e `next_action` della
risposta per eventi esatti. Questo estratto mostra i campi che cambiano:

```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."
}
```

In modalità automatica, `coverage.selected_events` è uguale a
`coverage.analysis_classified_events`. La quinta voce di `limitations` è
`Returning, resurrected, and dormant compare any supported classified product activity; no event is ranked, selected, or inferred.`

### Ciclo di vita senza utenti

Se né l'intervallo di analisi né la cronologia contengono utenti utilizzabili,
`buckets` è vuoto e `summary` omette `latest_fully_observed_period`:

```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": []
}
```

Gli utenti che compaiono solo nella cronologia possono comunque produrre fasce
temporali con utenti inattivi quando l'intervallo di analisi non ha attività.

### Errori del ciclo di vita

Oltre agli [errori comuni dell'ambito](#shared-scope-errors), queste richieste
restituiscono `422` e `validation_failed`:

| Causa | `error` |
| - | - |
| Versione 1 senza `event`, versione 2 con `event` o un'altra versione | `product analytics lifecycle activity selection is contradictory` |
| `history_period_count` non compreso tra `2` e `31` | `product analytics lifecycle history_period_count must be between 2 and 31` |
| Periodi di cronologia per un totale di oltre 62 giorni | `product analytics lifecycle history must not exceed 62 days` |
| Più di 100 fasce temporali di analisi | `product analytics lifecycle interval would exceed 100 analysis buckets` |

Per esempio, dieci periodi di cronologia `week` richiedono 70 giorni:

```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" }
}
```

### Leggi l'ambito di analisi selezionato

Le risposte per eventi esatti hanno `schema_version: 1`. Il loro `query`
riporta i selettori e omette `activity_scope`. Le risposte automatiche hanno
`schema_version: 2` e `query.activity_scope: "all_classified_activity"`.
Omettono i selettori. Un selettore diverso può cambiare il risultato anche se
l'attività acquisita non cambia.

## Risposta delle serie di metriche

`GET /api/telemetry/metrics/series` legge un nome di metrica esatto in un
progetto. Copia il nome da `GET /api/telemetry/metrics`. Questa richiesta
raggruppa un contatore delta per servizio:

```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"
```

### Serie di metriche riuscita

Questa risposta fittizia contiene una serie di un contatore delta. Tre
campioni con valori `2`, `3` e `5` cadono nella prima fascia temporale. Due
campioni con valori `1` e `4` cadono nell'ultima. Nessun campione cade nella
fascia centrale, quindi la risposta non ha un punto per quella fascia.

```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."
  }
}
```

### Leggi una serie di metriche

Il primo punto registra 10 job completati, non 10 campioni. `rate_per_second`
divide quella variazione per la fascia temporale di 300 secondi. `last` è
l'ultima variazione registrata, non la somma. Vedi
[significato delle aggregazioni delle metriche](/it/concepts/telemetry#read-the-metric-value).

Il tipo e la temporalità di una serie determinano il suo `aggregation.code` e
le statistiche di ogni punto. Un punto omette le statistiche che non si
applicano. Una statistica mancante non è zero.

| Tipo e temporalità | `status` | `aggregation.code` | `value` | Altre statistiche |
| - | - | - | - | - |
| `gauge`, `instant` | `ready` | `gauge_last` | Ultimo campione | `last`, `min`, `max`, `average` |
| `counter`, `delta` | `ready` | `delta_sum` | Somma delle variazioni | `last`, `min`, `max`, `average`, `sum`, `rate_per_second` |
| `histogram`, `delta` | `ready` | `distribution_p95` | p95 approssimativo | `min`, `max`, `average`, `sum`, `p50`, `p95`, `p99` |
| Qualsiasi tipo, `cumulative` | `limited` | `raw_cumulative_last` | Ultimo campione grezzo | `last`, `min`, `max` |
| Qualsiasi altra coppia | `limited` | `raw_last` | Ultimo campione grezzo | `last`, `min`, `max` |

`limited` è una risposta riuscita, non un errore. Aggiunge
`aggregation.limitation`, che spiega perché LogBrew mostra solo valori grezzi.
`ready` non dimostra un'acquisizione completa.

Leggi `coverage` prima di disegnare un grafico:

* `samples` conta i campioni di tutte le serie corrispondenti, incluse le serie
  che la risposta non restituisce.
* `series` conta le serie corrispondenti. `returned_series` e `points` contano
  i dati restituiti.
* `truncated` è `true` quando `series_limit` ha rimosso serie con volume più
  basso.
* `expected_buckets_per_series` è il numero di fasce temporali possibili
  nell'intervallo.

Non aggiungere un punto per una fascia temporale senza campioni. Non inserire
uno zero e non copiare il valore precedente. Ogni punto restituisce fino a 3
`trace_exemplars`. Un esemplare di traccia collega un campione a una traccia.
Non spiega tutti i campioni della fascia temporale. Se nessun punto ha un
esemplare di traccia, `next_action.target` è `metric_samples`.

### Ambito ed errori delle serie di metriche

`project_id`, `name` e `since` sono obbligatori. `name` può avere al massimo
200 caratteri. `interval` è `auto`, `1m`, `5m`, `15m`, `1h`, `6h` o `1d`. Il
valore predefinito è `auto`, che seleziona l'intervallo più piccolo con al
massimo 300 fasce temporali. Un intervallo esplicito non può richiedere più di
500 fasce temporali.

`group_by` è `none`, `service_name`, `release` o `environment`. Il valore
predefinito è `none`. Senza raggruppamento, tipi, unità e temporalità diversi
restano in serie separate. `series_limit` accetta da `1` a `20`. Il valore
predefinito è `10`.

Un risultato vuoto restituisce `200` con `series: []` e `samples` a zero.
L'oggetto `coverage` omette `first_seen_at` e `last_seen_at`. Questo non
dimostra che l'applicazione non abbia mai inviato la metrica. Controlla il
progetto, il nome della metrica e l'intervallo di tempo.

Se ometti `name`, la richiesta restituisce `422`:

```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" }
}
```

Fasce temporali di un minuto su sette giorni restituiscono `422`:

```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" }
}
```

Altri errori `422` sono `metric series group_by is not supported`,
`metric series interval is not supported` e
`metric series_limit must be between 1 and 20`.

## Risposta dell'analisi dei percorsi

`POST /api/telemetry/analytics/paths` trova gli eventi con nome che precedono
o seguono un evento selezionato nella stessa sessione. L'evento selezionato è
l'ancoraggio. Copia il suo `kind` e il suo `event_name` da
`classified_activity.top_events`. La route restituisce `schema_version: 1`.
Non accetta `response_version` né `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` e `anchor` sono obbligatori.

### Percorsi riusciti

In questo risultato fittizio, quattro sessioni contengono l'ancoraggio. I due
percorsi restituiti rappresentano tre di quelle sessioni. Un percorso in
posizione più bassa non viene restituito.

```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."
  }
}
```

### Leggi i percorsi

`share_of_anchored_sessions` divide le sessioni di un percorso per tutte e
quattro le sessioni con l'ancoraggio. Le quote sono 50% e 25%, non 67% e 33%.
`unrepresented_sessions` conta le sessioni con l'ancoraggio che nessun
percorso restituito rappresenta. `paths_truncated: true` significa che il
risultato è incompleto.

La copertura conta eventi, non sessioni. Qui cinque eventi corrispondono
all'ancoraggio, ma uno non ha un ID di sessione. Quell'evento non può entrare
in un percorso. Ogni percorso restituisce fino a 3 esemplari di traccia. Usa
un ID traccia della tua risposta. Un collegamento a una traccia non mostra che
cosa ha causato un'azione dell'utente o un errore.

| Campo | Significato |
| - | - |
| `following` | Inizia dal primo ancoraggio corrispondente in ogni sessione. L'ancoraggio ha posizione `0`. I nodi successivi hanno posizioni positive. |
| `preceding` | Termina all'ultimo ancoraggio corrispondente in ogni sessione. I nodi precedenti hanno posizioni negative. L'ancoraggio ha posizione `0`. |
| `depth` | Numero di nodi accanto all'ancoraggio, escluso l'ancoraggio. Da `1` a `8`. Il valore predefinito è `4`. Un percorso può avere meno nodi. |
| `collapse_repeated` | Unisce i nodi consecutivi con lo stesso tipo e lo stesso nome. Il valore predefinito è `true`. |
| `path_limit` | Numero massimo di percorsi restituiti, ordinati per numero di sessioni. Da `1` a `20`. Il valore predefinito è `10`. |

I nodi sono in ordine temporale in entrambe le direzioni. Un percorso non è la
riproduzione completa di una sessione. LogBrew legge al massimo 1024 eventi
con nome per sessione prima di selezionare l'ancoraggio: i primi eventi per
`following` e gli ultimi per `preceding`. Un ancoraggio fuori da questo limite
può essere omesso.

### <span id="filter-the-anchor-by-property">Filtra l'ancoraggio per proprietà</span>

Invia fino a quattro `property_filters`, ognuno con una `key` e un `value`
esatti. Copia la chiave dal [catalogo delle proprietà](#analytics-property-catalog).
I filtri si applicano solo all'ancoraggio, non agli eventi intorno. I valori
distinguono tra maiuscole e minuscole. Quando ci sono filtri, `query` li
riporta e `coverage.anchor_property_filters` indica:

| Campo | Significato |
| - | - |
| `context_events` | Eventi di ancoraggio nell'ambito prima dei filtri sulle proprietà. |
| `property_ready_events` | Eventi di ancoraggio che hanno tutte le chiavi richieste. |
| `missing_property_events` | Eventi di ancoraggio senza una o più chiavi richieste. |
| `matching_events` | Eventi di ancoraggio i cui valori corrispondono a tutti i filtri. |
| `nonmatching_value_events` | Eventi di ancoraggio che hanno tutte le chiavi ma un valore diverso. |
| `property_ready_rate` | `property_ready_events` diviso `context_events`. |
| `match_rate` | `matching_events` diviso `property_ready_events`. |

Chiavi mancanti e valori diversi richiedono correzioni diverse. Non sommarli.
L'oggetto è omesso quando la richiesta non ha filtri sulle proprietà.

### Percorsi vuoti e richieste rifiutate

Un array `paths` vuoto può essere una risposta `200` riuscita. Leggi
`summary`, `coverage` e `next_action`. Questi codici distinguono le cause:
`capture_product_activity`, `choose_captured_path_anchor`,
`capture_anchor_properties`, `improve_anchor_property_coverage`,
`verify_anchor_property_values`, `sessionize_product_activity` e
`narrow_or_move_path_anchor`.

Oltre agli [errori comuni dell'ambito](#shared-scope-errors), queste richieste
restituiscono `422` e `validation_failed`:

| Causa | `error` |
| - | - |
| `depth` non compreso tra `1` e `8` | `product analytics path depth must be between 1 and 8` |
| `path_limit` non compreso tra `1` e `20` | `product analytics path_limit must be between 1 and 20` |
| Più di quattro filtri sulle proprietà | `product analytics paths accept at most four exact anchor property filters` |
| Una chiave che non è nel catalogo delle proprietà | `product analytics path property keys must be supported privacy-safe keys` |
| La stessa chiave due volte | `product analytics path property keys must be unique` |
| Un valore vuoto, più lungo di 256 caratteri o con un carattere di controllo | `product analytics path property values must be non-empty, control-free, and at most 256 characters` |

Per esempio, `depth: 0` restituisce:

```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">Catalogo delle proprietà di analisi</span>

`GET /api/telemetry/analytics/properties` elenca le chiavi delle proprietà
presenti negli eventi di prodotto classificati di un progetto. Usa le chiavi
nei [confronti tra segmenti](#analytics-segment-comparison) e nei filtri
sull'ancoraggio dei percorsi. Il catalogo restituisce chiavi e conteggi. Non
restituisce mai valori delle proprietà o identità.

### Leggi le chiavi delle proprietà disponibili

Invia `project_id` e `since`. Puoi anche inviare `until`, `service_name`,
`release`, `environment`, `limit` e `response_version`. `limit` accetta da
`1` a `50` chiavi. Il valore predefinito è `20`. Invia `response_version=2`
per ottenere il valore pubblico di `estimation.method`.

```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"
```

### Catalogo delle proprietà riuscito

In questo risultato fittizio esistono 100 eventi classificati. Cinque di
questi sono stati acquisiti prima dell'indice delle proprietà attuale.

```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."
  }
}
```

### Interpreta il catalogo

`source` è `standard_context` per una chiave di contesto standard, come
`resource.runtime.name`, oppure `custom_tag` per una chiave che inizia con
`tag.`. `value_type` è sempre `string`. `properties` è ordinato per `events`,
dal valore più alto.

`tag.plan` è presente in 60 dei 100 eventi classificati. Ha circa 3 valori
distinti. Il descrittore non mostra quei valori. Usa i valori che conosci
dalla tua applicazione. Non indovinare un valore da un conteggio. Un evento
può avere diverse chiavi, quindi non sommare i conteggi `events` delle singole
chiavi.

| Campo | Significato |
| - | - |
| `summary.classified_events` | Eventi classificati nell'ambito. È il denominatore di ogni `coverage_rate`. |
| `summary.available_property_keys` | Numero stimato di chiavi distinte, non il numero di righe restituite. |
| `coverage.unindexed_events` | Eventi acquisiti prima dell'indice delle proprietà attuale. Non possono contribuire con chiavi. |
| `coverage.incomplete_index_events` | Eventi con una parte del contesto malformata o troncata. Le loro chiavi valide contano comunque. |
| `coverage.privacy_filtered_events` | Eventi da cui LogBrew ha rimosso chiavi di tag personalizzati sensibili. Non è un conteggio di chiavi. |
| `coverage.properties_truncated` | `true` quando esistono più chiavi di `limit`. Restringi l'ambito oppure aumenta `limit` fino a 50. |
| `coverage.values_returned` | Sempre `false`. |

Un array `properties` vuoto non dimostra che il progetto non abbia eventi di
prodotto. Leggi `summary`, `coverage` e `next_action`.

### Errori del catalogo delle proprietà

Oltre agli [errori comuni dell'ambito](#shared-scope-errors), `limit=0` o
`limit=51` restituisce `422`:

```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" }
}
```

Un `response_version` diverso da `1` o `2` restituisce
`product analytics response_version must be 1 or 2`. LogBrew controlla
`response_version` prima degli altri valori.

Una richiesta `POST` restituisce `405`:

```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">Confronto tra segmenti di analisi</span>

`POST /api/telemetry/analytics/segments/compare` confronta con quale frequenza
sessioni o utenti raggiungono un evento esatto in 2-4 segmenti di un progetto.
Un segmento seleziona gli eventi per servizio, release, ambiente e valori
delle proprietà. Il primo segmento è il riferimento.

### Definisci il confronto

Invia questo corpo JSON con l'autenticazione dell'account e
`Content-Type: application/json`. Qui `basic` e `premium` sono valori di piano
dell'applicazione di esempio, non piani LogBrew:

```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` e `segments` sono obbligatori. `analysis_unit` è `session` o
`identified_user`. Il valore predefinito è `session`, che conta sessioni, non
persone. `interval` accetta gli stessi valori della panoramica. Il valore
predefinito è `auto`.

Ogni segmento richiede una `key` univoca, una `label` e un insieme di filtri
diverso:

* `key`: da 1 a 32 byte. Inizia con una lettera ASCII minuscola o con una
  cifra. Usa solo lettere ASCII minuscole, cifre, `_` e `-`.
* `label`: da 1 a 80 caratteri, senza caratteri di controllo.
* `service_name`, `release`, `environment`: facoltativi. Ogni valore ha da 1 a
  256 caratteri, senza caratteri di controllo.
* `property_filters`: da 0 a 4 filtri. Ogni chiave può comparire una sola
  volta in un segmento. Un evento deve corrispondere a tutti i filtri del
  segmento. I valori distinguono tra maiuscole e minuscole, hanno da 1 a 256
  caratteri e LogBrew rimuove gli spazi iniziali e finali.

Un segmento senza filtri seleziona tutta l'attività classificata del progetto
nell'intervallo di tempo. I segmenti possono sovrapporsi. Un'etichetta o una
chiave diversa non rende validi due insiemi di filtri identici.

### Confronto tra segmenti riuscito

In questo risultato fittizio, il riferimento raggiunge il checkout in 10 sessioni
su 50. Il segmento premium lo raggiunge in 18 sessioni su 60.

```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."
  }
}
```

### Leggi tassi e differenze

`eligible_units` stima le sessioni o gli utenti con attività classificata nel
segmento. `reached_units` stima quanti di loro hanno raggiunto il target.
`reach_rate` è `reached_units` diviso `eligible_units`. Gli eventi senza l'ID
dell'unità selezionata non contano per queste unità.

Il tasso del riferimento è 20%. Il tasso premium è 30%. La differenza è di 10
punti percentuali. L'incremento relativo è 50%, non 10%. I piccoli errori
decimali derivano dall'aritmetica in virgola mobile. Arrotonda i tassi per la
visualizzazione, ma calcola con i valori restituiti. Il segmento di
riferimento non ha `comparison_to_baseline`. L'incremento relativo è omesso
quando il tasso di raggiungimento del riferimento è zero.

In `query`, un filtro di segmento che non hai inviato è `null`. Una lista
`property_filters` vuota è omessa.

`coverage.property_filters` ha gli stessi campi della
[copertura dei filtri sull'ancoraggio dei percorsi](#filter-the-anchor-by-property).
Qui `matching_events` è uguale a `classified_events`. Tieni separati chiavi
mancanti e valori diversi. I segmenti possono sovrapporsi e una sessione può
comparire in più fasce temporali. Non sommare i conteggi delle unità tra
segmenti o fasce temporali.

Il confronto è descrittivo. `confidence.causal_inference` è
`not_established` e `confidence.statistical_significance` è `not_tested`. Un
tasso del 30% contro il 20% non dimostra che un piano abbia causato più
checkout.

### Errori del confronto tra segmenti

Oltre agli [errori comuni dell'ambito](#shared-scope-errors), queste richieste
restituiscono `422` e `validation_failed`:

| Causa | `error` |
| - | - |
| Meno di 2 o più di 4 segmenti | `product analytics segment comparison requires two through four segments` |
| Due segmenti con la stessa chiave | `product analytics segment keys must be unique` |
| Due segmenti con gli stessi filtri | `product analytics segment filters must be unique` |
| Una chiave che non è composta da 1-32 byte consentiti | `product analytics segment keys must be 1 through 32 machine-safe bytes` |
| Un'etichetta vuota, troppo lunga o con un carattere di controllo | `product analytics segment labels must be non-empty, control-free, and at most 80 characters` |
| Un valore di filtro con un carattere di controllo | `product analytics segment filters must be control-free` |
| Più di quattro filtri sulle proprietà in un segmento | `product analytics segments accept at most four exact property filters` |
| Una chiave che non è nel catalogo delle proprietà | `product analytics segment property keys must be supported privacy-safe keys` |
| La stessa chiave di proprietà due volte in un segmento | `product analytics segment property keys must be unique within each segment` |
| Un valore di proprietà vuoto, troppo lungo o con un carattere di controllo | `product analytics segment property values must be non-empty, control-free, and at most 256 characters` |
| Un `response_version` diverso da `1` o `2` | `product analytics response_version must be 1 or 2` |

Gli errori di `interval` sono gli stessi degli [errori della panoramica](#overview-errors).

Per esempio, due segmenti con chiavi diverse e filtri identici restituiscono:

```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" }
}
```

Un'etichetta diversa o un ordine diverso dei filtri sulle proprietà non
cambia gli eventi selezionati. Un errore di validazione non è una prova che
nessun evento corrisponda.

Una richiesta `GET` restituisce `405`:

```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" }
}
```

## Risposta del volume dei segnali

`GET /api/telemetry/summary/volume` conta i segnali conservati per un progetto
e un intervallo di tempo. Richiede `project_id` e `since`. Non accetta
`project_ids`.

`until` non può essere nel futuro. Se lo ometti, la fine è l'ora della
richiesta. Un `since` compatto come `24h` conta all'indietro da `until`.
`interval` è `auto`, `1m`, `5m`, `15m`, `1h`, `6h` o `1d`. Il valore
predefinito `auto` seleziona l'intervallo più piccolo con al massimo 120 fasce
temporali. Una richiesta non può richiedere più di 500 fasce temporali.
L'unico `response_version` è `1`.

### Conteggi dei segnali

Questa risposta fittizia copre due fasce temporali di un minuto. La richiesta
è stata eseguita alle 12:02 UTC senza `until`. L'account ha una policy di
conservazione di 30 giorni. Leggi la policy e il limite restituiti. Non dare
per scontato che questi valori valgano per il tuo account.

```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"]
  }
}
```

### Leggi ogni conteggio nella sua unità

| Segnale | Cosa conta `total` | Non leggerlo come |
| - | - | - |
| `issues` | Occorrenze di problemi conservate | Problemi raggruppati o utenti coinvolti |
| `logs` | Eventi di log conservati | Richieste |
| `traces` | ID traccia univoci, contati al loro primo span conservato in questo intervallo | Span o totale delle tracce mai avviate |
| `actions` | Eventi di azione conservati | Utenti o sessioni |
| `metrics` | Punti di metrica conservati | La somma dei valori delle metriche |

`total` è la somma dei conteggi delle fasce temporali della serie. `peak` è il
conteggio più alto di una sua fascia. `non_empty_buckets` conta le fasce con un
conteggio superiore a zero. Le cinque serie compaiono sempre in questo ordine.
Non combinare conteggi di segnali diversi in un unico punteggio di impatto.

Le fasce temporali iniziano da `query.since`. Una fascia include il suo inizio
ed esclude la sua fine. L'ultima fascia può essere più breve dell'intervallo.
La risposta non ha una serie con il conteggio delle release. Non leggere
`release_volume_not_included` come zero release.

### Intervalli vuoti e accorciati

Se nessun segnale corrisponde, tutte e cinque le serie restano e i loro punti
hanno conteggi a zero espliciti. Una richiesta fallita è diversa. Non
sostituire un errore con un grafico pieno di zeri.

Confronta `query.requested_since` con `query.since`. Se la conservazione
accorcia l'intervallo, `coverage.retention.window_clipped` è `true` e
`limitations` contiene `retention_window_clipped`. Se non resta nulla
dell'intervallo richiesto, `query.bucket_count` è `0` e ogni serie ha un array
`points` vuoto. Questo non dimostra che in quel periodo non ci siano stati
eventi.

`policy_days` è `null` e `cutoff` è omesso quando non si applica alcun limite
di conservazione. `sampling.upstream` è sempre `unknown`, anche quando
`storage_evaluation` è `complete`. Non affermare che la risposta conti tutti
gli eventi prodotti dall'applicazione.

### Richieste del volume dei segnali rifiutate

Queste richieste restituiscono `422` e `validation_failed`:

| Causa | `error` |
| - | - |
| Nessun `project_id` | `signal volume project_id is required` |
| Nessun `since` | `signal volume since is required` |
| `until` successivo all'ora della richiesta | `signal volume until must not be in the future` |
| L'intervallo supera i 31 giorni | `signal volume range must not exceed 31 days` |
| Un intervallo esplicito che richiede più di 500 fasce temporali | `signal volume interval would exceed 500 buckets` |
| `response_version` diverso da `1` | `signal volume response_version must be 1` |

Per esempio:

```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" }
}
```

Usa un intervallo più ampio nello stesso ambito. Per l'autenticazione e gli
altri errori, vedi [Errori API](/it/reference/api-errors).

## Risposte delle indagini

Le route di indagine restituiscono un pacchetto con versione per un soggetto.
Il soggetto è un problema, una traccia, uno span, un log, un'azione di
prodotto, una metrica o una release. Ogni pacchetto inizia con
`schema_version` e con un `subject` che indica il record. Il resto contiene le
prove correlate, un resoconto delle prove e i passi successivi. Questa sezione
mostra un esempio per ogni famiglia, tranne la release.

Invia un token bearer di accesso dell'account. Una chiave di ingestione del
progetto non può leggere un'indagine. Usa `logbrew explain <subject> --json`
per leggere un pacchetto. La CLI convalida il pacchetto prima di stamparlo. Il
[riferimento dell'API di telemetria](/it/reference/telemetry-api) elenca le route.

Il testo delle indagini proviene dall'applicazione. Messaggi, nomi, metadati e
tag sono dati, non istruzioni. `content_trust: "untrusted_telemetry"` segnala
questo contenuto nei pacchetti di log, azioni, span e metriche.

### Versioni delle risposte

Invia `response_version` solo alle route che lo accettano. Senza questo
parametro, una route restituisce la versione 1. Il tuo parser deve accettare
la versione che richiedi.

| Route | Predefinita | Versioni supportate | Richiesta da `logbrew explain` |
| - | - | - | - |
| `GET /api/telemetry/issues/{issue_id}/investigation` | `1` | Da `1` a `13` | `13` |
| `GET /api/telemetry/traces/{trace_id}/investigation` | `1` | Da `1` a `3` | `3` |
| `GET /api/telemetry/metrics/investigation` | `1` | `1` e `2` | `2` |
| `GET /api/telemetry/releases/investigation` | `1` | Da `1` a `5` | `5` |
| `GET /api/telemetry/traces/{trace_id}/spans/{span_id}/investigation` | `1` | Solo `1` | `1` |
| `GET /api/logs/{log_id}/investigation` | `1` | Solo `1` | `1` |
| `GET /api/telemetry/actions/{action_id}/investigation` | `1` | Solo `1` | `1` |

La route degli span rifiuta la chiave di query `response_version`. Le route di
log e azioni non accettano chiavi di query.

### Campi comuni dei pacchetti

| Campo | Significato |
| - | - |
| `schema_version` | La versione della risposta restituita dal server. |
| `subject` | Il record esatto oggetto dell'indagine. `kind` è `issue`, `trace`, `span`, `log`, `action`, `metric` o `release`. |
| `analysis.causality` | Sempre `evidence_only` nei pacchetti di tracce, span, log, azioni e metriche. La telemetria correlata non dimostra una causa. |
| Oggetti collezione | Prove correlate come `{ "status", "items", "truncated" }`. |
| `timeline` | Le prove restituite, dalla meno recente alla più recente, con un proprio flag `truncated`. L'ordine non dimostra una causa. |
| `evidence` | Il resoconto delle prove. `status` è `complete` o `partial`. |
| `next_actions` | Letture suggerite in ordine di `priority`, a partire da `1`. Non sono state eseguite. |

Ogni collezione correlata riporta uno `status` di disponibilità:

| Stato | Significato | Comportamento del client |
| - | - | - |
| `available` | La lettura è terminata e ha restituito elementi. | Mostra gli elementi e il flag `truncated`. |
| `not_linked` | Il soggetto non ha un identificatore per questo collegamento, come un ID traccia. | Spiega che il collegamento manca. Non ricostruirlo dai timestamp. |
| `not_found` | La lettura è terminata e non ha trovato prove conservate. | Mostra un risultato vuoto. |
| `unavailable` | La lettura facoltativa non è riuscita. Il soggetto resta valido. | Lascia visibile il soggetto. Riprova più tardi. Non mostrare zero elementi come risultato. |

Il resoconto delle prove ha quattro liste ordinate di nomi di campo stabili:
`captured_fields`, `missing_fields`, `redacted_fields` e `truncated_fields`.
`status` è `complete` solo quando le ultime tre liste sono vuote. I dati
oscurati non sono dati mancanti. I dati troncati non sono dati completi. Non
completare un valore oscurato o troncato.

### Limiti delle indagini

Questi limiti valgono per una singola risposta. Un flag `truncated` o una voce
in `truncated_fields` indica che un limite ha omesso dei dati.

| Prove | Limite |
| - | - |
| Elementi correlati in una collezione | 20 |
| Span conservati letti per una traccia | 1.000 |
| Elementi della timeline | 50 per i pacchetti di log, azioni e span. 100 per i pacchetti di tracce e metriche. |
| Attributi strutturati, proprietà e metadati | 64 valori scalari, 4 livelli di oggetti o array, 16 elementi per array, 512 caratteri per stringa |
| Intervallo di tempo di correlazione | 5 minuti prima e dopo un log, un'azione o l'occorrenza del problema selezionata. Per una traccia o uno span, 5 minuti prima dell'inizio e dopo la fine, al massimo 24 ore. |

Ogni sezione di famiglia elenca i propri limiti.

### Risposta dell'indagine su un problema

Usa `GET /api/telemetry/issues/{issue_id}/investigation` per leggere le prove
di un'occorrenza di un problema raggruppato. La
[guida all'indagine sui problemi](/it/guides/investigate-an-issue) mostra in che
ordine leggere le prove. Richiedi la versione 13:

```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"
```

Le chiavi di query sono `response_version`, `selection` e `occurrence_id`.
`selection` è `recommended`, `first` o `latest`. I valori distinguono tra
maiuscole e minuscole. Nelle versioni da 2 a 13, se ometti il selettore viene
usato `recommended`. La versione 1 restituisce l'ultima occorrenza conservata
e non accetta selettori. I filtri della lista dei problemi non si applicano a
questa lettura.

<Accordion title="Esempio di indagine su un problema nella versione 13">
  Questa risposta fittizia `200 OK` ha un'occorrenza `TypeError` gestita con una
  traccia collegata. Non ha richiesta, breadcrumb, log correlati né prove di
  deploy, quindi `evidence.status` è `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>

| Campo | Versione | Significato |
| - | - | - |
| `subject` | 1 | Il problema raggruppato. `first_seen_at`, `last_seen_at` e `occurrence_count` descrivono il gruppo. |
| `event` | 1 | L'occorrenza selezionata: SDK, `context`, `exception`, `stack_frames` e `breadcrumbs`. Nella versione 1, `null` quando non è possibile leggere un'ultima occorrenza. |
| `cause` | 1 | `status` è `reported_hypothesis`, `evidence_only` o `unknown`. `signals` elenca i segnali osservati. |
| `fix` | 1 | Una posizione nel codice. `status` è `reported_location`, `observed_application_frame`, `observed_frame`, `observed_underlying_exception_frame` o `unknown`. |
| `impact` | 1 | I conteggi delle occorrenze e `user_impact`. `reported` contiene l'impatto segnalato dall'applicazione oppure `null`. |
| `correlations` | 1 | `trace`, `logs`, `actions`, `metrics` e `release`. |
| `occurrence_selection` | 2 | Il selettore richiesto, il motivo e i riepiloghi delle occorrenze selezionata, prima, ultima e consigliata. |
| `lifecycle` | 3 | `persisted_status`, `effective_status`, l'attività di stato e `regression`. `effective_status` può essere `regressed`. |
| `occurrence_analysis` | 4 | L'andamento delle occorrenze e le distribuzioni per release, ambiente, servizio e SDK. |
| `event.exception_chain` | 5 | Fino a 8 eccezioni collegate. `relationship` è `reported`, `cause`, `context`, `aggregate_member` o `suppressed`. |
| `event.request` | 6 | `method`, `route_template` e `response_status_code`. La chiave è assente quando non è stata acquisita alcuna richiesta. |
| `grouping` | 7 | La `strategy` di raggruppamento, i suoi `components` e l'uso dei frame dello stack. |
| `correlations.release.deployment_status` | 8 | Lo stato della ricerca del deploy. `deployment`, `time_since_deployment_ms` e `deployment_causality` compaiono solo quando è stato trovato un deploy. |
| `correlations.related_issues` | 9 | Altri problemi sulla stessa traccia. |
| `source_locator` | 10 | Repository, componente, revisione e file relativo al repository, quando LogBrew riesce a collegarli. |
| `reproduction` | 11 | `status` è `ready`, `partial` o `insufficient_evidence`. |
| Codice `verify_correction` di `next_actions` | 12 | Compare quando `reproduction.status` è `ready`. |
| `impact.user_impact.count_method` | 13 | Indica un conteggio distinto approssimativo come `approximate_distinct`. Le versioni precedenti usano un nome di valore più vecchio. `unavailable` significa nessun conteggio. |

Le chiavi di una versione successiva sono assenti in una versione precedente.
Non leggere una chiave mancante come `null`.

`subject.status` e gli stati di `lifecycle` indicano un problema archiviato
come `ignored`. Le risposte di lista e di dettaglio dei problemi usano
`archived` dalla versione di risposta 2 in poi.

Limiti dei problemi: la raccomandazione legge al massimo 50 occorrenze
conservate. L'andamento ha al massimo 30 fasce temporali. Ogni distribuzione
restituisce al massimo 10 valori. Uno stack ha al massimo 32 frame.

#### Errori delle richieste di indagine su un problema

Usa `selection` oppure `occurrence_id`. Non inviarli entrambi, nemmeno quando
selezionano la stessa occorrenza:

```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` | Causa | Ripristino |
| - | - | - | - |
| `422` | `selection and occurrence_id are mutually exclusive` | La richiesta ha entrambi i selettori. | Mantieni un solo selettore. |
| `422` | `issue occurrence selection requires response_version=2 through 13` | La richiesta ha un selettore e la versione 1, oppure nessuna versione. | Invia `response_version=13`. Mantieni il selettore. |
| `422` | `issue investigation response_version must be 1 through 13` | La versione è fuori intervallo. | Invia una versione supportata. |
| `422` | `invalid query parameters` | Una chiave sconosciuta, un UUID non valido, una versione non intera o un valore di `selection` sconosciuto. | Correggi la [query](/it/reference/api-errors#invalid-query-parameters). |
| `404` | `issue occurrence not found` | L'occorrenza non è nella cronologia conservata di questo gruppo. | Copia l'ID dell'occorrenza dagli eventi di questo problema. Non usare al suo posto `latest` o `recommended` senza approvazione. |
| `404` | `issue not found` | Nessun progetto leggibile ha questo problema. | Controlla l'account e l'UUID del problema. Non inviare l'UUID di un'occorrenza come ID del problema. |

Un'occorrenza mancante non significa che manchi il problema. Un `404` non
indica se un altro account può leggere il problema.

### Risposta dell'indagine su una traccia

Usa `GET /api/telemetry/traces/{trace_id}/investigation` per leggere una
traccia con il suo percorso di errore, il percorso più lento e i segnali
correlati. Le chiavi di query sono `response_version`, `project_id`, `release`
e `environment`. Sono tutte facoltative. Richiedi la versione 3:

```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"
```

La versione 2 aggiunge `cause` e `fix` a ogni problema correlato. La versione 3
aggiunge `span_id` a problemi, azioni e metriche correlati, quando è stato
acquisito.

<Accordion title="Esempio di indagine su una traccia nella versione 3">
  Questa risposta fittizia ha uno span server radice e uno span client fallito.
  Lo span fallito è anche lo span figlio più lento. Gli span non hanno contesto
  strutturato, quindi `spans.context` è mancante.

  ```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>

| Campo | Significato |
| - | - |
| `subject` | I totali della traccia calcolati dagli span analizzati. |
| `analysis.status` | `errors_observed`, `latency_focus` o `no_error_observed`. |
| `analysis.first_error_path` | La catena di padri nota dalla radice al primo span di errore. |
| `analysis.bottleneck_path` | La catena di padri nota fino allo span figlio più lento. |
| `spans.items[].roles` | Perché lo span è nell'anteprima: `root`, `first_error`, `error_path`, `bottleneck`, `bottleneck_path`, `error` o `slow`. |
| `correlations.window` | L'intervallo di tempo e gli ambiti di deploy usati per le letture correlate. |
| `correlations.issues`, `logs`, `actions`, `metrics` | Segnali con lo stesso ID traccia nell'intervallo. |

`trace.parentage` è mancante quando uno span indica un padre che LogBrew non
ha conservato. L'anteprima degli span ha al massimo 64 span. Ogni percorso di
analisi ha al massimo 64 span. Le letture correlate usano al massimo 8 ambiti
di deploy.

Una prossima azione con target `trace_span` indica uno `span_id` di questo
pacchetto. Per leggere quello span, chiama la route dello span con
`project_id`, `environment` e `release` dello span.

### Risposta dell'indagine su uno span

Usa `GET /api/telemetry/traces/{trace_id}/spans/{span_id}/investigation` per
leggere un'operazione in una traccia. Invia `project_id`, `environment` e
`release`. Sono obbligatori tutti e tre. Copiali dallo span selezionato. Non
inviare l'`id` della riga dello span come `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="Esempio di indagine su uno span">
  Questa risposta fittizia descrive lo span client fallito dell'esempio della
  traccia. Un log di errore ha lo stesso ID span. Lo span è durato più del 95°
  percentile approssimativo degli span simili conservati.

  ```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>

| Campo | Significato |
| - | - |
| `payload` | I `metadata` dello span, fino a 8 `events` e fino a 8 `links`. Condividono un unico limite di 64 valori. |
| `analysis.observations` | `subject_error`, `child_error`, `exact_span_error_log`, `related_issue`, `subject_at_or_above_peer_p95` o `subject_at_or_above_peer_p99`. |
| `topology` | `root`, `parent`, `ancestors`, `children` diretti, `descendant_count` e `cross_service_edges`. |
| `topology.parent_chain_status` | `root`, `complete`, `missing`, `cycle`, `truncated` o `unavailable`. |
| `baseline` | Span precedenti con stesso progetto, ambiente, release, servizio, operazione e nome. |
| `correlations.logs` | Log con lo stesso ID traccia e lo stesso ID span. |
| `correlations.issues`, `actions`, `metrics` | Segnali con lo stesso ID traccia nello stesso progetto, ambiente e release. |
| `timeline[].offset_ms` | Millisecondi dall'inizio dello span. Un valore negativo è precedente allo span. |

Il riferimento legge le 24 ore prima dell'inizio dello span. `since` è
incluso e `until` è escluso. `error_rate_basis_points: 500` significa 5%.
`subject_percentile_basis_points: 9500` significa che il 95% degli span simili
conservati non è durato più di questo span. I percentili sono approssimativi.
Tieni `baseline.limitations` insieme ai valori. Un riferimento `not_found` non
ha span simili conservati. Un riferimento `unavailable` è una lettura non
riuscita, non un conteggio pari a zero.

`parent_chain_status: "complete"` significa che la catena conservata arriva a
una radice. Non dimostra che LogBrew abbia conservato tutti gli span della
richiesta. La topologia restituisce al massimo 64 antenati, 50 figli diretti e
50 collegamenti tra servizi.

| HTTP | `error` | Ripristino |
| - | - | - |
| `422` | `trace_id must be a non-zero 32-character hexadecimal value` | Copia `trace_id` da una risposta LogBrew sulle tracce. |
| `422` | `span_id must be a non-zero 16-character hexadecimal value` | Copia `span_id` da una risposta LogBrew sulle tracce. |
| `422` | `environment and release must be non-empty exact span scope values` | Copia l'ambito dallo span selezionato. |
| `422` | `invalid query parameters` | Invia `project_id`, `environment` e `release`, senza altre chiavi. |
| `404` | `span not found` | Controlla gli ID, il progetto, l'ambiente e la release. |

### Risposta dell'indagine su un log

Usa `GET /api/logs/{log_id}/investigation` per leggere un log e le prove
correlate. Questa route non ha chiavi di query. Copia l'ID del log da una lista
di log.

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

La lettura può restituire prove fuori dai filtri della lista dei log. Le
letture correlate usano progetto, ambiente e release del log, e i 5 minuti
prima e dopo il log. Anche i log vicini usano lo stesso servizio. Non
richiedono un ID traccia. Le letture sulla traccia esatta richiedono l'ID
traccia del log e possono includere altri servizi. Il riepilogo della traccia
usa lo stesso ID traccia e lo stesso ambito, senza l'intervallo di tempo.

<Accordion title="Esempio di indagine su un log">
  Questa risposta fittizia ha un log di avviso senza contesto di traccia e un log
  vicino. La risposta non ricostruisce un collegamento a una traccia dai
  timestamp.

  ```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>

| Campo | Significato |
| - | - |
| `attributes` | Gli attributi strutturati entro i limiti. `values` esclude `context`, che si trova nel campo `context` di primo livello. |
| `analysis.status` | `critical_evidence`, `error_evidence`, `warning_evidence` o `no_failure_observed`. |
| `correlations.trace` | L'ID traccia, l'ID span, `exact_span` e il `summary` della traccia. |
| `correlations.trace_logs` | Log con lo stesso ID traccia. `relationship` è `exact_trace`. |
| `correlations.nearby_logs` | Log dello stesso servizio nell'intervallo. `relationship` è `nearby_scope`. Esclude il soggetto e i log della traccia esatta. |
| `correlations.issues`, `actions`, `metrics` | Segnali con lo stesso ID traccia. |
| `correlations.release` | L'ambito della release per un'indagine sulla release. Non contiene un confronto. |
| `timeline[].relationship` | `subject`, `exact_span`, `exact_trace` o `nearby_scope`. |

Un ID traccia può essere presente anche quando lo stato della traccia è
`not_found` o `unavailable`. Un riepilogo della traccia disponibile non
garantisce un `exact_span`.

### Risposta dell'indagine su un'azione

Usa `GET /api/telemetry/actions/{action_id}/investigation` per leggere
un'azione di prodotto, il suo stato riportato e le prove correlate. Questa
route non ha chiavi di query. Le letture correlate usano lo stesso intervallo e
gli stessi ambiti di un'indagine su un log.

```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` e `next_actions` usano le forme dell'indagine su un
log. Le azioni correlate escludono l'azione oggetto dell'indagine.

<Accordion title="Esempio di indagine su un'azione">
  Questa risposta fittizia descrive un'azione di checkout fallita di un utente
  che ha eseguito l'accesso. L'azione non ha un ID traccia.

  ```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>

| Campo | Significato |
| - | - |
| `subject.status` | `queued`, `running`, `success`, `failure` oppure `null` quando non è stato acquisito uno stato supportato. |
| `subject.subject_classification` | `user`, `anonymous`, `legacy_unknown`, `missing`, `historical_unindexed` o `unsupported`. |
| `subject.session_captured` | Indica se l'azione aveva una sessione. La risposta non restituisce mai l'ID della sessione. |
| `properties` | L'oggetto `metadata` dell'azione, entro i limiti. |
| `analysis.status` | `subject_failure`, `correlated_failure_evidence`, `in_progress`, `success_observed` o `status_not_captured`. |

La risposta non restituisce mai identificatori di soggetto o di sessione. Il
resoconto delle prove elenca sempre `subject.distinct_id` come oscurato, e
`subject.session_id` quando è stata acquisita una sessione. Per questo motivo
ogni pacchetto di azione è `partial` e include `improve_capture`. Non
rimuovere i controlli sulla privacy per soddisfarlo.

### Risposta dell'indagine su una metrica

Usa `GET /api/telemetry/metrics/investigation` per leggere un nome di metrica
in un progetto e in un intervallo di tempo. La risposta contiene la serie
attuale, un confronto con l'intervallo precedente di pari durata, l'ultimo
campione, gli esemplari di traccia e i deploy completati. La versione 2
aggiunge la descrizione della metrica presa dall'ultimo campione conservato.
La versione 1 riporta sempre `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` e `since` sono obbligatori. `since` è incluso e `until`
è escluso. Per impostazione predefinita `until` è l'ora attuale. Il confronto
legge anche l'intervallo precedente di pari durata.

<Accordion title="Esempio di indagine su una metrica nella versione 2">
  Questo istogramma fittizio ha 5 campioni in due fasce temporali di 5 minuti.
  L'ultima fascia ha un p95 di 48 ms. L'ultima fascia dell'intervallo
  precedente ha un p95 di 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>

| Campo | Significato |
| - | - |
| `subject.description_status` | `captured`, `not_captured` o `unavailable`. |
| `query` | La query normalizzata. `service_name`, `release` e `environment` compaiono solo se inviati. |
| `analysis.status` | `no_samples`, `change_observed`, `no_change_observed`, `baseline_not_found` o `comparison_unavailable`. |
| `analysis.focus` | L'elemento del confronto con la variazione relativa più grande, oppure con la variazione assoluta più grande quando non esiste una variazione relativa. `null` quando nessun elemento è confrontabile. |
| `series[].aggregation.code` | `gauge_last`, `delta_sum`, `distribution_p95`, `raw_cumulative_last` o `raw_last`. |
| `comparison.status` | `available`, `partial`, `not_found`, `unavailable` o `no_current_samples`. |
| `comparison.items[]` | L'ultima fascia temporale non vuota di ogni intervallo per la stessa identità di serie. |
| `latest_sample` | L'ultimo campione grezzo, con SDK, `context`, `metadata` e collegamento alla traccia. |
| `exemplars` | Campioni grezzi con un ID traccia. `coverage` conta i campioni collegati. |
| `deployments` | I deploy completati dall'inizio dell'intervallo precedente fino a `until`. |
| `next_actions[]` | `code`, `target`, un `reason` in testo semplice e un ambito `context` per la lettura successiva. |

`relative_change_percent` è `(current - previous) / abs(previous) * 100`.
È `null` quando il valore precedente è zero o mancante.
`expected_buckets_per_series` conta le fasce temporali possibili, non quelle
con dati. Non disegnare le fasce vuote come zero. Un deploy vicino a una
variazione non dimostra di averla causata.

Un progetto che l'account non può leggere restituisce `200 OK` con
`analysis.status: "no_samples"`, non `404`. Un risultato vuoto non descrive
gli altri tipi di segnale.

Limiti delle metriche: l'intervallo è al massimo di 31 giorni. Ogni serie ha
al massimo 500 fasce temporali. `series_limit` va da 1 a 20, con 10 come
valore predefinito. La risposta restituisce al massimo 20 esemplari e 20
deploy.

| HTTP | `error` | Ripristino |
| - | - | - |
| `422` | `metric investigation response_version must be 1 or 2` | Ometti `response_version` oppure invia `2`. |
| `422` | `metric series project_id is required` | Invia l'ID di un progetto leggibile. |
| `422` | `metric series name is required` | Copia il nome dalla lista delle metriche. |
| `422` | `metric series since is required` | Invia un valore come `24h` o un timestamp RFC 3339. |
| `422` | `metric series range must not exceed 31 days` | Usa un intervallo più breve. |
| `422` | `metric series interval would exceed 500 buckets` | Usa `interval=auto` o un intervallo più ampio. |
| `422` | `metric series_limit must be between 1 and 20` | Invia un valore da 1 a 20. |

`interval` è `auto`, `1m`, `5m`, `15m`, `1h`, `6h` o `1d`. `group_by` è
`none`, `service_name`, `release` o `environment`. Altri valori restituiscono
`422`.

### Errori delle indagini

| HTTP | Route | `error` |
| - | - | - |
| `404` | Log | `log not found` |
| `404` | Azione | `action not found` |
| `404` | Traccia | `trace not found` |
| `422` | Traccia | `trace investigation response_version must be 1, 2, or 3` |
| `400` | Log, azione, problema | `invalid URL path parameters` quando l'ID nel percorso non è un UUID |
| `422` | Problema, traccia, span, metrica | `invalid query parameters` per una chiave sconosciuta o un valore del tipo sbagliato |

Un `404` significa che nessun progetto leggibile contiene il record. Ogni
route restituisce anche `401` senza un'autenticazione valida e `405` per un
metodo diverso da `GET`. Vedi [Errori API](/it/reference/api-errors) per le
risposte di
[risorsa non trovata](/it/reference/api-errors#resource-not-found),
[percorso](/it/reference/api-errors#invalid-path-value),
[autenticazione](/it/reference/api-errors#authentication-failure) e
[metodo](/it/reference/api-errors#unsupported-method).

Una lettura facoltativa delle prove può fallire dentro una risposta `200 OK`.
In quel caso la collezione riporta `unavailable`. Non mostrarla come
`not_found` o come zero record.

## <span id="severity-values">Valori di gravità</span>

I valori di gravità mostrati agli utenti sono `info`, `warning`, `error` e
`critical`. SDK e runtime possono inviare alias comuni come `trace`, `debug`,
`warn` o `fatal`. Le risposte REST e in tempo reale restituiscono sempre il valore
canonico. Per esempio, LogBrew accetta `warn` in ingresso e restituisce
`warning`. L'ingestione rifiuta i valori di gravità sconosciuti.

| Alias | Valore canonico |
| - | - |
| `trace`, `debug` | `info` |
| `warn` | `warning` |
| `fatal` | `critical` |

## <span id="severity-rule-responses">Risposte delle regole di gravità</span>

Una regola di gravità cambia il modo in cui LogBrew mostra un log o un
problema. Non cambia la gravità acquisita dall'applicazione. Log e problemi
restituiscono un oggetto `triage`:

| Campo | Significato |
| - | - |
| `effective_severity` | La gravità da mostrare. Senza una regola, è uguale a `severity`. |
| `ignored` | `true` quando una regola dei log ignora il log, oppure quando il problema è archiviato. |
| `rule_applied` | `true` quando si applica una regola di gravità o lo stato ignorato. `false` è il valore predefinito, non un dato mancante. |

Usa `triage.effective_severity` per la visualizzazione. Mantieni `severity`
come valore acquisito. Per impostazione predefinita, la lista dei log omette i
log ignorati. Invia `status=ignored` o `status=all` su `GET /api/logs` per
includerli.

L'account deve avere il permesso di gestire i problemi nel progetto. L'accesso
in lettura non basta. Senza questo permesso, una modifica alla regola
restituisce `403` con `code: forbidden`.

### Modifica una regola dei log

`PUT /api/logs/{log_id}/triage-rule` imposta la regola per il log e per i log
successivi con la stessa firma. Il corpo richiede sia `severity` sia
`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 }'
```

Una risposta `200 OK` contiene il [log](#log-response) completo. Il suo
`severity` resta `warning`. Il suo `triage` mostra la regola:

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

Questo estratto mostra solo i campi modificati. Nella richiesta, `severity` è
`source`, `info`, `warning`, `error` o `critical`. `source` ripristina la
gravità acquisita. Non riattiva un log ignorato. Per mostrare di nuovo il log,
invia `"ignored": false`.

### Modifica una regola dei problemi

`PUT /api/telemetry/issues/{issue_id}/triage-rule` imposta la gravità mostrata
per un problema raggruppato e per le sue occorrenze successive. Il corpo
accetta solo `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" }'
```

Una risposta `200 OK` contiene il [problema](#issue-response) completo nella
versione 1. Il `severity` acquisito e lo `status` non cambiano:

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

Questo estratto mostra solo alcuni campi. Una regola non risolve, non archivia
e non riapre un problema. Per questo usa il
[cambio di stato](#issue-status-response-examples). Una priorità derivata
segue la nuova gravità effettiva. Leggi il problema con `response_version=2` o
`3` per vederla.

Una gravità non supportata restituisce `422`:

```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"
  }
}
```

Un campo sconosciuto nel corpo, come `status` in una regola dei problemi,
restituisce `422` con `code: invalid_json`. Un log o un problema mancante o
illeggibile restituisce `404` con `code: not_found`. Se la risposta va persa,
leggi di nuovo il log o il problema prima di inviare di nuovo la regola.

## Formato delle risposte di errore

Gli errori dell'applicazione restituiscono un envelope JSON. Questo esempio
mostra una richiesta rifiutata; il testo di `error` e di `next` dipende
dall'errore:

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

Usa `code` per le diramazioni del programma e `next_action` per
l'automazione. Mostra `error` e `next` alle persone come testo semplice. Non
analizzarne la formulazione. Alcuni errori aggiungono campi, come `limit`,
`reset_at` o `retry_after_seconds`. Una risposta senza corpo JSON non ha un
`code` LogBrew. Vedi [Errori API](/it/reference/api-errors) per tutti i
codici.

## Leggi i dati con la CLI

La CLI legge le stesse route e restituisce lo stesso JSON con `--json`. Inizia
con una ricerca ampia, poi restringi:

```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
```

Aggiungi `--pagination cursor` per ottenere l'envelope con cursore. La CLI
richiede la versione 4 della risposta dei problemi. Vedi
[Leggi la pagina successiva](/it/reference/cli#read-the-next-page) e
[Monitoraggio in tempo reale](/it/reference/cli#live-watch).


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