
# Analytics & Reports API

Näiden vain luku -päätepisteiden avulla voit tuoda tilisi toiminnan omiin koontinäyttöihisi ja raportteihisi: viestitapahtumien määrät, krediittien kulutuksen, tekoälyn kustannukset sekä samat kaaviot ja oivallukset, jotka näkyvät sovelluksen sisäisessä koontinäytössä. Tämä opas kattaa:

- **Yhteenveto** — viestimäärien laskurit (lähetetyt, toimitetut, luetut, vastatut, varatut, luodut yhteystiedot, krediitit).
- **Krediitit** — yksityiskohtainen, sivutettu kirjanpito krediittien käytöstä summineen ja erittelyineen.
- **Tekoälyn kustannukset** — päiväkohtainen yhteenveto tekoälyn kuluista.
- **Metriikkasarjat** — kaavioita varten valmis aikasarja yhdelle tai useammalle metriikalle, ryhmiteltynä kampanjan, kanavan, tekoälyagentin tai numeron mukaan.
- **Keskustelujen tulokset** — miten keskustelut päättyivät tekoälyn määrittämän tulostunnisteen mukaan.
- **Koontinäytön oivallukset** ja **Koontinäytön tekoälyoivallukset** — sovelluksen sisäisen koontinäytön taustalla oleva täydellinen data, mukaan lukien tekoälyn kirjoittamat yhteenvedot.
- **Entiteetin toiminta** — yksittäisen yhteystiedon, sopimuksen tai tehtävän aikajana.
- **Aggregoidut tapahtumamäärät** — vanha, camelCase-muotoinen yhteenveto, joka on säilytetty olemassa olevia integraatioita varten.

Jokainen tämän sivun päätepiste vaatii tarkan laajuuden (scope), ei molempia: välitä enintään yksi `campaign_id` (vanha) tai `agent_id`, jos päätepiste hyväksyy sen. Molempien lähettäminen palauttaa `400`, ja tunnus, jota ei ole tililläsi, palauttaa `404` eikä `403`, jotta muiden tilien tunnukset pysyvät arvaamattomina.

Kaikki alla olevat polut ovat suhteessa rajapinnan perus-URL-osoitteeseen:

```
https://api.youraiconnector.com/v1
```

Jokainen pyyntö on todennettava. Katso kohdasta [Todennus](authentication.md) neljä hyväksyttyä menetelmää. Tässä olevissa esimerkeissä käytetään `X-API-Key`-otsikkoa (ja yhtä kyselyparametrimuotoa cURL-kutsulle).

---

## Päivämääräväli

Kaikki kolme päätepistettä hyväksyvät samat valinnaiset päivämääräsuodattimet:

| Parametri | Kuvaus |
|---|---|
| `from` | Välin alku, `YYYY-MM-DD`, sisältäen kyseisen päivän. Oletusarvo on 30 päivää sitten. |
| `to` | Välin loppu, `YYYY-MM-DD`, sisältäen kyseisen päivän. Oletusarvo on tänään. |

Päivämäärät tulkitaan UTC-ajassa. Välin oletusarvo on **viimeiset 30 päivää**, ja se on rajoitettu **366 päivään** — tätä laajempi väli palauttaa `400`-virheen. `from` ei saa olla päivämäärä, joka on `to`-päivämäärän jälkeen.

### `truncated`-lippu

**Yhteenveto**- ja **Krediitit**-päätepisteet rajoittavat sitä, kuinka monta tietuetta yksi pyyntö voi skannata. Jos valitsemasi väli on niin vilkas, että se saavuttaa tämän rajan, vastaus sisältää `"truncated": true`-arvon. Kun näet sen, luvut perustuvat osittaiseen skannaukseen — rajaa päivämääräväliäsi (tai selaa sivuja pienemmillä ikkunoilla) saadaksesi täydelliset luvut.

::: note
**Huomautus:** Kustannus- ja tunnusluvut sisältyvät vain niihin tekoälypyyntöihin, jotka laskutetaan omilta palveluntarjoajan API-avaimiltasi. Kun kustannusluvut on piilotettu tililtäsi, vastaus asettaa `"costs_redacted": true` ja kustannuskenttien arvoksi palautetaan nolla.
:::


