
# Knowledge Base API

Tietokantasi on se, mistä tekoäly lukee tiedot. Se koostuu kahdesta osasta, ja tämä sivu käsittelee molempia:

- **Tietolähteet** (`/kb-sources`) — verkkosivut ja ladatut asiakirjat, joita syötät alustalle. Jokainen niistä luetaan, jaetaan osiin ja muutetaan UKK-kysymyksiksi, joihin tekoälysi voi vastata.
- **Tietoryhmät** (`/kb-groups`) — UKK-kysymysten nimetyt niput, joita voit käyttää agentille tai kampanjalle yhdellä kutsulla, jolloin jo kuratoimasi tietopohja voidaan käyttää uudelleen seuraavassa luomassasi agentissa.

Lähteen tuottamat UKK-kysymykset päätyvät samaan kirjastoon kuin käsin kirjoittamasi, joten kun tuonti on valmis, voit lukea, muokata ja linkittää niitä [UKK-rajapinnan](faqs.md) avulla.

Kaikki alla olevat päätepisteet ovat suhteessa perus-URL-osoitteeseen `https://api.youraiconnector.com/v1`. Jokainen pyyntö on todennettava – katso [API-käyttöoikeus](../integrations/api-access.md) ja [Todennus](authentication.md). API-käyttöoikeus on maksullinen ominaisuus; ilman sitä pyynnöt hylätään virheellä `403`.


