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

# Analytics API

> Lesen Sie Ihre Konversationsanalysen: aggregierte Kennzahlen pro Agent und Kanal sowie die Details jeder Konversation

Die Analytics API ist ein schreibgeschützter Endpoint, der die Konversationsdaten Ihres Unternehmens zurückgibt. Sie hat zwei Modi:

* **`type=metrics`**: aggregierte Zahlen pro Agent und Kanal (Konversationen, Weiterleitungen an einen Menschen, KI-Quote ohne Weiterleitung, Anrufdauer, WhatsApp-Benachrichtigungen, erneute Kontaktaufnahmen sowie Tages- und Stundenreihen). Verwenden Sie diesen Modus für Berichte und Dashboards.
* **`type=chats`**: eine Zeile pro Konversation mit allen Parametern, paginiert. Verwenden Sie diesen Modus, um die Rohdaten zu exportieren oder abzugleichen.

## 🔑 Authentifizierung

Jede Anfrage benötigt einen API-Schlüssel mit der Berechtigung **`analytics_api`**. Fordern Sie ihn beim Lovi-Team an; er unterscheidet sich vom Schlüssel des Web-Widgets.

Senden Sie den Schlüssel im Header `x-api-key` (empfohlen) oder als Query-Parameter `access_key`.

```bash theme={null}
curl -H "x-api-key: YOUR_API_KEY" \
  "https://cloud.lovi.ai/functions/v1/analytics?type=metrics&date_from=2026-10-01&date_to=2026-10-31"
```

> [!NOTE]
>
> Das Unternehmen wird immer aus dem Schlüssel abgeleitet. Ein Schlüssel kann nur die Daten des eigenen Unternehmens lesen, und es gibt keinen Parameter, um ein anderes auszuwählen.

## Endpoint

```
GET https://cloud.lovi.ai/functions/v1/analytics
```

### Query-Parameter

| Parameter | Erforderlich | Beschreibung |
| - | - | - |
| `type` | Ja | `metrics` oder `chats`. |
| `date_from` | Ja | Erster Tag, `YYYY-MM-DD`, einschließlich. |
| `date_to` | Ja | Letzter Tag, `YYYY-MM-DD`, einschließlich. Der Zeitraum darf bis zu **31 Tage** umfassen. |
| `tz` | Nein | IANA-Zeitzone, mit der die Tage interpretiert und die Tages- und Stundenreihen erstellt werden. Standard `Europe/Madrid`. Beispiele: `UTC`, `America/Bogota`. |
| `channels` | Nein | Durch Kommas getrennte Kanäle: `voice`, `whatsapp`, `web`, `instagram`, `facebook`… |
| `agents` | Nein | Durch Kommas getrennte Agent-IDs (UUID). |
| `languages` | Nein | Durch Kommas getrennte Sprachcodes des Nutzers, z. B. `es,pt`. |
| `limit` | Nein | Nur `chats`. Konversationen pro Seite, 1–100. Standard 100. |
| `cursor` | Nein | Nur `chats`. Der `next_cursor` der vorherigen Seite. |

Die Tage werden in `tz` interpretiert: `date_from=2026-10-01&date_to=2026-10-31` mit `tz=Europe/Madrid` deckt den Zeitraum vom 1. Oktober 00:00 Uhr bis zum 1. November 00:00 Uhr Madrider Zeit ab. Sommerzeitumstellungen werden automatisch berücksichtigt.

Alle Zeitstempel in den Antworten sind **UTC** (ISO 8601 mit der Endung `Z`).

## Kennzahlen (`type=metrics`)

Gibt einen Eintrag pro Agent und Kanal zurück, sortiert nach Anzahl der Konversationen.

```bash theme={null}
curl -H "x-api-key: YOUR_API_KEY" \
  "https://cloud.lovi.ai/functions/v1/analytics?type=metrics&date_from=2026-10-01&date_to=2026-10-31&channels=voice"
```