---

## Viestimäärien yhteenveto

Palauttaa tilisi aggregoidut viestitapahtumien laskurit sekä välin kokonaissummina että päiväkohtaisena sarjana. Jokainen päivä välillä näkyy `by_date`-kohdassa — hiljaiset päivät täytetään nollilla. Voit halutessasi suodattaa tulokset yhteen kampanjaan käyttämällä `campaign_id`-parametria.

`GET /analytics/summary`

| Parametri | Pakollinen | Kuvaus |
|---|---|---|
| `from` | Ei | Alueen alku, `YYYY-MM-DD`. |
| `to` | Ei | Alueen loppu, `YYYY-MM-DD`. |
| `campaign_id` | Ei | Laske vain tähän kampanjaan kuuluvat tapahtumat. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/summary?from=2026-05-01&to=2026-05-31&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({ from: "2026-05-01", to: "2026-05-31" });
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/summary?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/summary",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"from": "2026-05-01", "to": "2026-05-31"},
)
data = res.json()
```

**Vastaus**

```json
{
  "success": true,
  "from": "2026-05-01",
  "to": "2026-05-31",
  "totals": {
    "total": 1240,
    "sent": 800,
    "delivered": 760,
    "read": 540,
    "replied": 210,
    "booked": 35,
    "contact_created": 120,
    "credits_spent": 412.5,
    "credits_recharged": 500
  },
  "by_date": [
    {
      "date": "2026-05-01",
      "total": 40,
      "sent": 25,
      "delivered": 24,
      "read": 18,
      "replied": 7,
      "booked": 1,
      "contact_created": 4,
      "credits_spent": 13.5,
      "credits_recharged": 0
    }
  ],
  "truncated": false
}
```

Jokaisella `by_date`-kohdan merkinnällä on samat laskurikentät kuin `totals`-kohdassa, sekä lisäksi `date`.

Jos annat `campaign_id`-arvon, joka ei kuulu tilillesi, vastauksena on `404` ja `{ "success": false, "error": "Campaign not found" }`.

---

## Krediittien käyttö

Palauttaa krediittien käytön määritetyllä välillä: sivutettu luettelo yksittäisistä tietueista sekä alueen kokonaissummat ja erittelyt syyn ja kampanjan mukaan.

`GET /analytics/credits`

| Parametri | Pakollinen | Kuvaus |
|---|---|---|
| `from` | Ei | Alueen alku, `YYYY-MM-DD`. |
| `to` | Ei | Alueen loppu, `YYYY-MM-DD`. |
| `campaign_id` | Ei | Sisällytä vain tähän kampanjaan kohdistuva käyttö. |
| `limit` | Ei | Sivukoko `records`-toiminnolle, 1–100. Oletusarvo on 50. |
| `cursor` | Ei | Käytä edellisen sivun `next_cursor`-arvoa seuraavan sivun hakemiseen. |

> **Oikaisut vs. kulutus:** Saldon muutokset, kuten bonukset, tilauksen uusimiset ja korjaukset, on **jätetty pois** `totals`-kohdasta ja erittelyistä – ne eivät ole varsinaista kulutusta. Ne näkyvät edelleen `records`-luettelossa, merkittynä `"is_adjustment": true`-tunnisteella.

**Kokonaissummat ja erittelyt näkyvät vain ensimmäisellä sivulla** (kun `cursor`-arvoa ei ole annettu). Seuraavilla sivuilla `totals`, `by_reason`, `by_reason_cost` ja `by_campaign` palautetaan muodossa `null` – vain `records`-taulukko jatkuu. Tämä estää koko alueen uudelleenskannauksen jokaisen sivun kohdalla.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/credits?from=2026-05-01&to=2026-05-31&limit=50&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({
  from: "2026-05-01",
  to: "2026-05-31",
  limit: "50",
});
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/credits?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();

// To page: pass data.next_cursor as ?cursor on the next request, until it is null.
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/credits",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"from": "2026-05-01", "to": "2026-05-31", "limit": 50},
)
data = res.json()

# To page: pass data["next_cursor"] as cursor on the next request, until it is None.
```