> **Tuonti kuluttaa krediittejä.** Sivun tai asiakirjan lukeminen ja siitä UKK-kysymysten kirjoittaminen kuluttaa krediittejä suunnilleen sisällön määrän mukaan. Käytä [Tuonnin arviointia](#estimate-what-an-import-will-cost) ennen kuin aloitat laajan indeksoinnin.

---

## Miten tuonti toimii

Tuonti on taustaprosessi, ei toiminto, joka valmistuu odottaessasi. Jokainen tuonnin päätepiste vastaa välittömästi `source_id`-tunnisteella, ja voit kysellä lähteen tilaa, kunnes se on valmis:

1. **Aloita tuonti** — `POST /kb-sources/url` (yksi sivu), `POST /kb-sources/file` (ladattu asiakirja) tai `POST /kb-sources/bulk-import` (jopa 100 sivua). Saat takaisin lähteen tunnisteen ja `status: "queued"`-tunnisteen.
2. **Kysely** — `GET /kb-sources/{sourceId}` kunnes `status` ei ole enää `queued` tai `processing`.
3. **Lue UKK-kysymykset** — kun tila on `ready`, sen tuottamat merkinnät ovat UKK-kirjastossasi: `GET /faqs`.

Jokainen lähde raportoi yhden seuraavista tiloista:

| Tila | Mitä se tarkoittaa |
|---|---|
| `queued` | Odottaa lukemista. Mitään ei ole vielä veloitettu. |
| `processing` | Luetaan ja muutetaan parhaillaan UKK-kysymyksiksi. |
| `ready` | Valmis. Sen UKK-kysymykset ovat kirjastossasi. |
| `failed` | Ei voitu tuoda. `error_message` kertoo syyn. |
| `cancelled` | Pysäytetty ennen lukemista (katso [Tuonnin pysäyttäminen](#stop-an-import)). |
| `paused` | Pysäytetty, koska oma tekoälyavaimesi epäonnistui tuonnin aikana (katso [Keskeytetyn tuonnin jatkaminen](#resume-a-paused-import)). |
| `deleting` | Massapoisto on käynnissä. |
| `unknown` | Tietueella ei ole tilaa. Käsittele sitä ei-valmiina. |

> **Liitä tuonnin yhteydessä.** Välitä `autoLinkToAgentId` missä tahansa tuonnin päätepisteessä, niin lähde — sekä jokainen sen tuottama UKK-kysymys — päätyy kyseisen agentin tietokantaan samalla kutsulla ilman erillistä linkitysvaihetta. `autoLinkToCampaignId` tekee saman klassiselle kampanjalle. Linkitys on parhaan yrityksen periaate: tunniste, jota ei ole olemassa tai joka kuuluu toiselle tilille, ohitetaan hiljaisesti ja tuonti jatkuu, joten vahvista linkitys lukemalla agentin tiedot uudelleen.

---

## Verkkosivun tuominen

`POST /kb-sources/url`

Lisää yhden verkkosivun tietokantaasi.

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `url` | Kyllä | Sivun täydellinen `http`- tai `https`-osoite. |
| `autoLinkToAgentId` | Ei | Sen tekoälyagentin tunnus, johon tuotu lähde liitetään. |
| `autoLinkToCampaignId` | Ei | Vanha versio. Sen kampanjan tunnus, johon tuotu lähde liitetään. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-sources/url?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/pricing",
    "autoLinkToAgentId": "ag7HkQ2ZpLxR3mNb"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/kb-sources/url", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://example.com/pricing",
    autoLinkToAgentId: "ag7HkQ2ZpLxR3mNb",
  }),
});
const { source_id } = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/kb-sources/url",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "url": "https://example.com/pricing",
        "autoLinkToAgentId": "ag7HkQ2ZpLxR3mNb",
    },
)
source_id = res.json().get("source_id")
```

**Vastaus** — `202 Accepted`

```json
{
  "success": true,
  "source_id": "kb_src_abc123",
  "status": "queued",
  "batch_id": "batch_9f2a"
}
```

Kysy `source_id`-tilaa [Tarkista lähde](#check-a-source) -toiminnolla, kunnes tila on `ready` tai `failed`.

Jos sama sivu on jo tietopohjassasi, mitään uutta ei aseteta jonoon ja saat sen sijaan `200`-vastauksen – ja jos pyysit automaattista linkitystä, olemassa oleva lähde linkitetään sinulle joka tapauksessa:

```json
{
  "success": true,
  "status": "exists",
  "skipped_duplicate": 1
}
```

Puuttuva `url` tai osoite, joka ei ole kelvollinen `http`/`https`-osoite, palauttaa `400`-vastauksen.

---

## Tuo ladattu tiedosto

`POST /kb-sources/file`

Lisää tiedoston, joka on **jo tilisi tiedostotallennustilassa**, tietolähteeksi. Tuetut tyypit: PDF, DOCX, TXT, MD, CSV ja XLSX.

> **Tämä päätepiste ei sisällä itse tiedostoa.** Siinä ei ole multipart-lähetystä, base64-runkoa eikä URL-osoitteesta lataamista: lähetät tiedoston tallennussijainnin, jonka on oltava omassa latauskansiossasi (`storage_path` täytyy alkaa `users/{your user id}/uploads/`-merkkijonolla), muuten pyyntö hylätään `403`-vastauksella. Hallintapaneeli sijoittaa tiedostot sinne, kun raahaat ne sisään. Jos et pysty sijoittamaan tiedostoa sinne, tuo verkkosivu käyttämällä [Tuo verkkosivu](#import-a-web-page) -toimintoa.

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `storage_path` | Kyllä | Ladatun tiedoston sijainti. Täytyy alkaa `users/{your user id}/uploads/`-merkkijonolla. |
| `filename` | Kyllä | Alkuperäinen tiedostonimi tiedostopäätteineen – näin tiedostotyyppi tunnistetaan. |
| `mime_type` | Kyllä | Tiedoston MIME-tyyppi, esimerkiksi `application/pdf`. |
| `autoLinkToAgentId` | Ei | Sen tekoälyagentin tunnus, johon asiakirja liitetään. |
| `autoLinkToCampaignId` | Ei | Vanha versio. Sen kampanjan tunnus, johon asiakirja liitetään. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-sources/file?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "storage_path": "users/abc123uid/uploads/handbook.pdf",
    "filename": "handbook.pdf",
    "mime_type": "application/pdf",
    "autoLinkToAgentId": "ag7HkQ2ZpLxR3mNb"
  }'
```

**Vastaus** — `202 Accepted`

```json
{
  "success": true,
  "source_id": "kb_src_abc123",
  "status": "queued"
}
```

| Tila | Milloin |
|---|---|
| `400` | Pakollinen kenttä puuttuu tai tiedostotyyppiä ei voida lukea. |
| `403` | `storage_path` on oman latauskansiosi ulkopuolella. |

---

## Tarkista lähde

`GET /kb-sources/{sourceId}`

