
# Knowledge Base API

Je knowledge base is de bron waar de AI uit leest. Deze bestaat uit twee onderdelen, en deze pagina behandelt beide:

- **Knowledge sources** (`/kb-sources`) — de webpagina's en geüploade documenten die je aan het platform toevoegt. Elk item wordt gelezen, opgesplitst in secties en omgezet in FAQ's die je AI kan beantwoorden.
- **Knowledge groups** (`/kb-groups`) — benoemde bundels van FAQ's die je in één aanroep kunt toepassen op een Agent of een campagne, zodat een kennisbank die je al hebt samengesteld, opnieuw kan worden gebruikt voor de volgende Agent die je maakt.

De FAQ's die een bron genereert, komen in dezelfde bibliotheek terecht als de FAQ's die je handmatig schrijft. Zodra een import is voltooid, kun je ze lezen, bewerken en koppelen met de [FAQs API](faqs.md).

Alle onderstaande eindpunten zijn relatief ten opzichte van de basis-URL `https://api.youraiconnector.com/v1`. Elk verzoek moet worden geverifieerd — zie [API-toegang](../integrations/api-access.md) en [Authenticatie](authentication.md). API-toegang is een betaalde functie; zonder deze functie worden verzoeken afgewezen met een `403`.


> **Importeren kost credits.** Het lezen van een pagina of document en het schrijven van FAQ's op basis daarvan verbruikt credits, ongeveer in verhouding tot de hoeveelheid inhoud. Gebruik [Een import schatten](#estimate-what-an-import-will-cost) voordat je een grote crawl start.

---

## Hoe een import werkt

Importeren is een achtergrondproces, geen actie die direct klaar is terwijl je wacht. Elk import-eindpunt antwoordt onmiddellijk met een `source_id`, en je polst die bron totdat deze klaar is:

1. **Start de import** — `POST /kb-sources/url` (één pagina), `POST /kb-sources/file` (een geüpload document), of `POST /kb-sources/bulk-import` (maximaal 100 pagina's). Je krijgt een bron-ID en `status: "queued"` terug.
2. **Polsen** — `GET /kb-sources/{sourceId}` totdat `status` niet langer `queued` of `processing` is.
3. **Lees de FAQ's** — wanneer de status `ready` is, staan de gegenereerde items in je FAQ-bibliotheek: `GET /faqs`.

Elke bron rapporteert een van deze statussen:

| Status | Wat het betekent |
|---|---|
| `queued` | Wacht om gelezen te worden. Er zijn nog geen kosten in rekening gebracht. |
| `processing` | Wordt momenteel gelezen en omgezet in FAQ's. |
| `ready` | Voltooid. De FAQ's staan in je bibliotheek. |
| `failed` | Kon niet worden geïmporteerd. `error_message` geeft de reden aan. |
| `cancelled` | Gestopt voordat het werd gelezen (zie [Een import stoppen](#stop-an-import)). |
| `paused` | Gestopt omdat je eigen AI-sleutel halverwege de import faalde (zie [Een gepauzeerde import hervatten](#resume-a-paused-import)). |
| `deleting` | Een bulkverwijdering is bezig met het verwerken ervan. |
| `unknown` | Het record heeft geen status. Behandel het als niet gereed. |

> **Koppelen tijdens het importeren.** Geef `autoLinkToAgentId` door bij elk import-eindpunt en de bron — plus elke FAQ die het genereert — wordt in dezelfde aanroep toegevoegd aan de kennis van die Agent, zonder dat er een extra koppelingsstap nodig is. `autoLinkToCampaignId` doet hetzelfde voor een klassieke campagne. Koppelen is een 'best effort'-proces: een ID dat niet bestaat of bij een ander account hoort, wordt stilzwijgend overgeslagen en de import gaat gewoon door. Controleer de koppeling dus door de Agent opnieuw uit te lezen.

---

## Een webpagina importeren

`POST /kb-sources/url`

Voegt één webpagina toe aan je knowledge base.

**Aanvraagvelden**

| Veld | Vereist | Beschrijving |
|---|---|---|
| `url` | Ja | Volledig `http` of `https` adres van de pagina. |
| `autoLinkToAgentId` | Nee | ID van een AI-agent waaraan de geïmporteerde bron moet worden gekoppeld. |
| `autoLinkToCampaignId` | Nee | Verouderd. ID van een campagne waaraan de geïmporteerde bron moet worden gekoppeld. |

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

**Antwoord** — `202 Accepted`

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

Poll `source_id` met [Controleer een bron](#check-a-source) totdat de status `ready` of `failed` is.

Als dezelfde pagina al in je kennisbank staat, wordt er niets nieuws in de wachtrij geplaatst en krijg je in plaats daarvan een `200` — en als je om een automatische koppeling hebt gevraagd, wordt de bestaande bron alsnog voor je gekoppeld:

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

Een ontbrekende `url`, of een die geen geldig `http`/`https` adres is, retourneert `400`.

---

## Een geüpload document importeren

`POST /kb-sources/file`

Voegt een document dat **al in de bestandsopslag van je account staat** toe als kennisbron. Ondersteunde typen: PDF, DOCX, TXT, MD, CSV en XLSX.

> **Dit eindpunt bevat het bestand niet.** Er is geen multipart-upload, geen base64-body en geen download-van-een-URL: je verstuurt de opslaglocatie van een bestand dat al bestaat, en dit moet zich in je eigen uploads-map bevinden (`storage_path` moet beginnen met `users/{your user id}/uploads/`), anders wordt het verzoek geweigerd met `403`. Het dashboard plaatst bestanden daar wanneer je ze erin sleept. Als je geen manier hebt om een bestand daar te plaatsen, importeer dan een webpagina met [Importeer een webpagina](#import-a-web-page).

**Aanvraagvelden**

| Veld | Vereist | Beschrijving |
|---|---|---|
| `storage_path` | Ja | Waar het geüploade bestand zich bevindt. Moet beginnen met `users/{your user id}/uploads/`. |
| `filename` | Ja | Oorspronkelijke bestandsnaam inclusief extensie — zo wordt het bestandstype gedetecteerd. |
| `mime_type` | Ja | MIME-type van het bestand, bijvoorbeeld `application/pdf`. |
| `autoLinkToAgentId` | Nee | ID van een AI-agent waaraan het document moet worden gekoppeld. |
| `autoLinkToCampaignId` | Nee | Verouderd. ID van een campagne waaraan het document moet worden gekoppeld. |

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

**Antwoord** — `202 Accepted`

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

| Status | Wanneer |
|---|---|
| `400` | Een vereist veld ontbreekt, of het bestand is van een type dat we niet kunnen lezen. |
| `403` | `storage_path` bevindt zich buiten je eigen uploads-map. |

---

## Een bron controleren

`GET /kb-sources/{sourceId}`

De poll die volgt op elke import en vernieuwing. Herhaal dit totdat de status `ready` of `failed` is.

**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()
```

**Antwoord**

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

| Veld | Type | Beschrijving |
|---|---|---|
| `status` | string | Waar de bron zich in de pipeline bevindt (zie de [statustabel](#how-an-import-works)). |
| `faq_count` | integer | Hoeveel FAQ's er tot nu toe uit deze bron zijn gegenereerd. |
| `section_count` | integer | In hoeveel inhoudssecties de bron is opgesplitst. |
| `error_message` | string \| null | Waarom de import is mislukt, wanneer de status `failed` is. Anders `null`. |

---

## Een bron verwijderen

`DELETE /kb-sources/{sourceId}`

Verwijdert één kennisbron. **Standaard blijven de FAQ's die deze heeft geproduceerd behouden** — voeg `delete_faqs=true` toe om deze ook te verwijderen.

**Queryparameters**

| Parameter | Vereist | Beschrijving |
|---|---|---|
| `delete_faqs` | Nee | Stel in op `true` om ook elke FAQ te verwijderen die deze bron heeft geproduceerd. Standaard `false`. |

**cURL**

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

**Antwoord**

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

`faqs_deleted` is `0` tenzij je om `delete_faqs=true` hebt gevraagd.

---

## Veel pagina's tegelijk importeren

`POST /kb-sources/bulk-import`

Voegt maximaal 100 webpagina's toe in één aanroep — het gebruikelijke vervolg op [Pagina's op een website ontdekken](#discover-pages-on-a-website) of [Nieuwe pagina's op een website vinden](#find-new-pages-on-a-website). Pagina's die al in je kennisbank staan, worden overgeslagen in plaats van gedupliceerd (en zijn nog steeds gekoppeld aan de Agent wanneer je daarom hebt gevraagd).

**Aanvraagvelden**

| Veld | Vereist | Beschrijving |
|---|---|---|
| `urls` | Ja | Adressen om te importeren. Minimaal 1, maximaal 100 per aanroep. |
| `autoLinkToAgentId` | Nee | ID van een AI-Agent om elke geïmporteerde pagina aan te koppelen. |
| `autoLinkToCampaignId` | Nee | Verouderd. ID van een campagne om elke geïmporteerde pagina aan te koppelen. |

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

**Antwoord** — `202 Accepted`

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

Poll elk ID in `queued_source_ids` met [Een bron controleren](#check-a-source). Het verzenden van een lege `urls` array, een niet-string invoer of meer dan 100 invoeren retourneert `400`.

---

## Veel bronnen tegelijk verwijderen

`POST /kb-sources/bulk-delete`

Verwijdert maximaal 2.000 kennisbronnen in één aanroep. De verwijdering wordt op de achtergrond uitgevoerd en je ontvangt een e-mail wanneer dit is voltooid.

> **Bulk verwijderen verwijdert ook altijd de FAQ's.** In tegenstelling tot [Een bron verwijderen](#delete-a-source), waarbij deze behouden blijven tenzij anders aangegeven, verwijdert dit eindpunt elke bron samen met de FAQ's die erdoor zijn gegenereerd. Er is geen optie om ze te behouden.

**Aanvraagvelden**

| Veld | Vereist | Beschrijving |
|---|---|---|
| `sourceIds` | Ja | ID's van de te verwijderen bronnen. Minimaal 1, maximaal 2.000 per aanroep. |
| `domainLabel` | Nee | Een vriendelijke naam voor deze opschoonactie. Wordt alleen gebruikt in de voltooiingsmail. |

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

**Antwoord** — `202 Accepted`

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

---

## Pagina's op een website ontdekken

`POST /kb-sources/discover-pages`

Verkent een website vanaf een startadres en somt de gevonden pagina's op hetzelfde domein op, elk met een oordeel over of het de moeite waard is om te importeren. **Er wordt niets geïmporteerd en er wordt niets voor u geselecteerd** — dit is de "wat staat er op deze site"-stap die u uitvoert voordat u beslist wat u wilt verzenden naar [Veel pagina's tegelijk importeren](#import-many-pages-at-once).

**Aanvraagvelden**

| Veld | Vereist | Beschrijving |
|---|---|---|
| `url` | Ja | Adres om de verkenning vanaf te starten, meestal de startpagina van de site. |
| `maxPages` | Nee | Bovengrens voor het aantal terug te geven pagina's. |

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

**Antwoord**

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

| Veld | Type | Beschrijving |
|---|---|---|
| `source_type` | string | Hoe de pagina's zijn gevonden — `sitemap` (de eigen sitemap van de site) of `link_discovery` (door links te volgen). |
| `url` | string | Volledig adres van de pagina. |
| `title` | string \| null | Paginatitel, indien deze kon worden gelezen. |
| `depth` | integer | Hoeveel links verwijderd van de startpagina deze pagina is gevonden. |
| `score` | integer | Hoe nuttig de pagina eruitziet als kennis, van `0` tot `100`. |
| `recommendation` | string | `add` (duidelijk de moeite waard om te importeren, score 90 of hoger), `maybe` (twijfelachtig), of `skip` (inhoud die zelden helpt bij een assistent — changelogs, juridische pagina's, dubbele vertalingen). |
| `reason_key` | string | Een stabiele, machineleesbare reden achter de aanbeveling, bijvoorbeeld `core_page`, `changelog_history`, `legal_page` of `locale_duplicate`. |

> **Verkenning is een inspanningsverplichting.** Als de site niet kan worden gelezen, is het antwoord nog steeds `200`, met `success: false`, een lege `pages`-lijst en een `error`-bericht. Controleer `success` voordat u `pages` leest.

Een ontbrekende `url` geeft `400` terug.

---

## Schat wat een import gaat kosten

`POST /kb-sources/estimate-cost`

Berekent hoeveel credits een voorgestelde import zou verbruiken, voordat u zich eraan verbindt. Pagina's worden opgehaald en documenten worden gelezen om hun grootte te meten, maar er wordt niets geïmporteerd en de schatting zelf kost geen credits.

**Aanvraagvelden**

| Veld | Vereist | Beschrijving |
|---|---|---|
| `urls` | Nee | Pagina-adressen die u overweegt te importeren. |
| `files` | Nee | Reeds geüploade bestanden die u overweegt. Elk item vereist `storage_path`, `filename` en `mime_type`. |
| `tier` | Nee | Het AI-kwaliteitsniveau waarop de import zal draaien, zodat de schatting overeenkomt met wat er daadwerkelijk in rekening wordt gebracht. Laat dit weg voor het standaardtarief. |

Verzend `urls`, `files`, of beide.

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

**Antwoord**

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

Elke rij weerspiegelt de URL of het opslagpad in `ref`, zodat u deze kunt koppelen aan uw invoer. Een pagina of bestand dat niet kon worden gelezen, krijgt nog steeds een rij, geteld als één chunk, met een `error` erop.

---

## Een import stoppen

`POST /kb-sources/cancel-import`

Stopt pagina's die nog in de importwachtrij staan — de "import stoppen"-knop voor een crawl die groter bleek dan u had verwacht. Het annuleren van een wachtende pagina kost niets, omdat deze nog niet is gelezen.

Pagina's die al worden verwerkt, worden **niet** gestopt: het werk is al gaande en wordt hoe dan ook in rekening gebracht, dus deze worden voltooid. Het antwoord rapporteert hoeveel dat er waren.

**Aanvraagvelden**

| Veld | Verplicht | Beschrijving |
|---|---|---|
| `host` | Nee | Stop alleen wachtende pagina's op deze website (bijvoorbeeld `docs.example.com`). Laat dit leeg om elke wachtende import in het account te stoppen. |

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

**Antwoord**

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

---

## Een gepauzeerde import hervatten

`POST /kb-sources/resume-import`

Start een import opnieuw die was gepauzeerd omdat uw eigen AI-sleutel niet meer werkte.

> Door dit aan te roepen geeft u **toestemming** om de import te voltooien met de sleutel die op dat moment actief is — wat kan betekenen dat er platformcredits worden verbruikt als uw eigen sleutel nog steeds niet werkt.

**Aanvraagvelden**

| Veld | Verplicht | Beschrijving |
|---|---|---|
| `host` | Nee | Hervat alleen gepauzeerde pagina's op deze website. Laat dit leeg om alles wat gepauzeerd is te hervatten. |

**cURL**

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

**Antwoord**

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

---

## Nieuwe pagina's op een website vinden

`POST /kb-sources/refresh-domain`

Verkent een website waarvan u al eerder hebt geïmporteerd en rapporteert alleen de pagina's die nog **niet** in uw kennisbank staan, elk met dezelfde aanbeveling als bij paginadetectie. Er wordt niets geïmporteerd en er wordt niets gewijzigd.

De twee vervolgacties zijn bewust afzonderlijke aanroepen, dus deze actie uitvoeren kost niets:

- importeer de nieuwe pagina's die je wilt met [Importeer meerdere pagina's tegelijk](#import-many-pages-at-once);
- lees de pagina's die je al hebt opnieuw in met [Vernieuw elke pagina op een website](#refresh-every-page-on-a-website).

**Aanvraagvelden**

| Veld | Vereist | Beschrijving |
|---|---|---|
| `baseUrl` | Ja | Elk adres op de website, of alleen de host. |
| `maxPages` | Nee | Bovengrens voor het aantal te verkennen pagina's. |

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

**Antwoord**

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

| Veld | Type | Beschrijving |
|---|---|---|
| `discovered` | integer | Hoeveel pagina's er in totaal op de site zijn gevonden. |
| `new_pages` | array | Pagina's die nog niet in je kennisbank staan. Er wordt niets voor je in de wachtrij geplaatst — importeer de pagina's die je wilt. |
| `new_urls_queued` | integer | Altijd `0`. Behouden voor achterwaartse compatibiliteit; dit eindpunt plaatst nooit iets in de wachtrij. |
| `existing_refresh_queued` | integer | Hoeveel pagina's die je al van deze site hebt geïmporteerd, klaarstonden om opnieuw te worden ingelezen. Er wordt niets in de wachtrij geplaatst door deze aanroep. |
| `batch_id` | string | Alleen aanwezig wanneer er een batch is aangemaakt. |

Net als bij ontdekking faalt dit op een zachte manier: een site die niet kan worden gelezen, retourneert nog steeds `200`, met `success: false`, een lege `new_pages` en een `error`. Een ontbrekende of lege `baseUrl` retourneert `400`.

---

## Vernieuw elke pagina op een website

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

Leest elke pagina die je al van een website hebt geïmporteerd opnieuw in, zodat de veelgestelde vragen de huidige inhoud van de site volgen: gewijzigde secties worden bijgewerkt, nieuwe secties worden toegevoegd en verwijderde secties worden verwijderd.

Dit plaatst werk in de wachtrij en keert onmiddellijk terug. Volg dit op met [Volg een websitevernieuwing](#track-a-website-refresh) en stop het met [Stop een websitevernieuwing](#stop-a-website-refresh).

**Aanvraagvelden**

| Veld | Vereist | Beschrijving |
|---|---|---|
| `baseUrl` | Ja | Elk adres op de website, of alleen de host. |

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

**Antwoord**

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

---

## Volg een websitevernieuwing

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

Hoe ver een websitevernieuwing is gevorderd, zodat je de voortgang kunt tonen als "221 van 249".

**Queryparameters**

| Parameter | Vereist | Beschrijving |
|---|---|---|
| `baseUrl` | Ja | Elk adres op de website, of alleen de host. |

**cURL**

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

**Antwoord**

```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` is `null` wanneer er geen vernieuwing voor die website wordt uitgevoerd. Het aantal voltooide pagina's tot nu toe is `total` minus `pending`. De taak `status` is een van `refreshing` (nog bezig met pagina's), `deduplicating` (de opschoonronde aan het einde), of de uiteindelijke `completed`, `failed` en `cancelled`. Bewaar `domainBatchId` — dit is wat je doorgeeft aan het annuleer-eindpunt.

Een ontbrekende of lege `baseUrl` retourneert `400`.

---

## Een websiteverversing stoppen

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

Stopt een websiteverversing die nog bezig is met het verwerken van pagina's. Pagina's die al klaar zijn, behouden hun bijgewerkte inhoud; pagina's die nog niet zijn gestart, worden verwijderd, en pagina's die opnieuw werden gelezen, keren terug naar hun vorige staat.

**Aanvraagvelden**

| Veld | Vereist | Beschrijving |
|---|---|---|
| `jobId` | Ja | De `domainBatchId` geretourneerd door [Een websiteverversing volgen](#track-a-website-refresh). |

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

**Antwoord**

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

| Veld | Type | Beschrijving |
|---|---|---|
| `status` | string | Status van de verversing na deze aanroep: `cancelled`, `deduplicating`, `completed` of `failed`. |
| `cancelled_units` | integer | Hoeveel werk er nog openstond toen de annulering plaatsvond. `0` bij een herhaalde annulering. |
| `sources_reset` | integer | Pagina's die uit de verwerking zijn gehaald en teruggezet naar `ready`. |
| `sources_cancelled` | integer | Gloednieuwe pagina's van deze verversing die nog in de wachtrij stonden en nu zijn geannuleerd. |

Twee keer annuleren is onschadelijk — de tweede aanroep rapporteert dezelfde eindstatus. Zodra de verversing is overgegaan naar de opschoonfase, kan deze niet meer worden gestopt en komt het antwoord terug met `success: false` en `reason: "already_finalizing"`. Een ontbrekende `jobId` retourneert `400`, en een taak die niet in uw account staat, retourneert `404`.

---

## Eén bron verversen

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

Leest één webpagina opnieuw in die u al hebt geïmporteerd en brengt de bijbehorende FAQ's weer in lijn met de huidige inhoud van de pagina: gewijzigde secties worden bijgewerkt, nieuwe worden toegevoegd, verwijderde worden geschrapt.

**cURL**

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

**Antwoord** — `202 Accepted`

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

Poll de bron totdat de status `queued` en `processing` verlaat. Een bron-ID die niet in uw account staat, retourneert `404`.

---

## De meest relevante pagina's kiezen

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

Vraagt de AI om uit een lijst met kandidaten de vijf pagina's te kiezen die een bedrijf het beste beschrijven — wordt gebruikt bij het genereren van een campagne-playbook op basis van een website. Dit verbruikt credits.

**Aanvraagvelden**

| Veld | Vereist | Beschrijving |
|---|---|---|
| `urls` | Ja | Kandidaat-paginadressen om uit te kiezen, meestal afkomstig van paginadetectie. |
| `homeUrl` | Ja | De startpagina van de site, gebruikt als context voor de keuze. |

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

**Antwoord**

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

Dit is een helper, geen resource: bij een fout antwoordt het nog steeds `200`, met `success: false`, een lege `pages` lijst en een `error` bericht.

---

## Kennisgroepen

Een **kennisgroep** is een benoemde bundel van veelgestelde vragen (FAQ's) — "Verzending en retourneren", "Onboarding" — die u in één aanroep kunt toepassen op een Agent of een campagne. De groep bevat verwijzingen, geen kopieën: de FAQ's zelf blijven in uw centrale bibliotheek staan, dus het bewerken van een FAQ met de [FAQs API](faqs.md) werkt deze overal bij waar deze wordt gebruikt.

Het toepassen van een groep **voegt** alleen toe wat ontbreekt, dus het twee keer toepassen van dezelfde groep is ongevaarlijk en `added_count` komt de tweede keer terug als `0`.

---

## Een kennisgroep aanmaken

`POST /kb-groups`

Maakt een groep aan. Deze begint leeg — voeg FAQ's toe met [Een FAQ toevoegen aan een groep](#add-a-faq-to-a-group).

**Aanvraagvelden**

| Veld | Vereist | Beschrijving |
|---|---|---|
| `name` | Ja | Naam van de groep. |

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

**Antwoord** — `201 Created`

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

---

## Een kennisgroep hernoemen

`PUT /kb-groups/{groupId}`

Wijzigt de naam van een groep. De FAQ's in de groep blijven ongewijzigd.

**Aanvraagvelden**

| Veld | Vereist | Beschrijving |
|---|---|---|
| `name` | Ja | Nieuwe naam voor de groep. |

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

**Antwoord**

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

---

## Een kennisgroep verwijderen

`DELETE /kb-groups/{groupId}`

Verwijdert de groep. Alleen de bundel wordt verwijderd — de FAQ's erin blijven in uw bibliotheek staan, en alles waarop de groep al was toegepast, behoudt die FAQ's.

**cURL**

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

**Antwoord**

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

---

## Een FAQ toevoegen aan een groep

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

Plaatst een bestaande FAQ in een groep. Dit wijzigt alleen de bundel — het koppelt de FAQ niet uit zichzelf aan een Agent; pas daarvoor de groep toe.

**Aanvraagvelden**

| Veld | Verplicht | Beschrijving |
|---|---|---|
| `faq_id` | Ja | ID van de toe te voegen FAQ. |

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

**Antwoord**

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

---

## Een FAQ verwijderen uit een groep

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

Haalt een FAQ uit een groep. De FAQ zelf wordt niet verwijderd en Agents waaraan de groep al was toegewezen, behouden deze.

**cURL**

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

**Antwoord**

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

---

## Een groep toepassen op een Agent

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

Voegt elke FAQ in de groep in één aanroep toe aan de kennis van een AI Agent — de snelle manier om een nieuwe Agent te voorzien van een kennisbank die je al hebt samengesteld.

**Aanvraagvelden**

| Veld | Verplicht | Beschrijving |
|---|---|---|
| `agent_id` | Ja | ID van de AI Agent waarop de groep moet worden toegepast. |

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

**Antwoord**

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

`added_count` is het aantal FAQ's dat daadwerkelijk is toegevoegd — `0` wanneer de groep leeg is of al is toegepast.

---

## Een groep toepassen op een campagne

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

De classic-campaign versie van de bovenstaande aanroep. Gebruik op een account op basis van Agents in plaats daarvan [Een groep toepassen op een Agent](#apply-a-group-to-an-agent).

**Aanvraagvelden**

| Veld | Vereist | Beschrijving |
|---|---|---|
| `campaign_id` | Ja | ID van de campagne waarop de groep moet worden toegepast. |

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

**Antwoord**

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

---

## Knowledge Base API-fouten

Deze endpoints retourneren de standaard fouten-envelop:

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

| Status | Wanneer dit gebeurt op een knowledge base-endpoint |
|---|---|
| `400` | Een vereist veld ontbreekt of is ongeldig — een lege `url`, een ontbrekende `baseUrl` of `jobId`, meer dan 100 URL's bij een bulkimport, meer dan 2.000 ID's bij een bulkverwijdering, of een bestandstype dat we niet kunnen lezen. |
| `402` | Onvoldoende credits om de import uit te voeren. Waardeer op en probeer het opnieuw. |
| `403` | Een `storage_path` buiten je eigen uploadmap — of je abonnement bevat geen API-toegang. |
| `404` | De bron, groep, FAQ, Agent, campagne of verversingstaak is niet gevonden — deze bestaat niet of behoort tot een ander account. |

> **Soft failures zijn geen fouten.** Discovery (`discover-pages`, `refresh-domain`) en de helper voor het kiezen van pagina's antwoorden `200` met `success: false` en een `error`-bericht wanneer de website niet kan worden gelezen, in plaats van het verzoek te laten mislukken. Controleer altijd `success` voordat je de gegevens leest.

De gedeelde codes die elk endpoint kan retourneren — `401`, `403` (uw abonnement bevat geen API-toegang), `429` (snelheidslimiet) en `500` — worden vermeld met richtlijnen voor opnieuw proberen in [Fouten & Paginering](errors-and-pagination.md).

---

## Gerelateerd

- [FAQs API](faqs.md) — lees, bewerk en koppel de FAQ's die je bronnen genereren.
- [FAQ's beheren](../ai-automation/faq-management.md) — dezelfde knowledge base in het dashboard.
- [AI Agents](../ai-agents/ai-agents.md) — de Agents waaraan je bronnen en groepen koppelt.
- [API-toegang](../integrations/api-access.md) — genereer je API-sleutel.
- [Authenticatie](authentication.md) — alle manieren om je sleutel door te geven.