**Vastaus** (ensimmäinen sivu)

```json
{
  "success": true,
  "from": "2026-05-01",
  "to": "2026-05-31",
  "totals": {
    "credits_used": 412.5,
    "cost_usd": 1.284512,
    "records": 318
  },
  "by_reason": {
    "AI Message": 380.0,
    "Campaign Message": 32.5
  },
  "by_reason_cost": {
    "AI Message": 1.284512,
    "Campaign Message": 0
  },
  "by_campaign": {
    "Spring Promo": 250.0,
    "Reactivation": 162.5
  },
  "records": [
    {
      "id": "rec_abc123",
      "amount": 1,
      "timestamp": "2026-05-31T14:02:11.000Z",
      "reason": "AI Message",
      "is_adjustment": false,
      "campaign_id": "campaign123",
      "campaign_name": "Spring Promo",
      "contact_id": "contact456",
      "contact_name": "Jane Smith",
      "credit_type": "ai",
      "custom_keys_used": false,
      "description": null,
      "cost_usd": 0,
      "input_tokens": 0,
      "output_tokens": 0,
      "cache_read_tokens": 0,
      "cache_creation_tokens": 0,
      "ai_model": null,
      "request_id": null,
      "is_test": false
    }
  ],
  "next_cursor": "rec_abc123",
  "costs_redacted": false,
  "truncated": false
}
```

**Kenttähuomautukset:**

- `amount` — tietueesta veloitetut krediitit. Nolla, jos tietueet laskutetaan oman palveluntarjoajan API-avaimesi kautta.
- `is_adjustment` — `true` saldomuutoksille (jätetty pois kokonaissummista/erittelyistä).
- `cost_usd`, `input_tokens`, `output_tokens`, `cache_read_tokens`, `cache_creation_tokens`, `ai_model`, `request_id` — täytetään vain tietueissa, jotka laskutetaan oman palveluntarjoajan API-avaimesi kautta; muussa tapauksessa nolla tai `null`.
- `is_test` — `true` leikkikenttä-/testiajoille, joita ei koskaan laskuteta.
- `next_cursor` — seuraavan sivun kohdistin tai `null`, kun tietueita ei ole enää jäljellä.

---

## AI-kustannusten yhteenveto

Palauttaa tilisi päivittäisen AI-kulujen yhteenvedon. Tämä lukee valmiiksi koostetut päivittäiset summat, joten se on nopea myös pitkillä aikaväleillä. Jokainen alueen päivä näkyy `days`-kohdassa – hiljaiset päivät täytetään nollilla.

`GET /analytics/ai-cost`