Kysely, joka seuraa jokaista tuontia ja päivitystä. Toista sitä, kunnes tila on `ready` tai `failed`.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/kb-sources/kb_src_abc123?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/kb-sources/kb_src_abc123",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const source = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/kb-sources/kb_src_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
source = res.json()
```

**Vastaus**

```json
{
  "success": true,
  "source_id": "kb_src_abc123",
  "status": "ready",
  "faq_count": 24,
  "section_count": 31,
  "error_message": null
}
```

| Kenttä | Tyyppi | Kuvaus |
|---|---|---|
| `status` | string | Missä lähde on putkessa (katso [tilataulukko](#how-an-import-works)). |
| `faq_count` | integer | Kuinka monta UKK:ta tästä lähteestä on tähän mennessä luotu. |
| `section_count` | integer | Kuinka moneen sisältöosioon lähde jaettiin. |
| `error_message` | string \| null | Miksi tuonti epäonnistui, kun tila on `failed`. Muussa tapauksessa `null`. |

---

## Poista lähde

`DELETE /kb-sources/{sourceId}`

Poistaa yhden tietolähteen. **Oletusarvoisesti sen tuottamat UKK:t säilytetään** — lisää `delete_faqs=true` poistaaksesi myös ne.

**Kyselyparametrit**

| Parametri | Pakollinen | Kuvaus |
|---|---|---|
| `delete_faqs` | Ei | Aseta arvoon `true`, jos haluat poistaa myös jokaisen tämän lähteen tuottaman UKK:n. Oletusarvo on `false`. |

**cURL**

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/kb-sources/kb_src_abc123?delete_faqs=true&apiKey=YOUR_API_KEY"
```

**Vastaus**

```json
{
  "success": true,
  "faqs_deleted": 24
}
```

`faqs_deleted` on `0`, ellet pyytänyt `delete_faqs=true`.

---

## Tuo useita sivuja kerralla

`POST /kb-sources/bulk-import`

Lisää jopa 100 verkkosivua yhdellä kutsulla — tavallinen jatkotoimenpide [sivujen löytämiselle verkkosivustolta](#discover-pages-on-a-website) tai [uusien sivujen etsimiselle verkkosivustolta](#find-new-pages-on-a-website). Tietokannassasi jo olevat sivut ohitetaan sen sijaan, että ne monistettaisiin (ja ne linkitetään edelleen agenttiin, kun pyysit sitä).

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `urls` | Kyllä | Tuotavat osoitteet. Vähintään 1, enintään 100 per kutsu. |
| `autoLinkToAgentId` | Ei | Sen tekoälyagentin tunnus, johon jokainen tuotu sivu liitetään. |
| `autoLinkToCampaignId` | Ei | Vanha versio. Sen kampanjan tunnus, johon jokainen tuotu sivu liitetään. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-sources/bulk-import?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": ["https://example.com/pricing", "https://example.com/faq"],
    "autoLinkToAgentId": "ag7HkQ2ZpLxR3mNb"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/kb-sources/bulk-import", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    urls: ["https://example.com/pricing", "https://example.com/faq"],
    autoLinkToAgentId: "ag7HkQ2ZpLxR3mNb",
  }),
});
const { queued_source_ids } = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/kb-sources/bulk-import",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "urls": ["https://example.com/pricing", "https://example.com/faq"],
        "autoLinkToAgentId": "ag7HkQ2ZpLxR3mNb",
    },
)
queued_source_ids = res.json()["queued_source_ids"]
```

**Vastaus** — `202 Accepted`

```json
{
  "success": true,
  "batch_id": "batch_9f2a",
  "queued": 2,
  "skipped_duplicate": 0,
  "queued_source_ids": ["kb_src_abc123", "kb_src_def456"]
}
```

Kysy jokaisen tunnuksen tilaa kohdassa `queued_source_ids` käyttämällä [Tarkista lähde](#check-a-source)-toimintoa. Tyhjän `urls`-taulukon, ei-merkkijonomuotoisen merkinnän tai yli 100 merkinnän lähettäminen palauttaa `400`.

---

## Poista useita lähteitä kerralla

`POST /kb-sources/bulk-delete`

Poistaa jopa 2 000 tietolähdettä yhdellä kutsulla. Poisto suoritetaan taustalla, ja saat sähköpostin, kun se on valmis.

> **Massapoisto poistaa aina myös UKK-osiot.** Toisin kuin [Poista lähde](#delete-a-source), joka säilyttää ne, ellet toisin pyydä, tämä päätepiste poistaa jokaisen lähteen yhdessä sen tuottamien UKK-osioiden kanssa. Niiden säilyttämiseen ei ole vaihtoehtoa.

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `sourceIds` | Kyllä | Poistettavien lähteiden tunnisteet. Vähintään 1, enintään 2 000 kutsua kohden. |
| `domainLabel` | Ei | Tämän puhdistustoiminnon kutsumanimi. Käytetään vain valmistumisilmoituksessa. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-sources/bulk-delete?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sourceIds": ["kb_src_abc123", "kb_src_def456"],
    "domainLabel": "example.com"
  }'
```

**Vastaus** — `202 Accepted`

```json
{
  "success": true,
  "batch_id": "del_batch_31a",
  "queued": 2
}
```