```json theme={null}
{
  "tz": "Europe/Madrid",
  "from": "2026-09-30T22:00:00.000Z",
  "to": "2026-10-31T23:00:00.000Z",
  "data": [
    {
      "agent": { "id": "2fef9696-0662-4e49-bb83-7564ff25c7ef", "name": "Voice assistant" },
      "channel": "voice",
      "conversations": 12480,
      "escalated": 4120,
      "contained_pct": 67.0,
      "avg_duration_s": { "all": 109, "without_transfer": 120, "with_transfer": 86 },
      "whatsapp_notifications": 1210,
      "unique_users": 7950,
      "recontacts": 2480,
      "daily": [
        { "date": "2026-10-01", "conversations": 410, "escalated": 151 }
      ],
      "hourly": [
        { "hour": 9, "conversations": 1320 },
        { "hour": 10, "conversations": 1544 }
      ]
    }
  ]
}
```

| Feld | Beschreibung |
| - | - |
| `agent` | KI-Agent, der die Konversationen bearbeitet hat (`id`, `name`). `null`, wenn die Konversation keinen Agenten hat. |
| `channel` | Kanal der Konversation. `n/a`, wenn er nicht erfasst wurde. |
| `conversations` | Im Zeitraum begonnene Konversationen (bei Voice: Anrufe). |
| `escalated` | An einen Menschen weitergeleitete Konversationen (sie haben ein Ereignis `chat_escalated`). |
| `contained_pct` | `(conversations − escalated) / conversations × 100`. Anteil, der von der KI ohne Weiterleitung bearbeitet wurde. **Es ist keine Lösungsquote.** |
| `avg_duration_s` | Durchschnittliche Anrufdauer in Sekunden: insgesamt, ohne Weiterleitung und mit Weiterleitung. `null` bei Kanälen ohne Dauer (nur Voice erfasst sie). |
| `whatsapp_notifications` | Aus diesen Konversationen gesendete WhatsApp-Benachrichtigungen (Ereignisse `notification_sent`). |
| `unique_users` | Verschiedene Nutzer (bei Voice: verschiedene Telefonnummern). |
| `recontacts` | Nutzer mit 2 oder mehr Konversationen im Zeitraum. Quote der erneuten Kontaktaufnahme = `recontacts / unique_users`. |
| `daily` | Konversationen und Weiterleitungen pro Tag, in `tz`. Tage ohne Konversationen werden weggelassen. |
| `hourly` | Konversationen pro Tagesstunde (0–23), in `tz`. Stunden ohne Konversationen werden weggelassen. |

> [!TIP]
>
> **Vergleiche mit dem Vormonat**: Rufen Sie den Endpoint zweimal auf, einmal pro Monat, und berechnen Sie die Differenz.
> **KI-Quote nur an Tagen mit menschlichen Agenten**: Verwenden Sie `daily` und behalten Sie die Tage mit `escalated > 0`.

## Konversationen (`type=chats`)

Gibt die Konversationen des Zeitraums einzeln zurück, die ältesten zuerst, standardmäßig 100 pro Seite.

```bash theme={null}
curl -H "x-api-key: YOUR_API_KEY" \
  "https://cloud.lovi.ai/functions/v1/analytics?type=chats&date_from=2026-10-01&date_to=2026-10-01&channels=voice&limit=100"
```

```json theme={null}
{
  "data": [
    {
      "id": "29d67962-119b-406c-b172-d66cf179975e",
      "created_at": "2026-10-01T05:58:40.4431Z",
      "ended_at": "2026-10-01T05:58:48Z",
      "last_message_at": null,
      "status": "aiagent",
      "channel": "voice",
      "language": "es",
      "agent": { "id": "2fef9696-0662-4e49-bb83-7564ff25c7ef", "name": "Voice assistant" },
      "escalated_to_human": true,
      "escalated_at": "2026-10-01T05:58:45.12Z",
      "attended_by_human": false,
      "human_agents": [],
      "whatsapp_notifications": 0,
      "parameters": {
        "channel": "voice",
        "call_length": 8,
        "phone_call": "+34600000000",
        "voice_inbound": true,
        "conversation_recording_url": "https://…"
      }
    }
  ],
  "next_cursor": "MjAyNi0xMC0wMVQwNjowMjoxMS4xMjM0NTZ8…"
}
```