| Parametri | Pakollinen | Kuvaus |
|---|---|---|
| `from` | Ei | Alueen alku, `YYYY-MM-DD`. |
| `to` | Ei | Alueen loppu, `YYYY-MM-DD`. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/ai-cost?from=2026-05-01&to=2026-05-31&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({ from: "2026-05-01", to: "2026-05-31" });
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/ai-cost?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/ai-cost",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"from": "2026-05-01", "to": "2026-05-31"},
)
data = res.json()
```

**Vastaus**

```json
{
  "success": true,
  "from": "2026-05-01",
  "to": "2026-05-31",
  "totals": {
    "total_usd": 12.4821,
    "byok_usd": 12.4821,
    "platform_usd": 0,
    "calls": 4210
  },
  "days": [
    {
      "date": "2026-05-01",
      "total_usd": 0.4012,
      "byok_usd": 0.4012,
      "platform_usd": 0,
      "input_usd": 0.18,
      "output_usd": 0.19,
      "cache_creation_usd": 0.02,
      "cache_read_usd": 0.0112,
      "calls": 140,
      "by_provider": { "anthropic": 0.4012 }
    }
  ],
  "costs_redacted": false
}
```

**Kenttähuomautukset:**

- `byok_usd` — laskutettu käyttö omilla palveluntarjoajan API-avaimillasi.
- `platform_usd` — se osa käytöstä, joka suoritettiin alustalla oman avaimesi sijaan.
- `input_usd`, `output_usd`, `cache_creation_usd`, `cache_read_usd` — kustannuskomponentit, jotka muodostavat kohdan `total_usd`.
- `by_provider` — USD-määräinen käyttö AI-palveluntarjoajan nimen mukaan jaoteltuna.
- USD-summat palautetaan vain tileille, jotka käyttävät omaa palveluntarjoajan avaintaan. Luottoa käyttäville tileille jokainen USD-kenttä on nolla ja `costs_redacted` on `true` (kutsulaskurit pysyvät näkyvissä).

---

## Metriikkasarjat

Palauttaa yhden tai useamman metriikan aikasarjan yhdellä kutsulla, valinnaisesti ryhmiteltynä enintään kahden ulottuvuuden mukaan – päätepiste kaavion sitomiseen. Yksi pyyntö voi vastata kysymykseen "lähetetyt ja vastatut per päivä, per kanava, tälle kampanjalle" ilman kutsua per kampanja.

`GET /analytics/series`

Jokainen vastaus sisältää `labels`-taulukon (aikakseli, nollatäytetty koko alueella) ja yhden merkinnän `series`-kohdassa per ryhmä, joista jokainen sisältää yhden taulukon per pyydetty metriikka kohdistettuna `labels`-kohtaan. `limit`-kohdan jälkeisiä sarjoja ei hylätä – ne tiivistyvät `other_bucket`-kohtaan, joka lasketaan alueen kokonaissummana miinus palautetut sarjat, joten renderöity kaavio vastaa aina todellisia lukuja; `truncated` on `true` aina kun näin tapahtuu.

Mistä luvut tulevat: `sent`, `delivered`, `read` ja `replied` tulevat viestitietueista, jotka sisältävät kanavan ja lähettävän numeron. `booked`, `contact_created` ja `credits_spent` tulevat tapahtumavirrasta, joka ei sisällä lähettävää numeroa, joten nämä metriikat päätyvät `null`-numeroiseen säiliöön, kun ryhmittelet `number`-kohdan mukaan.

| Parametri | Pakollinen | Kuvaus |
|---|---|---|
| `from` | Ei | Alueen alku, `YYYY-MM-DD`. Oletuksena 30 päivää sitten. |
| `to` | Ei | Alueen loppu, `YYYY-MM-DD`. Oletuksena tänään. |
| `metrics` | Ei | Pilkuilla erotettu luettelo kohteista `sent`, `ai_sent`, `human_sent`, `delivered`, `read`, `replied`, `booked`, `contact_created`, `credits_spent`. Oletuksena `sent,replied`. Tuntematon metriikka palauttaa `400`. |
| `group_by` | Ei | Pilkuilla erotettu luettelo enintään kahdesta ulottuvuudesta kohteista `date`, `campaign`, `channel`, `agent`, `number`. `date` hyväksytään, mutta sillä ei ole vaikutusta – jokainen vastaus sisältää jo aikakselin. Jätä pois yksittäistä koko tilin kattavaa sarjaa varten. |
| `granularity` | Ei | `day` (oletus), `week` tai `month`. Viikkosäiliöt alkavat maanantaina, kuukausisäiliöt 1. päivänä. |
| `limit` | Ei | Kuinka monta sarjaa palautetaan ennen kuin loput tiivistyvät `other_bucket`-kohtaan, 1–50. Oletuksena 12. |
| `campaign_id` | Ei | Laske vain tähän kampanjaan kuuluva toiminta. Vanha; suosi `agent_id`. |
| `agent_id` | Ei | Laske vain tähän tekoälyagenttiin kuuluva toiminta. |
| `channel` | Ei | Laske vain tällä kanavalla tapahtuva toiminta, esimerkiksi `whatsapp`. |

Tämän päätepisteen päivämääräväli on rajoitettu **92 päivään** (tiukempi kuin muualla tällä sivulla käytetty 366 päivän rajoitus).

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/series?from=2026-05-01&to=2026-05-31&metrics=sent,replied,booked&group_by=campaign,channel&limit=10&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({
  from: "2026-05-01",
  to: "2026-05-31",
  metrics: "sent,replied,booked",
  group_by: "campaign,channel",
  limit: "10",
});
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/series?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/series",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={
        "from": "2026-05-01",
        "to": "2026-05-31",
        "metrics": "sent,replied,booked",
        "group_by": "campaign,channel",
        "limit": 10,
    },
)
data = res.json()
```