---

## Sivujen etsiminen verkkosivustolta

`POST /kb-sources/discover-pages`

Tutkii verkkosivustoa yhdestä aloitusosoitteesta alkaen ja listaa samasta verkkotunnuksesta löytyneet sivut sekä arvion siitä, kannattaako ne tuoda. **Mitään ei tuoda eikä mitään valita puolestasi** — tämä on "mitä sivustolla on" -vaihe, joka suoritetaan ennen kuin päätät, mitä lähetät [Tuo useita sivuja kerralla](#import-many-pages-at-once) -toimintoon.

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `url` | Kyllä | Osoite, josta tutkiminen aloitetaan, yleensä sivuston etusivu. |
| `maxPages` | Ei | Palautettavien sivujen yläraja. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-sources/discover-pages?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.com", "maxPages": 100 }'
```

**Vastaus**

```json
{
  "success": true,
  "source_type": "sitemap",
  "pages": [
    {
      "url": "https://example.com/pricing",
      "title": "Pricing",
      "depth": 1,
      "score": 95,
      "recommendation": "add",
      "reason_key": "core_page"
    }
  ]
}
```

| Kenttä | Tyyppi | Kuvaus |
|---|---|---|
| `source_type` | merkkijono | Miten sivut löytyivät — `sitemap` (sivuston oma sivukartta) tai `link_discovery` (seuraamalla linkkejä). |
| `url` | merkkijono | Sivun koko osoite. |
| `title` | merkkijono \| null | Sivun otsikko, jos se oli luettavissa. |
| `depth` | kokonaisluku | Kuinka monen linkin päästä aloitussivusta tämä sivu löytyi. |
| `score` | kokonaisluku | Kuinka hyödylliseltä sivu vaikuttaa tietolähteenä, välillä `0` – `100`. |
| `recommendation` | merkkijono | `add` (selvästi tuomisen arvoinen, pisteet 90 tai yli), `maybe` (rajatapaus) tai `skip` (sisältö, joka auttaa avustajaa harvoin — muutoslokit, lakisääteiset sivut, päällekkäiset käännökset). |
| `reason_key` | merkkijono | Vakaa, koneellisesti luettava syy suosituksen taustalla, esimerkiksi `core_page`, `changelog_history`, `legal_page` tai `locale_duplicate`. |

> **Tutkiminen on parhaan yrityksen periaatteella toimivaa.** Jos sivustoa ei voida lukea, vastaus on silti `200`, sisältäen `success: false`, tyhjän `pages`-listan ja `error`-viestin. Tarkista `success` ennen kuin luet `pages`.

Puuttuva `url` palauttaa `400`.

---

## Tuonnin kustannusarvio

`POST /kb-sources/estimate-cost`

Laskee, kuinka monta krediittiä ehdotettu tuonti kuluttaisi, ennen kuin vahvistat sen. Sivut haetaan ja asiakirjat luetaan niiden koon mittaamiseksi, mutta mitään ei tuoda, eikä itse arvio kuluta krediittejä.

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `urls` | Ei | Sivujen osoitteet, joiden tuomista harkitset. |
| `files` | Ei | Jo ladatut tiedostot, joita harkitset. Jokainen merkintä tarvitsee `storage_path`, `filename` ja `mime_type`. |
| `tier` | Ei | AI-laatutaso, jolla tuonti suoritetaan, jotta arvio vastaa todellisia kustannuksia. Jätä pois standardihintaa varten. |

Lähetä `urls`, `files` tai molemmat.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-sources/estimate-cost?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "urls": ["https://example.com/pricing"] }'
```

**Vastaus**

```json
{
  "success": true,
  "estimates": [
    { "ref": "https://example.com/pricing", "chunks": 7, "credits": 7 }
  ],
  "total_chunks": 7,
  "total_credits": 7
}
```

Jokainen rivi toistaa URL-osoitteen tai tallennuspolun kohteessa `ref`, jotta voit yhdistää sen syötteeseesi. Sivu tai tiedosto, jota ei voitu lukea, saa silti rivin, joka lasketaan yhdeksi lohkoksi, ja siinä on `error`.

---

## Tuonnin pysäyttäminen

`POST /kb-sources/cancel-import`

Pysäyttää tuontijonossa odottavat sivut – "pysäytä tuonti" -painike indeksoinnille, joka osoittautui odotettua suuremmaksi. Odottavan sivun peruuttaminen ei maksa mitään, koska sitä ei ole vielä luettu.

Jo käsiteltäviä sivuja **ei** pysäytetä: niiden työ on käynnissä ja niistä veloitetaan joka tapauksessa, joten ne valmistuvat. Vastaus kertoo, kuinka monta niitä oli.

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `host` | Ei | Pysäytä vain tämän verkkosivuston odottavat sivut (esimerkiksi `docs.example.com`). Jätä tyhjäksi, jos haluat pysäyttää kaikki tilin odottavat tuonnit. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-sources/cancel-import?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "host": "docs.example.com" }'
```

**Vastaus**

```json
{
  "success": true,
  "cancelled": 412,
  "in_flight": 3
}
```

---

## Keskeytetyn tuonnin jatkaminen

`POST /kb-sources/resume-import`

Käynnistää uudelleen tuonnin, joka keskeytettiin, koska oma AI-avaimesi lakkasi toimimasta.

> Tämän kutsuminen **on** suostumuksesi tuonnin viimeistelyyn sillä avaimella, joka on tällä hetkellä aktiivinen – mikä voi tarkoittaa alustan krediittien käyttöä, jos oma avaimesi on edelleen alhaalla.

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `host` | Ei | Jatka vain tämän verkkosivuston keskeytettyjä sivuja. Jätä tyhjäksi, jos haluat jatkaa kaikkia keskeytettyjä sivuja. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-sources/resume-import?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

**Vastaus**

```json
{
  "success": true,
  "resumed": 58
}
```

---

## Uusien sivujen etsiminen verkkosivustolta

`POST /kb-sources/refresh-domain`

Tutkii verkkosivuston, jolta olet jo tuonut tietoja, ja raportoi vain ne sivut, jotka **eivät** ole vielä tietokannassasi. Jokaisella on sama suositus kuin sivun löytämisessä. Mitään ei tuoda eikä mitään muuteta.

Nämä kaksi jatkotoimenpidettä ovat tarkoituksella erillisiä kutsuja, joten tästä poistuminen ei maksa mitään:

- tuo uudet haluamasi sivut käyttämällä [Tuo useita sivuja kerralla](#import-many-pages-at-once);
- lue uudelleen jo olemassa olevat sivut käyttämällä [Päivitä verkkosivuston jokainen sivu](#refresh-every-page-on-a-website).

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `baseUrl` | Kyllä | Mikä tahansa osoite verkkosivustolla tai vain isäntänimi. |
| `maxPages` | Ei | Yläraja sille, kuinka monta sivua tutkitaan. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-sources/refresh-domain?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "baseUrl": "https://example.com" }'
```