| Feld | Beschreibung |
| - | - |
| `id` | ID der Konversation. |
| `created_at`, `ended_at`, `last_message_at` | Beginn, Ende und letzte Nachricht, in UTC. |
| `status` | Mit wem die Konversation geführt wird: `aiagent`, `human`, `queue` (wartet auf einen Menschen) oder `push` (durch eine Benachrichtigung gestartet). |
| `channel`, `language` | Der Einfachheit halber aus `parameters.channel` und `parameters.lang_user` übernommen. |
| `agent` | KI-Agent der Konversation (`id`, `name`). |
| `escalated_to_human`, `escalated_at` | Ob sie an einen Menschen weitergeleitet wurde und wann (erste Weiterleitung). |
| `attended_by_human` | Ob ein menschlicher Agent mindestens eine Nachricht geschrieben hat. |
| `human_agents` | Menschliche Agenten, die in der Konversation geschrieben haben (`id`, `name`). Kann leer sein, auch wenn `attended_by_human` den Wert `true` hat: Nachrichten, die aus einem externen CRM gesendet werden, werden keiner Person zugeordnet. |
| `whatsapp_notifications` | Aus der Konversation gesendete WhatsApp-Benachrichtigungen. |
| `parameters` | **Alle** für die Konversation gespeicherten Parameter, ungefiltert. Die Schlüssel hängen vom Kanal und von der Konfiguration Ihres Agenten ab (bei Voice: `call_length`, `phone_call`, `voice_inbound`, `session_call_id`, `conversation_recording_url`…; sowie jeder benutzerdefinierte Parameter, den Ihr Agent speichert). |

### Paginierung

Solange `next_cursor` nicht `null` ist, fordern Sie die nächste Seite mit denselben Parametern plus `cursor=<next_cursor>` an. Die Konversationen sind nach `created_at` und `id` sortiert, sodass zwischen den Seiten keine Konversation wiederholt oder übersprungen wird.

```python theme={null}
import requests

URL = "https://cloud.lovi.ai/functions/v1/analytics"
HEADERS = {"x-api-key": "YOUR_API_KEY"}
params = {"type": "chats", "date_from": "2026-10-01", "date_to": "2026-10-31", "channels": "voice"}

chats = []
while True:
    page = requests.get(URL, headers=HEADERS, params=params, timeout=60).json()
    chats.extend(page["data"])
    if not page["next_cursor"]:
        break
    params["cursor"] = page["next_cursor"]

print(len(chats), "conversations")
```

## Fehler

Fehler liefern einen JSON-Body `{ "success": false, "message": "…" }`.

| Code | Wann |
| - | - |
| `400` | Fehlender Schlüssel (`Missing access_key parameter`), ungültiger `type`, ungültige Daten, Zeitraum über 31 Tage, ungültige Werte für `tz`, `limit`, `agents`, `channels` oder `cursor`. |
| `403` | Der Schlüssel existiert, hat aber nicht die Berechtigung `analytics_api`. |
| `404` | Ungültiger oder widerrufener Schlüssel. |
| `405` | Andere Methode als `GET`. |
| `500` | Interner Fehler. Versuchen Sie es nach einigen Sekunden erneut; falls er weiterhin auftritt, wenden Sie sich mit dem Zeitpunkt der Anfrage an den Support. |

## Limits und bewährte Vorgehensweisen

* Bis zu **31 Tage** pro Anfrage und **100 Konversationen** pro Seite.
* Eine `metrics`-Anfrage für einen ganzen Monat dauert einige Sekunden. Für einen Monats- oder Tagesbericht genügt ein Aufruf pro Zeitraum: Polling ist nicht nötig.
* Um einen ganzen Monat an Konversationen zu exportieren, durchlaufen Sie die Seiten nacheinander und nicht parallel.
* Halten Sie den Schlüssel geheim und verwenden Sie ihn nur serverseitig. Verwenden Sie ihn nicht in einem Browser oder einer mobilen App.


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