
# API bazy wiedzy

Twoja baza wiedzy to źródło, z którego korzysta sztuczna inteligencja. Składa się ona z dwóch części, a ta strona omawia obie z nich:

- **Źródła wiedzy** (`/kb-sources`) — strony internetowe i przesłane dokumenty, które dostarczasz platformie. Każde z nich jest odczytywane, dzielone na sekcje i przekształcane w odpowiedzi na często zadawane pytania (FAQ), z których może korzystać Twoja sztuczna inteligencja.
- **Grupy wiedzy** (`/kb-groups`) — nazwane zestawy FAQ, które możesz zastosować do Agenta lub kampanii w jednym wywołaniu, dzięki czemu raz przygotowany zasób wiedzy można ponownie wykorzystać w kolejnym tworzonym Agencie.

FAQ wygenerowane ze źródła trafiają do tej samej biblioteki, co te napisane ręcznie, więc po zakończeniu importu możesz je przeglądać, edytować i łączyć za pomocą [API FAQ](faqs.md).

Wszystkie poniższe punkty końcowe odnoszą się do bazowego adresu URL `https://api.youraiconnector.com/v1`. Każde żądanie musi zostać uwierzytelnione — zobacz [Dostęp do API](../integrations/api-access.md) oraz [Uwierzytelnianie](authentication.md). Dostęp do API jest funkcją płatną; bez niego żądania będą odrzucane z błędem `403`.