**Vastaus**

```json
{
  "success": true,
  "source_type": "sitemap",
  "discovered": 249,
  "new_pages": [
    {
      "url": "https://example.com/new-guide",
      "score": 95,
      "recommendation": "add",
      "reason_key": "core_page"
    }
  ],
  "new_urls_queued": 0,
  "existing_refresh_queued": 249
}
```

| Kenttä | Tyyppi | Kuvaus |
|---|---|---|
| `discovered` | kokonaisluku | Kuinka monta sivua sivustolta löytyi yhteensä. |
| `new_pages` | taulukko | Sivut, jotka eivät vielä ole tietokannassasi. Mitään ei aseteta jonoon puolestasi – tuo haluamasi sivut. |
| `new_urls_queued` | kokonaisluku | Aina `0`. Säilytetty taaksepäin yhteensopivuuden vuoksi; tämä päätepiste ei koskaan aseta mitään jonoon. |
| `existing_refresh_queued` | kokonaisluku | Kuinka monta jo tuomaasi sivua tältä sivustolta löytyi valmiina uudelleenluettavaksi. Tämä kutsu ei aseta mitään jonoon. |
| `batch_id` | merkkijono | Näkyy vain, kun erä on luotu. |

Kuten löytäminen, tämä epäonnistuu pehmeästi: sivusto, jota ei voida lukea, palauttaa silti `200`, jossa on `success: false`, tyhjä `new_pages` ja `error`. Puuttuva tai tyhjä `baseUrl` palauttaa `400`.

---

## Päivitä verkkosivuston jokainen sivu

`POST /kb-sources/trigger-domain-refresh`

Lukee uudelleen jokaisen sivun, jonka olet jo tuonut verkkosivustolta, jotta sen UKK-osiot vastaavat sivuston nykyistä sisältöä: muuttuneet osiot päivitetään, uudet osiot lisätään ja poistetut osiot poistetaan.