**Vastaus**

```json
{
  "success": true,
  "from": "2026-05-01",
  "to": "2026-05-31",
  "granularity": "day",
  "labels": ["2026-05-01", "2026-05-02"],
  "group_by": ["campaign", "channel"],
  "metrics": ["sent", "replied", "booked"],
  "series": [
    {
      "key": {
        "campaign_id": "campaign123",
        "campaign_name": "Spring Promo",
        "channel": "whatsapp"
      },
      "total": 812,
      "metrics": {
        "sent": [40, 35],
        "replied": [12, 9],
        "booked": [2, 1]
      }
    }
  ],
  "other_bucket": {
    "series_count": 6,
    "total": 340,
    "metrics": {
      "sent": [18, 20],
      "replied": [5, 6],
      "booked": [0, 1]
    }
  },
  "truncated": true
}
```

**Kenttähuomautukset:**

- `key` — yhden sarjan identiteetti. Vain pyydettyjen `group_by`-ulottuvuuksien avaimet ovat läsnä; ulottuvuus, jonka arvo on tuntematon riville (viesti ilman kampanjaa, tapahtuma ilman kanavaa), palautuu muodossa `null` sen sijaan, että se hylättäisiin, joten sarjat summautuvat edelleen kokonaissummiin.
- `other_bucket` — `null`, kun mitään ei tiivistetty.
- Tämä päätepiste palauttaa `503` ja `"error_code": "analytics_unavailable"`, kun raportointitietokanta ei pysty vastaamaan tilisi osalta, sen sijaan että palauttaisi `200` täynnä nollia – nollattu kaavio tulkittaisiin faktaksi.

---

## Keskustelujen tulokset

Palauttaa tiedon siitä, miten keskustelut päättyivät tietyllä aikavälillä: päiväkohtainen määrä jokaiselle tekoälyn määrittämälle tulostunnisteelle, sekä alueen kokonaissummat vastauksille, varauksille, ihmiselle siirroille ja keskusteluille, joita tekoäly ei koskaan luokitellut.

`GET /analytics/outcomes`

Välitä `group_by=tag` tiivistääksesi aikakselin ja saadaksesi vain alueen kokonaissummat per tunniste – tässä tilassa `labels` on tyhjä ja jokaisen tunnisteen `counts`-taulukko on tyhjä, kun taas `total` on edelleen täytetty.

| Parametri | Pakollinen | Kuvaus |
|---|---|---|
| `from` | Ei | Aikavälin alku, `YYYY-MM-DD`. Oletusarvo on 30 päivää sitten. |
| `to` | Ei | Aikavälin loppu, `YYYY-MM-DD`. Oletusarvo on tänään. |
| `campaign_id` | Ei | Laske vain keskustelut, joiden yhteyshenkilöt ovat tällä hetkellä tässä kampanjassa. Vanhentunut; käytä mieluummin `agent_id`. |
| `agent_id` | Ei | Laske vain tämän tekoälyagentin tulokset. |
| `group_by` | Ei | `date` (oletus) säilyttää päiväkohtaiset laskelmat; `tag` tiivistää ne aikavälin kokonaissummiksi. |