> **Importowanie kosztuje kredyty.** Odczytanie strony lub dokumentu i utworzenie z nich FAQ zużywa kredyty, mniej więcej proporcjonalnie do ilości zawartości. Skorzystaj z [Szacowania importu](#estimate-what-an-import-will-cost) przed rozpoczęciem dużego procesu indeksowania.

---

## Jak działa import

Importowanie to zadanie działające w tle, a nie proces, który kończy się natychmiast. Każdy punkt końcowy importu odpowiada natychmiast za pomocą `source_id`, a Ty odpytujesz to źródło, aż do zakończenia procesu:

1. **Rozpocznij import** — `POST /kb-sources/url` (jedna strona), `POST /kb-sources/file` (przesłany dokument) lub `POST /kb-sources/bulk-import` (do 100 stron). Otrzymasz identyfikator źródła oraz `status: "queued"`.
2. **Odpytuj** — `GET /kb-sources/{sourceId}`, aż `status` przestanie mieć wartość `queued` lub `processing`.
3. **Odczytaj FAQ** — gdy status to `ready`, wygenerowane wpisy znajdują się w Twojej bibliotece FAQ: `GET /faqs`.

Każde źródło zgłasza jeden z następujących statusów:

| Status | Co to oznacza |
|---|---|
| `queued` | Oczekiwanie na odczytanie. Jeszcze nie pobrano opłat. |
| `processing` | Trwa odczytywanie i przekształcanie w FAQ. |
| `ready` | Zakończono. FAQ znajdują się w Twojej bibliotece. |
| `failed` | Nie udało się zaimportować. `error_message` wyjaśnia dlaczego. |
| `cancelled` | Zatrzymano przed odczytaniem (zobacz [Zatrzymanie importu](#stop-an-import)). |
| `paused` | Zatrzymano, ponieważ Twój klucz AI zawiódł w trakcie importu (zobacz [Wznawianie wstrzymanego importu](#resume-a-paused-import)). |
| `deleting` | Trwa masowe usuwanie danych. |
| `unknown` | Rekord nie posiada statusu. Traktuj go jako niegotowy. |

> **Dołączaj podczas importu.** Przekaż `autoLinkToAgentId` w dowolnym punkcie końcowym importu, a źródło — wraz ze wszystkimi wygenerowanymi przez nie FAQ — trafi do bazy wiedzy Agenta w tym samym wywołaniu, bez konieczności wykonywania dodatkowego kroku łączenia. `autoLinkToCampaignId` robi to samo dla klasycznej kampanii. Łączenie odbywa się w miarę możliwości: identyfikator, który nie istnieje lub należy do innego konta, jest pomijany bez powiadomienia, a import nadal trwa, więc potwierdź połączenie, odczytując dane Agenta.

---

## Importowanie strony internetowej

`POST /kb-sources/url`

Dodaje jedną stronę internetową do Twojej bazy wiedzy.

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `url` | Tak | Pełny adres `http` lub `https` strony. |
| `autoLinkToAgentId` | Nie | Identyfikator agenta AI, do którego ma zostać przypisane importowane źródło. |
| `autoLinkToCampaignId` | Nie | Starsza wersja. Identyfikator kampanii, do której ma zostać przypisane importowane źródło. |

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

**Odpowiedź** — `202 Accepted`

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

Odpytuj `source_id` za pomocą [Sprawdź źródło](#check-a-source), aż status będzie `ready` lub `failed`.

Jeśli ta sama strona znajduje się już w Twojej bazie wiedzy, nic nowego nie zostanie dodane do kolejki i otrzymasz `200` — a jeśli poprosiłeś o automatyczne połączenie, istniejące źródło zostanie dla Ciebie powiązane:

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

Brakujący `url` lub adres, który nie jest poprawnym adresem `http`/`https`, zwraca `400`.

---

## Importuj przesłany dokument

`POST /kb-sources/file`

Dodaje dokument, który **znajduje się już w pamięci plików Twojego konta**, jako źródło wiedzy. Obsługiwane typy: PDF, DOCX, TXT, MD, CSV i XLSX.

> **Ten punkt końcowy nie przesyła pliku.** Nie ma tu przesyłania wieloczęściowego (multipart), treści base64 ani pobierania z adresu URL: wysyłasz lokalizację pliku, który już istnieje, i musi on znajdować się w Twoim własnym folderze przesyłania (`storage_path` musi zaczynać się od `users/{your user id}/uploads/`), w przeciwnym razie żądanie zostanie odrzucone z `403`. Panel sterowania umieszcza tam pliki, gdy przeciągniesz je do okna. Jeśli nie masz możliwości umieszczenia tam pliku, zaimportuj stronę internetową za pomocą [Importuj stronę internetową](#import-a-web-page).

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `storage_path` | Tak | Gdzie znajduje się przesłany plik. Musi zaczynać się od `users/{your user id}/uploads/`. |
| `filename` | Tak | Oryginalna nazwa pliku wraz z rozszerzeniem — w ten sposób wykrywany jest typ pliku. |
| `mime_type` | Tak | Typ MIME pliku, na przykład `application/pdf`. |
| `autoLinkToAgentId` | Nie | Identyfikator agenta AI, do którego ma zostać przypisany dokument. |
| `autoLinkToCampaignId` | Nie | Starsza wersja. Identyfikator kampanii, do której ma zostać przypisany dokument. |

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

**Odpowiedź** — `202 Accepted`

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

| Status | Kiedy |
|---|---|
| `400` | Brakuje wymaganego pola lub plik jest typu, którego nie możemy odczytać. |
| `403` | `storage_path` znajduje się poza Twoim własnym folderem przesyłania. |

---

## Sprawdź źródło

`GET /kb-sources/{sourceId}`

Odpytywanie, które następuje po każdym imporcie i odświeżeniu. Powtarzaj je, aż status będzie `ready` lub `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()
```

**Odpowiedź**

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

| Pole | Typ | Opis |
|---|---|---|
| `status` | string | Gdzie znajduje się źródło w potoku (zobacz [tabelę statusów](#how-an-import-works)). |
| `faq_count` | integer | Ile FAQ zostało wygenerowanych z tego źródła do tej pory. |
| `section_count` | integer | Na ile sekcji treści zostało podzielone źródło. |
| `error_message` | string \| null | Dlaczego import się nie powiódł, gdy status to `failed`. W przeciwnym razie `null`. |

---

## Usuwanie źródła

`DELETE /kb-sources/{sourceId}`

Usuwa jedno źródło wiedzy. **Domyślnie wygenerowane przez nie FAQ są zachowywane** — dodaj `delete_faqs=true`, aby usunąć również je.

**Parametry zapytania**

| Parametr | Wymagane | Opis |
|---|---|---|
| `delete_faqs` | Nie | Ustaw na `true`, aby usunąć również każde FAQ wygenerowane przez to źródło. Domyślnie `false`. |

**cURL**

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

**Odpowiedź**

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

`faqs_deleted` to `0`, chyba że poprosisz o `delete_faqs=true`.

---

## Importowanie wielu stron jednocześnie

`POST /kb-sources/bulk-import`

Dodaje do 100 stron internetowych w jednym wywołaniu — jest to typowy krok po [Odkrywaniu stron w witrynie](#discover-pages-on-a-website) lub [Wyszukiwaniu nowych stron w witrynie](#find-new-pages-on-a-website). Strony, które już znajdują się w Twojej bazie wiedzy, są pomijane zamiast duplikowania (i nadal są powiązane z Agentem, jeśli o to poprosisz).

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `urls` | Tak | Adresy do zaimportowania. Co najmniej 1, maksymalnie 100 na wywołanie. |
| `autoLinkToAgentId` | Nie | Identyfikator Agenta AI, do którego należy przypisać każdą zaimportowaną stronę. |
| `autoLinkToCampaignId` | Nie | Starsza wersja. Identyfikator kampanii, do której należy przypisać każdą zaimportowaną stronę. |

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

**Odpowiedź** — `202 Accepted`

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

Odpytuj każdy identyfikator w `queued_source_ids` za pomocą [Sprawdź źródło](#check-a-source). Przesłanie pustej tablicy `urls`, wpisu niebędącego ciągiem znaków lub więcej niż 100 wpisów zwróci `400`.

---

## Usuwanie wielu źródeł jednocześnie

`POST /kb-sources/bulk-delete`

Usuwa do 2000 źródeł wiedzy w jednym wywołaniu. Usuwanie odbywa się w tle, a po jego zakończeniu otrzymasz wiadomość e-mail.

> **Masowe usuwanie zawsze usuwa również FAQ.** W przeciwieństwie do [Usuwania źródła](#delete-a-source), które zachowuje je, chyba że zaznaczysz inaczej, ten punkt końcowy usuwa każde źródło wraz z wygenerowanymi przez nie FAQ. Nie ma opcji ich zachowania.

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `sourceIds` | Tak | Identyfikatory źródeł do usunięcia. Co najmniej 1, maksymalnie 2000 na wywołanie. |
| `domainLabel` | Nie | Przyjazna nazwa dla tego czyszczenia. Używana tylko w wiadomości e-mail o zakończeniu. |

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

**Odpowiedź** — `202 Accepted`

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

---

## Odkrywanie stron w witrynie

`POST /kb-sources/discover-pages`

Przeszukuje witrynę od wskazanego adresu początkowego i wyświetla listę stron znalezionych w tej samej domenie, z oceną, czy warto je zaimportować. **Nic nie jest importowane i nic nie jest wybierane automatycznie** — jest to krok „co znajduje się w tej witrynie”, który wykonujesz przed podjęciem decyzji, co wysłać do [Importu wielu stron jednocześnie](#import-many-pages-at-once).

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `url` | Tak | Adres, od którego należy rozpocząć przeszukiwanie, zazwyczaj strona główna witryny. |
| `maxPages` | Nie | Górny limit liczby stron do zwrócenia. |

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

**Odpowiedź**

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

| Pole | Typ | Opis |
|---|---|---|
| `source_type` | string | Sposób znalezienia stron — `sitemap` (własna mapa witryny) lub `link_discovery` (poprzez śledzenie linków). |
| `url` | string | Pełny adres strony. |
| `title` | string \| null | Tytuł strony, jeśli udało się go odczytać. |
| `depth` | integer | Jak daleko od strony początkowej znaleziono tę stronę (liczba linków). |
| `score` | integer | Jak użyteczna wydaje się strona jako wiedza, od `0` do `100`. |
| `recommendation` | string | `add` (zdecydowanie warto zaimportować, wynik 90 lub wyższy), `maybe` (na granicy) lub `skip` (treści rzadko przydatne dla asystenta — dzienniki zmian, strony prawne, zduplikowane tłumaczenia). |
| `reason_key` | string | Stabilny, czytelny dla maszyny powód rekomendacji, na przykład `core_page`, `changelog_history`, `legal_page` lub `locale_duplicate`. |

> **Eksploracja jest wykonywana w miarę możliwości.** Jeśli witryny nie można odczytać, odpowiedź to nadal `200`, z `success: false`, pustą listą `pages` i komunikatem `error`. Sprawdź `success` przed odczytaniem `pages`.

Brakujący `url` zwraca `400`.

---

## Szacowanie kosztów importu

`POST /kb-sources/estimate-cost`

Oblicza, ile kredytów zużyłby proponowany import, zanim go zatwierdzisz. Strony są pobierane, a dokumenty odczytywane w celu zmierzenia ich rozmiaru, ale nic nie jest importowane, a samo oszacowanie nie zużywa kredytów.

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `urls` | Nie | Adresy stron, które rozważasz zaimportować. |
| `files` | Nie | Już przesłane pliki, które rozważasz. Każdy wpis wymaga `storage_path`, `filename` i `mime_type`. |
| `tier` | Nie | Poziom jakości AI, na którym zostanie uruchomiony import, aby szacunek odpowiadał kwocie, która zostanie faktycznie pobrana. Pozostaw puste dla stawki standardowej. |

Wyślij `urls`, `files` lub oba.

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

**Odpowiedź**

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

Każdy wiersz odzwierciedla adres URL lub ścieżkę przechowywania w `ref`, dzięki czemu można dopasować go do danych wejściowych. Strona lub plik, których nie udało się odczytać, również otrzymują wiersz, liczony jako jeden fragment, z oznaczeniem `error`.

---

## Zatrzymanie importu

`POST /kb-sources/cancel-import`

Zatrzymuje strony, które wciąż oczekują w kolejce importu — przycisk „zatrzymaj import” dla indeksowania, które okazało się większe, niż oczekiwano. Anulowanie oczekującej strony nic nie kosztuje, ponieważ nie została ona jeszcze odczytana.

Strony, które są już przetwarzane, **nie** zostają zatrzymane: ich przetwarzanie trwa i jest naliczane w każdym przypadku, więc zostaną ukończone. Odpowiedź zawiera informację, ile takich stron było.

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `host` | Nie | Zatrzymaj tylko oczekujące strony w tej witrynie (na przykład `docs.example.com`). Pozostaw puste, aby zatrzymać każdy oczekujący import na koncie. |

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

**Odpowiedź**

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

---

## Wznawianie wstrzymanego importu

`POST /kb-sources/resume-import`

Restartuje import, który został wstrzymany, ponieważ Twój własny klucz AI przestał działać.

> Wywołanie tego **jest** Twoją zgodą na dokończenie importu przy użyciu klucza, który jest aktualnie aktywny — co może oznaczać zużycie kredytów platformy, jeśli Twój własny klucz nadal nie działa.

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `host` | Nie | Wznów tylko wstrzymane strony w tej witrynie. Pozostaw puste, aby wznowić wszystko, co zostało wstrzymane. |

**cURL**

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

**Odpowiedź**

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

---

## Znajdowanie nowych stron w witrynie

`POST /kb-sources/refresh-domain`

Przeszukuje witrynę, z której już importowano dane, i zgłasza tylko te strony, których **nie ma** jeszcze w Twojej bazie wiedzy, każdą z taką samą rekomendacją jak w przypadku odkrywania stron. Nic nie jest importowane i nic nie jest zmieniane.

Dwa kolejne kroki są celowo oddzielnymi wywołaniami, więc zrezygnowanie z tego etapu nic nie kosztuje:

- zaimportuj nowe strony, których potrzebujesz, korzystając z [Importuj wiele stron jednocześnie](#import-many-pages-at-once);
- odśwież strony, które już posiadasz, korzystając z [Odśwież każdą stronę w witrynie](#refresh-every-page-on-a-website).

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `baseUrl` | Tak | Dowolny adres w witrynie lub tylko host. |
| `maxPages` | Nie | Górna granica liczby stron do przeszukania. |

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

**Odpowiedź**

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

| Pole | Typ | Opis |
|---|---|---|
| `discovered` | liczba całkowita | Łączna liczba stron znalezionych w witrynie. |
| `new_pages` | tablica | Strony, których nie ma jeszcze w Twojej bazie wiedzy. Nic nie jest dla Ciebie kolejkowane — zaimportuj te, które chcesz. |
| `new_urls_queued` | liczba całkowita | Zawsze `0`. Zachowane dla kompatybilności wstecznej; ten punkt końcowy nigdy niczego nie kolejkuje. |
| `existing_refresh_queued` | liczba całkowita | Liczba stron już zaimportowanych z tej witryny, które zostały uznane za gotowe do ponownego odczytania. To wywołanie niczego nie kolejkuje. |
| `batch_id` | ciąg znaków | Obecne tylko wtedy, gdy utworzono partię. |

Podobnie jak w przypadku wykrywania, kończy się to łagodnym niepowodzeniem: witryna, której nie można odczytać, nadal zwraca `200`, z `success: false`, pustym `new_pages` oraz `error`. Brakujący lub pusty `baseUrl` zwraca `400`.

---

## Odśwież każdą stronę w witrynie

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

Ponownie odczytuje każdą stronę, która została już zaimportowana z witryny, dzięki czemu jej sekcje FAQ są zgodne z aktualną zawartością witryny: zmienione sekcje są aktualizowane, nowe dodawane, a usunięte usuwane.

To kolejkuje zadanie i zwraca odpowiedź natychmiast. Następnie użyj [Śledź odświeżanie witryny](#track-a-website-refresh), a aby je zatrzymać, użyj [Zatrzymaj odświeżanie witryny](#stop-a-website-refresh).

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `baseUrl` | Tak | Dowolny adres w witrynie lub tylko 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" }'
```

**Odpowiedź**

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

---

## Śledź odświeżanie witryny

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

Informacja o postępie odświeżania witryny, dzięki której możesz wyświetlić postęp, np. „221 z 249”.

**Parametry zapytania**

| Parametr | Wymagane | Opis |
|---|---|---|
| `baseUrl` | Tak | Dowolny adres w witrynie lub tylko host. |

**cURL**

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

**Odpowiedź**

```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` wynosi `null`, gdy dla danej witryny nie jest uruchomione żadne odświeżanie. Liczba ukończonych stron to `total` minus `pending`. Zadanie `status` jest jednym z `refreshing` (trwa przetwarzanie stron), `deduplicating` (końcowe czyszczenie) lub finalnym `completed`, `failed` i `cancelled`. Zachowaj `domainBatchId` — to identyfikator, który przekazujesz do punktu końcowego anulowania.

Brakujący lub pusty `baseUrl` zwraca `400`.

---

## Zatrzymaj odświeżanie witryny

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

Zatrzymuje odświeżanie witryny, które wciąż przetwarza swoje strony. Strony, które zostały już ukończone, zachowują zaktualizowaną zawartość; strony, których przetwarzanie nie zostało rozpoczęte, są pomijane, a strony, które były w trakcie ponownego odczytu, wracają do swojego poprzedniego stanu.

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `jobId` | Tak | `domainBatchId` zwrócony przez [Śledzenie odświeżania witryny](#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" }'
```

**Odpowiedź**

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

| Pole | Typ | Opis |
|---|---|---|
| `status` | string | Stan odświeżania po tym wywołaniu: `cancelled`, `deduplicating`, `completed` lub `failed`. |
| `cancelled_units` | integer | Ilość pracy, która pozostała do wykonania w momencie anulowania. `0` w przypadku ponownego anulowania. |
| `sources_reset` | integer | Strony wycofane z przetwarzania i przywrócone do `ready`. |
| `sources_cancelled` | integer | Całkowicie nowe strony tego odświeżania, które były w kolejce i zostały teraz anulowane. |

Dwukrotne anulowanie jest nieszkodliwe — drugie wywołanie zgłasza ten sam stan końcowy. Gdy odświeżanie przejdzie do etapu czyszczenia, nie można go już zatrzymać, a odpowiedź powraca z `success: false` i `reason: "already_finalizing"`. Brakujący `jobId` zwraca `400`, a zadanie, którego nie ma na Twoim koncie, zwraca `404`.

---

## Odśwież pojedyncze źródło

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

Ponownie odczytuje jedną stronę internetową, która została już zaimportowana, i dostosowuje zawarte na niej FAQ do bieżącej zawartości strony: zmienione sekcje są aktualizowane, nowe dodawane, a usunięte usuwane.

**cURL**

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

**Odpowiedź** — `202 Accepted`

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

Odpytuj źródło, aż jego status przestanie być `queued` i `processing`. Identyfikator źródła, którego nie ma na Twoim koncie, zwraca `404`.

---

## Wybierz najbardziej odpowiednie strony

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

Prosi AI o wybranie pięciu stron z listy kandydatów, które najlepiej opisują firmę — używane podczas generowania scenariusza kampanii na podstawie witryny internetowej. Ta operacja zużywa kredyty.

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `urls` | Tak | Adresy stron kandydujących do wyboru, zazwyczaj z wykrywania stron. |
| `homeUrl` | Tak | Strona główna witryny, używana jako kontekst dla wyboru. |

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

**Odpowiedź**

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

Jest to pomocnik, a nie zasób: w przypadku niepowodzenia nadal odpowiada `200`, z `success: false`, pustą listą `pages` oraz komunikatem `error`.

---

## Grupy wiedzy

**Grupa wiedzy** to nazwany zestaw FAQ — „Wysyłka i zwroty”, „Wdrożenie” — który można zastosować do agenta lub kampanii za pomocą jednego wywołania. Grupa przechowuje odwołania, a nie kopie: same FAQ pozostają w Twojej pojedynczej bibliotece, więc edycja jednego z nich za pomocą [API FAQ](faqs.md) aktualizuje je wszędzie, gdzie jest używane.

Zastosowanie grupy zawsze tylko **dodaje** to, czego brakuje, więc dwukrotne zastosowanie tej samej grupy jest nieszkodliwe, a `added_count` za drugim razem zwraca `0`.

---

## Tworzenie grupy wiedzy

`POST /kb-groups`

Tworzy grupę. Na początku jest ona pusta — dodaj do niej FAQ za pomocą [Dodaj FAQ do grupy](#add-a-faq-to-a-group).

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `name` | Tak | Nazwa grupy. |

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

**Odpowiedź** — `201 Created`

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

---

## Zmiana nazwy grupy wiedzy

`PUT /kb-groups/{groupId}`

Zmienia nazwę grupy. Zawarte w niej FAQ pozostają nienaruszone.

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `name` | Tak | Nowa nazwa grupy. |

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

**Odpowiedź**

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

---

## Usuwanie grupy wiedzy

`DELETE /kb-groups/{groupId}`

Usuwa grupę. Usuwany jest tylko zestaw — zawarte w nim FAQ pozostają w Twojej bibliotece, a wszystko, do czego grupa była już zastosowana, zachowuje te FAQ.

**cURL**

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

**Odpowiedź**

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

---

## Dodaj FAQ do grupy

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

Umieszcza istniejące FAQ w grupie. Zmienia to tylko pakiet — samo w sobie nie przypisuje FAQ do żadnego Agenta; w tym celu należy zastosować grupę.

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `faq_id` | Tak | ID FAQ do dodania. |

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

**Odpowiedź**

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

---

## Usuń FAQ z grupy

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

Usuwa FAQ z grupy. Samo FAQ nie jest usuwane, a Agenci, do których grupa została już zastosowana, zachowują je.

**cURL**

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

**Odpowiedź**

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

---

## Zastosuj grupę do Agenta

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

Dodaje każde FAQ z grupy do wiedzy Agenta AI w jednym wywołaniu — to szybki sposób na przekazanie nowemu Agentowi bazy wiedzy, którą już przygotowałeś.

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `agent_id` | Tak | ID Agenta AI, do którego ma zostać zastosowana grupa. |

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

**Odpowiedź**

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

`added_count` to liczba faktycznie dodanych FAQ — `0`, gdy grupa jest pusta lub już została zastosowana.

---

## Zastosuj grupę do kampanii

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

Wersja powyższego wywołania dla klasycznych kampanii. Na koncie opartym na Agentach użyj zamiast tego [Zastosuj grupę do Agenta](#apply-a-group-to-an-agent).

**Pola żądania**

| Pole | Wymagane | Opis |
|---|---|---|
| `campaign_id` | Tak | Identyfikator kampanii, do której ma zostać przypisana grupa. |

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

**Odpowiedź**

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

---

## Błędy API bazy wiedzy

Te punkty końcowe zwracają standardową kopertę błędu:

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

| Status | Kiedy występuje w punkcie końcowym bazy wiedzy |
|---|---|
| `400` | Brakuje wymaganego pola lub jest ono nieprawidłowe — puste `url`, brak `baseUrl` lub `jobId`, więcej niż 100 adresów URL w imporcie zbiorczym, więcej niż 2000 identyfikatorów w usuwaniu zbiorczym lub nieobsługiwany typ pliku. |
| `402` | Niewystarczająca liczba kredytów do przeprowadzenia importu. Doładuj konto i spróbuj ponownie. |
| `403` | `storage_path` poza własnym folderem przesyłania — lub Twój plan nie obejmuje dostępu do API. |
| `404` | Nie znaleziono źródła, grupy, FAQ, agenta, kampanii lub zadania odświeżania — albo nie istnieje, albo należy do innego konta. |

> **Błędy miękkie nie są błędami.** Odkrywanie (`discover-pages`, `refresh-domain`) oraz pomocnik wyboru stron odpowiadają `200` za pomocą `success: false` i komunikatu `error`, gdy witryna nie może zostać odczytana, zamiast przerywać żądanie. Zawsze sprawdzaj `success` przed odczytaniem danych.

Wspólne kody, które może zwrócić każdy punkt końcowy — `401`, `403` (Twój plan nie obejmuje dostępu do API), `429` (limit szybkości) oraz `500` — zostały wymienione wraz ze wskazówkami dotyczącymi ponawiania prób w sekcji [Błędy i stronicowanie](errors-and-pagination.md).

---

## Powiązane

- [API FAQ](faqs.md) — odczytuj, edytuj i łącz FAQ tworzone przez Twoje źródła.
- [Zarządzanie FAQ](../ai-automation/faq-management.md) — ta sama baza wiedzy w panelu nawigacyjnym.
- [Agenci AI](../ai-agents/ai-agents.md) — agenci, do których przypisujesz źródła i grupy.
- [Dostęp do API](../integrations/api-access.md) — wygeneruj swój klucz API.
- [Uwierzytelnianie](authentication.md) — wszystkie sposoby przekazywania klucza.