Tämä asettaa työn jonoon ja palauttaa vastauksen välittömästi. Seuraa sitä [Seuraa verkkosivuston päivitystä](#track-a-website-refresh) -toiminnolla ja pysäytä se [Pysäytä verkkosivuston päivitys](#stop-a-website-refresh) -toiminnolla.

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `baseUrl` | Kyllä | Mikä tahansa osoite verkkosivustolla tai vain isäntänimi. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-sources/trigger-domain-refresh?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "baseUrl": "https://example.com" }'
```

**Vastaus**

```json
{
  "success": true,
  "queued": 249
}
```

---

## Seuraa verkkosivuston päivitystä

`GET /kb-sources/domain-refresh-status`

Kuinka pitkällä verkkosivuston päivitys on, jotta voit näyttää edistymisen muodossa "221 / 249".

**Kyselyparametrit**

| Parametri | Pakollinen | Kuvaus |
|---|---|---|
| `baseUrl` | Kyllä | Mikä tahansa osoite verkkosivustolla tai vain isäntänimi. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/kb-sources/domain-refresh-status?baseUrl=https://example.com&apiKey=YOUR_API_KEY"
```

**Vastaus**

```json
{
  "success": true,
  "job": {
    "domainBatchId": "job_7c1e",
    "host": "example.com",
    "total": 249,
    "pending": 28,
    "succeeded": 219,
    "failed": 2,
    "skippedDuplicate": 0,
    "status": "refreshing",
    "startedAtIso": "2026-06-15T09:00:00.000Z"
  }
}
```

`job` on `null`, kun kyseiselle verkkosivustolle ei ole käynnissä päivitystä. Tähän mennessä valmistuneet sivut ovat `total` miinus `pending`. Työ `status` on jokin seuraavista: `refreshing` (käsittelee vielä sivuja), `deduplicating` (lopussa tehtävä puhdistusvaihe) tai lopullinen `completed`, `failed` ja `cancelled`. Säilytä `domainBatchId` – se on se, jonka välität peruutus-päätepisteelle.

Puuttuva tai tyhjä `baseUrl` palauttaa `400`.

---

## Pysäytä verkkosivuston päivitys

`POST /kb-sources/refresh-domain/cancel`

Pysäyttää verkkosivuston päivityksen, joka käsittelee vielä sivujaan. Jo valmistuneet sivut säilyttävät päivitetyn sisältönsä; aloittamattomat sivut hylätään, ja uudelleenluettavana olleet sivut palautuvat aiempaan tilaansa.

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `jobId` | Kyllä | [Verkkosivuston päivityksen seurannan](#track-a-website-refresh) palauttama `domainBatchId`. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-sources/refresh-domain/cancel?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "jobId": "job_7c1e" }'
```

**Vastaus**

```json
{
  "success": true,
  "status": "cancelled",
  "cancelled_units": 28,
  "sources_reset": 3,
  "sources_cancelled": 25
}
```

| Kenttä | Tyyppi | Kuvaus |
|---|---|---|
| `status` | merkkijono | Päivityksen tila tämän kutsun jälkeen: `cancelled`, `deduplicating`, `completed` tai `failed`. |
| `cancelled_units` | kokonaisluku | Kuinka paljon työtä oli vielä tekemättä, kun peruutus tapahtui. `0` toistuvassa peruutuksessa. |
| `sources_reset` | kokonaisluku | Käsittelystä poistetut ja `ready`-tilaan palautetut sivut. |
| `sources_cancelled` | kokonaisluku | Tämän päivityksen upouudet sivut, jotka olivat vielä jonossa ja on nyt peruutettu. |

Kahdesti peruuttaminen on vaaratonta – toinen kutsu raportoi saman lopputilan. Kun päivitys on siirtynyt siivousvaiheeseen, sitä ei voi enää pysäyttää, ja vastaus palauttaa `success: false` ja `reason: "already_finalizing"`. Puuttuva `jobId` palauttaa `400`, ja tiliisi kuulumaton työ palauttaa `404`.

---

## Päivitä yksittäinen lähde

`POST /kb-sources/{sourceId}/refresh`

Lukee uudelleen yhden jo tuomasi verkkosivun ja päivittää sen UKK-osiot vastaamaan sivun nykyistä sisältöä: muuttuneet osiot päivitetään, uudet lisätään ja poistetut poistetaan.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-sources/kb_src_abc123/refresh?apiKey=YOUR_API_KEY"
```

**Vastaus** — `202 Accepted`

```json
{
  "success": true,
  "source_id": "kb_src_abc123",
  "status": "queued"
}
```

Kysy lähteen tilaa, kunnes se ei ole enää `queued` tai `processing`. Tiliisi kuulumaton lähdetunnus palauttaa `404`.

---

## Valitse osuvimmat sivut

`POST /kb-sources/select-relevant-pages`

Pyytää tekoälyä valitsemaan ehdokaslistalta viisi sivua, jotka kuvaavat yritystä parhaiten – käytetään kampanjan pelikirjan luomiseen verkkosivustosta. Tämä kuluttaa krediittejä.

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `urls` | Kyllä | Valittavat ehdokassivujen osoitteet, yleensä sivujen etsinnästä. |
| `homeUrl` | Kyllä | Sivuston kotisivu, jota käytetään kontekstina valinnalle. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-sources/select-relevant-pages?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "homeUrl": "https://example.com",
    "urls": ["https://example.com/about", "https://example.com/pricing"]
  }'