Tämän päätepisteen aikaväli on rajoitettu **92 päivään**.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/outcomes?from=2026-05-01&to=2026-05-31&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({ from: "2026-05-01", to: "2026-05-31" });
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/outcomes?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/outcomes",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"from": "2026-05-01", "to": "2026-05-31"},
)
data = res.json()
```

**Vastaus**

```json
{
  "success": true,
  "from": "2026-05-01",
  "to": "2026-05-31",
  "group_by": "date",
  "labels": ["2026-05-01", "2026-05-02"],
  "by_tag": [
    { "tag": "interested", "total": 84, "counts": [3, 5] },
    { "tag": "not_interested", "total": 40, "counts": [1, 2] },
    { "tag": null, "total": 12, "counts": [0, 1] }
  ],
  "totals": {
    "sessions": 260,
    "replied": 210,
    "booked": 35,
    "human_alerted": 18,
    "unresolved": 12
  }
}
```

**Kenttähuomautukset:**

- `by_tag[].tag` — `null` keskusteluille, joille tekoäly ei koskaan määrittänyt tulostunnistetta.
- `totals.human_alerted` — ihmiselle siirretyt keskustelut; tämä kirjataan jokaisen siirron yhteydessä, eikä se aiemmin näkynyt missään päätepisteessä.
- Sama `503`/`analytics_unavailable`-toimintatapa kuin Metric-sarjassa, kun raportointitietokanta ei pysty vastaamaan.

---

## Koontinäytön oivallukset

Palauttaa koko koontinäytön hyötykuorman yhdellä kutsulla: vastausprosentin lämpökartta viikonpäivän ja tunnin mukaan, kampanjoiden tulostaulu, kanavakohtainen volyymi, tarkat yhteyskohtaiset summat, päiväkohtaiset mittarikoosteet (tili-, kanava- ja numerokohtaisesti), yhteyshenkilöiden alkuperä, saapuneiden viestien vastausaika ja viimeisimpien toimintojen syöte. Tämä on API:n kattavin raportointihyötykuorma — se ohjaa suoraan sovelluksen sisäistä koontinäyttöä.

`GET /analytics/dashboard-insights`

| Parametri | Pakollinen | Kuvaus |
|---|---|---|
| `startDate` | Kyllä | Aikavälin alku, `YYYY-MM-DD`. |
| `endDate` | Kyllä | Aikavälin loppu, `YYYY-MM-DD`. |
| `campaignId` | Ei | Sisällytä vain tähän kampanjaan kuuluva toiminta (`campaign_id` hyväksytään myös). Vanhentunut; käytä mieluummin `agent_id`. |
| `agent_id` | Ei | Sisällytä vain tähän tekoälyagenttiin kuuluva toiminta (`agentId` hyväksytään myös). Agentin laajuudessa kampanjoiden tulostaulu muodostetaan vain kyseisen agentin toiminnan perusteella. |

Tämä päätepiste käyttää `startDate`/`endDate`-muotoa (ei `from`/`to`), koska se jakaa toteutuksensa sovelluksen sisäisen koontinäytön kanssa. Aikaväli on rajoitettu 92 päivään, ja jos se on tätä laajempi, se **rajataan, ei hylätä**.

> **Null tarkoittaa ei saatavilla, ei nollaa.** Useat lohkot (`numberStats`, `channelDailySeries`, `metricDailyBreakdown`, `contactsByCountry`) lasketaan raportointitietokannasta ja ne palauttavat `null`, kun tietokanta ei pysty vastaamaan tilisi osalta. Älä renderöi `null`-lohkoa tyhjänä kaaviona.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/dashboard-insights?startDate=2026-05-01&endDate=2026-05-31&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({ startDate: "2026-05-01", endDate: "2026-05-31" });
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/dashboard-insights?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/dashboard-insights",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"startDate": "2026-05-01", "endDate": "2026-05-31"},
)
data = res.json()
```

**Vastaus** (lyhennetty — tämä hyötykuorma on suuri; katso täydellinen skeema [API-viitteestä](reference.md))

```json
{
  "success": true,
  "data": {
    "heatmap": {
      "buckets": [
        { "weekday": 1, "hour": 9, "sent": 12, "replied": 5, "replyRate": 0.42 }
      ]
    },
    "topCampaigns": [
      { "campaignId": "campaign123", "name": "Spring Promo", "sent": 420, "replied": 180, "booked": 22, "replyRate": 0.43, "creditsSpent": 210.5 }
    ],
    "channelVolume": [
      { "channel": "whatsapp", "sent": 800, "received": 540, "lastMessageAt": "2026-05-31T14:02:11.000Z" }
    ],
    "inboxSla": { "medianFirstResponseMs": 92000, "sampleSize": 140 },
    "activityFeed": [
      { "id": "evt_1", "kind": "booked", "at": "2026-05-31T14:02:11.000Z", "contactId": "contact456", "contactName": "Jane Smith", "campaignId": "campaign123", "campaignName": "Spring Promo", "label": "Jane Smith booked an appointment" }
    ],
    "numberStats": null,
    "channelDailySeries": null,
    "metricDailyBreakdown": null,
    "contactsByCountry": null,
    "ai_human_split": null
  }
}
```