```

**Vastaus**

```json
{
  "success": true,
  "pages": [
    { "url": "https://example.com/pricing", "title": "Pricing", "type": "pricing" }
  ]
}
```

Tämä on apuohjelma, ei resurssi: virhetilanteessa se vastaa silti `200`, `success: false`, tyhjällä `pages`-listalla ja `error`-viestillä.

---

## Tietoryhmät

**Tietoryhmä** on nimetty UKK-kokoelma – esimerkiksi "Toimitus ja palautukset" tai "Perehdytys" – jonka voit liittää agenttiin tai kampanjaan yhdellä kutsulla. Ryhmä sisältää viittauksia, ei kopioita: itse UKK-kysymykset pysyvät yhdessä kirjastossasi, joten yhden muokkaaminen [UKK-rajapinnan](faqs.md) kautta päivittää sen kaikkialla, missä sitä käytetään.

Ryhmän liittäminen **lisää** aina vain puuttuvat osat, joten saman ryhmän liittäminen kahdesti on vaaratonta ja `added_count` palauttaa `0` toisella kerralla.

---

## Luo tietoryhmä

`POST /kb-groups`

Luo ryhmän. Se on aluksi tyhjä – lisää siihen UKK-kysymyksiä kohdasta [Lisää UKK ryhmään](#add-a-faq-to-a-group).

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `name` | Kyllä | Ryhmän nimi. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-groups?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Shipping and returns" }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/kb-groups", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ name: "Shipping and returns" }),
});
const { group_id } = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/kb-groups",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"name": "Shipping and returns"},
)
group_id = res.json()["group_id"]
```

**Vastaus** — `201 Created`

```json
{
  "success": true,
  "group_id": "kbg_abc123"
}
```

---

## Nimeä tietoryhmä uudelleen

`PUT /kb-groups/{groupId}`

Muuttaa ryhmän nimen. Sen sisältämät UKK-kysymykset säilyvät ennallaan.

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `name` | Kyllä | Ryhmän uusi nimi. |

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/kb-groups/kbg_abc123?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Shipping, returns and refunds" }'
```

**Vastaus**

```json
{
  "success": true,
  "group_id": "kbg_abc123",
  "name": "Shipping, returns and refunds"
}
```

---

## Poista tietoryhmä

`DELETE /kb-groups/{groupId}`

Poistaa ryhmän. Vain kokoelma poistetaan – siinä olevat UKK-kysymykset säilyvät kirjastossasi, ja kaikki kohteet, joihin ryhmä oli jo liitetty, säilyttävät kyseiset UKK-kysymykset.

**cURL**

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/kb-groups/kbg_abc123?apiKey=YOUR_API_KEY"
```

**Vastaus**

```json
{
  "success": true
}
```

---

## Lisää UKK ryhmään

`POST /kb-groups/{groupId}/faqs`

Lisää olemassa olevan UKK:n ryhmään. Tämä muuttaa vain ryhmittelyä – se ei itsessään liitä UKK:ta mihinkään agenttiin; käytä ryhmää siihen tarkoitukseen.

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `faq_id` | Kyllä | Lisättävän UKK:n tunnus (ID). |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-groups/kbg_abc123/faqs?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "faq_id": "aBcD1234eFgH5678" }'
```

**Vastaus**

```json
{
  "success": true,
  "group_id": "kbg_abc123",
  "faq_id": "aBcD1234eFgH5678"
}
```

---

## Poista UKK ryhmästä

`DELETE /kb-groups/{groupId}/faqs/{faqId}`

Poistaa UKK:n ryhmästä. Itse UKK:ta ei poisteta, ja agentit, joille ryhmä on jo määritetty, säilyttävät sen.

**cURL**

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/kb-groups/kbg_abc123/faqs/aBcD1234eFgH5678?apiKey=YOUR_API_KEY"
```

**Vastaus**

```json
{
  "success": true,
  "group_id": "kbg_abc123",
  "faq_id": "aBcD1234eFgH5678"
}
```

---

## Määritä ryhmä agentille

`POST /kb-groups/{groupId}/apply-to-agent`

Lisää jokaisen ryhmän UKK:n tekoälyagentin tietopohjaan yhdellä kutsulla – tämä on nopein tapa antaa uudelle agentille valmiiksi kuratoitu tietopohja.

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `agent_id` | Kyllä | Sen tekoälyagentin tunnus (ID), jolle ryhmä määritetään. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-groups/kbg_abc123/apply-to-agent?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "agent_id": "ag7HkQ2ZpLxR3mNb" }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/kb-groups/kbg_abc123/apply-to-agent",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ agent_id: "ag7HkQ2ZpLxR3mNb" }),
  }
);
const { added_count } = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/kb-groups/kbg_abc123/apply-to-agent",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"agent_id": "ag7HkQ2ZpLxR3mNb"},
)
added_count = res.json()["added_count"]
```

**Vastaus**

```json
{
  "success": true,
  "group_id": "kbg_abc123",
  "agent_id": "ag7HkQ2ZpLxR3mNb",
  "added_count": 12
}
```

`added_count` kertoo, kuinka monta UKK:ta todellisuudessa lisättiin – `0`, jos ryhmä on tyhjä tai jo määritetty.

---

## Määritä ryhmä kampanjalle

`POST /kb-groups/{groupId}/apply-to-campaign`

Edellisen kutsun versio perinteisille kampanjoille. Agenttipohjaisella tilillä käytä sen sijaan [Määritä ryhmä agentille](#apply-a-group-to-an-agent)-toimintoa.

**Pyynnön kentät**

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `campaign_id` | Kyllä | Sen kampanjan tunnus, johon ryhmä liitetään. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/kb-groups/kbg_abc123/apply-to-campaign?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "campaign_id": "campaign123" }'
```

**Vastaus**

```json
{
  "success": true,
  "group_id": "kbg_abc123",
  "campaign_id": "campaign123",
  "added_count": 12
}
```

---

## Knowledge Base API -virheet

Nämä päätepisteet palauttavat vakiomuotoisen virhekuoren:

```json
{
  "success": false,
  "error": "Knowledge base source not found."
}
```

| Tila | Milloin se tapahtuu tietokannan päätepisteessä |
|---|---|
| `400` | Pakollinen kenttä puuttuu tai on virheellinen – tyhjä `url`, puuttuva `baseUrl` tai `jobId`, yli 100 URL-osoitetta massatuonnissa, yli 2 000 tunnusta massapoistossa tai tiedostotyyppi, jota emme voi lukea. |
| `402` | Ei riittävästi krediittejä tuonnin suorittamiseen. Lisää saldoa ja yritä uudelleen. |
| `403` | `storage_path` oman latauskansiosi ulkopuolella – tai tilauksesi ei sisällä API-käyttöoikeutta. |
| `404` | Lähdettä, ryhmää, FAQ-osiota, agenttia, kampanjaa tai päivitystyötä ei löytynyt – joko sitä ei ole olemassa tai se kuuluu toiselle tilille. |

> **Pehmeät virheet eivät ole varsinaisia virheitä.** Discovery (`discover-pages`, `refresh-domain`) ja sivunvalinta-apuohjelma vastaavat `200`-koodilla `success: false` ja `error`-viestillä, kun verkkosivustoa ei voida lukea, sen sijaan että pyyntö epäonnistuisi. Tarkista aina `success` ennen tietojen lukemista.

Jaetut koodit, joita jokainen päätepiste voi palauttaa — `401`, `403` (tilauksesi ei sisällä API-käyttöoikeutta), `429` (nopeusrajoitus) ja `500` — on lueteltu uudelleenyritysohjeiden kera kohdassa [Virheet ja sivutus](errors-and-pagination.md).

---

## Aiheeseen liittyvää

- [FAQs API](faqs.md) – lue, muokkaa ja linkitä lähteidesi tuottamia FAQ-osioita.
- [FAQ-osioiden hallinta](../ai-automation/faq-management.md) – sama tietokanta hallintapaneelissa.
- [AI-agentit](../ai-agents/ai-agents.md) – agentit, joihin liität lähteitä ja ryhmiä.
- [API-käyttöoikeus](../integrations/api-access.md) – luo API-avaimesi.
- [Todennus](authentication.md) – kaikki tavat välittää avaimesi.