**Kenttähuomautukset:**

- `heatmap.buckets[].weekday` — `0` on sunnuntai ja `6` on lauantai.
- `numberStats`, `channelDailySeries`, `metricDailyBreakdown`, `contactsByCountry`, `ai_human_split` — jokainen palauttaa itsenäisesti `null`, kun raportointitietokanta ei ole käytettävissä tilillesi; kaikki muut lohkot palautuvat normaalisti.

---

## Tekoälyn koontinäytön oivallukset

Palauttaa kolme lyhyttä, tekoälyn kirjoittamaa oivallusta tilin viestinnästä tietyllä aikavälillä: yksi onnistuminen, yksi seurattava asia ja yksi vinkki — lauseita, jotka voit kopioida suoraan raporttiin sen sijaan, että joutuisit tulkitsemaan lukuja itse. Luotu vain tilin omien viestimittareiden perusteella.

`GET /analytics/dashboard-ai-insights`

| Parametri | Pakollinen | Kuvaus |
|---|---|---|
| `startDate` | Kyllä | Aikavälin alku, `YYYY-MM-DD`. |
| `endDate` | Kyllä | Aikavälin loppu, `YYYY-MM-DD`. |

Tämä päätepiste koskee koko tiliä — se ei vaadi kampanja- tai agenttilaajuutta.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/dashboard-ai-insights?startDate=2026-05-01&endDate=2026-05-31&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({ startDate: "2026-05-01", endDate: "2026-05-31" });
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/dashboard-ai-insights?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/dashboard-ai-insights",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"startDate": "2026-05-01", "endDate": "2026-05-31"},
)
data = res.json()
```

**Vastaus**

```json
{
  "success": true,
  "data": {
    "insights": [
      { "tone": "win", "title": "Reply rate is up", "detail": "Your reply rate climbed to 43% this period, up from 36% the period before." },
      { "tone": "watch", "title": "Bookings slowed midweek", "detail": "Wednesday bookings dropped to a third of Monday's, worth a look at your Wednesday follow-up timing." },
      { "tone": "tip", "title": "Re-send to non-repliers", "detail": "212 contacts received a message but never replied — a short follow-up template often recovers 10-15% of them." }
    ]
  }
}
```

Puuttuva `startDate` tai `endDate` palauttaa `400`.

---

## Entiteetin toiminnan aikajana

Palauttaa yksittäisen yhteystiedon, kaupan tai tehtävän toiminnan yhtenä aikajanana, uusimmasta alkaen: mitä tapahtui ja milloin, sisältäen viestit, tapaamiset, muistiinpanot ja tilamuutokset. Käytä tätä vastataksesi kysymykseen "mitä tälle henkilölle on tapahtunut" ilman, että joudut yhdistelemään useita listauspäätepisteitä.

`GET /analytics/entity-activity`

| Parametri | Pakollinen | Kuvaus |
|---|---|---|
| `entityType` | Kyllä | `contact`, `deal` tai `task`. |
| `entityId` | Kyllä | Sen tietueen ID, jonka aikajana palautetaan. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/entity-activity?entityType=contact&entityId=contact456&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({ entityType: "contact", entityId: "contact456" });
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/entity-activity?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/entity-activity",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"entityType": "contact", "entityId": "contact456"},
)
data = res.json()
```

**Vastaus**

```json
{
  "success": true,
  "data": {
    "items": [
      {
        "id": "evt_9",
        "kind": "appointment_booked",
        "at": "2026-05-31T14:02:11.000Z",
        "label": "Booked an appointment for June 3",
        "detail": "Consultation call, 30 minutes"
      },
      {
        "id": "evt_8",
        "kind": "message_replied",
        "at": "2026-05-31T13:58:02.000Z",
        "label": "Replied: \"Yes, that time works\""
      }
    ]
  }
}
```

Puuttuva tai virheellinen `entityType`/`entityId` palauttaa `400`. Entiteetti, jota ei ole tililläsi, palauttaa `404`, joten muiden tilien tunnukset pysyvät arvaamattomina.

---

## Aggregoidut tapahtumien määrät (vanhentunut)

Palauttaa samat aggregoidut tapahtumien määrät kuin [Viestien määrän yhteenveto](#message-volume-summary), mutta camelCase-muodossa (`contactCreated` eikä `contact_created`, `byDate` eikä `by_date`), jota jotkin vanhemmat integraatiot käyttävät. Suosi `/analytics/summary`-päätepistettä uusissa integraatioissa — tämä päätepiste on olemassa vain siksi, että sovelluksen sisäinen hallintapaneeli ja API jakavat saman toteutuksen.

`GET /analytics/aggregate`

| Parametri | Pakollinen | Kuvaus |
|---|---|---|
| `startDate` | Ei | Aikavälin alku, ISO-päivämäärä tai päivämäärä ja kellonaika. Käyttää oletuksena samaa ikkunaa kuin `/analytics/summary`. |
| `endDate` | Ei | Aikavälin loppu, ISO-päivämäärä tai päivämäärä ja kellonaika. |
| `campaignId` | Ei | Laske vain tähän kampanjaan kuuluvat tapahtumat (`campaign_id` hyväksytään myös). Vanhentunut; suosi `agent_id`. |
| `agent_id` | Ei | Laske vain tähän tekoälyagenttiin kuuluvat tapahtumat (`agentId` hyväksytään myös). |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/aggregate?startDate=2026-05-01&endDate=2026-05-31&apiKey=YOUR_API_KEY"
```

**Vastaus**

```json
{
  "success": true,
  "data": {
    "from": "2026-05-01",
    "to": "2026-05-31",
    "total": 1240,
    "byAnalyticType": {
      "total": 1240,
      "sent": 800,
      "delivered": 760,
      "read": 540,
      "replied": 210,
      "booked": 35,
      "contactCreated": 120,
      "creditsSpent": 412.5,
      "creditsRecharged": 500
    },
    "byDate": [
      { "date": "2026-05-01", "byAnalyticType": { "total": 40, "sent": 25, "delivered": 24, "read": 18, "replied": 7, "booked": 1, "contactCreated": 4, "creditsSpent": 13.5, "creditsRecharged": 0 } }
    ]
  }
}
```

---

## Toimiston alitilien yhteenveto


---

## Analytics API -virheet

Analytics-päätepisteet palauttavat vakioituneen virhemuodon:

```json
{
  "success": false,
  "error": "Date range too large. Maximum is 366 days."
}
```

Analytiikkapäätepisteessä virheellinen päivämäärämuoto tai sallitun ikkunan ulkopuolinen aikaväli palauttaa `400`, ja tuntematon `campaign_id` tai `agent_id` palauttaa `404`. Sekä `campaign_id`- että `agent_id`-parametrien lähettäminen päätepisteeseen, joka hyväksyy vain toisen, on myös `400` — lähetä enintään yksi. Vain PG-raportointipäätepisteet (metrisarjat, keskustelujen tulokset, toimiston yhteenveto) palauttavat `503` ja `"error_code": "analytics_unavailable"` sen sijaan, että palauttaisivat `200` täynnä nollia, kun raportointitietokanta ei pysty vastaamaan tilisi osalta — yritä pian uudelleen. Jaetut koodit, jotka jokainen päätepiste voi palauttaa — `401`, `403` (tilauksesi ei sisällä API-pääsyä tai toimiston yhteenvedossa tilisi ei ole Agency/Dev), `429` (nopeusrajoitus) ja `500` — on lueteltu uudelleenkokeiluohjeiden kanssa kohdassa [Virheet ja sivutus](errors-and-pagination.md).

---

## Seuraavat vaiheet

- [Todennus](authentication.md) — neljä tapaa todentaa pyyntö.
- [Virheet ja nopeusrajoitukset](errors-and-pagination.md) — tilakoodit ja 300 pyyntöä/min -rajoitus.
- [Kampanjoiden API](campaigns.md) — kampanjat, joiden mukaan nämä luvut voidaan suodattaa.
