
# ナレッジベース API

ナレッジベースは、AIが読み取る情報源です。ナレッジベースには2つの要素があり、このページではその両方について説明します。

- **ナレッジソース** (`/kb-sources`) — プラットフォームに読み込ませるWebページやアップロードされたドキュメントです。それぞれが読み取られ、セクションに分割され、AIが回答するためのFAQに変換されます。
- **ナレッジグループ** (`/kb-groups`) — FAQをまとめた名前付きのバンドルです。エージェントやキャンペーンに一度の呼び出しで適用できるため、すでにキュレーション済みのナレッジを、次に作成するエージェントで再利用できます。

ソースから生成されたFAQは、手動で作成したFAQと同じライブラリに保存されます。そのため、インポートが完了したら、[FAQs API](faqs.md)を使用してそれらを読み取り、編集し、リンクさせることができます。

以下のすべてのエンドポイントは、ベースURL `https://api.youraiconnector.com/v1` に対する相対パスです。すべてのリクエストには認証が必要です。[APIアクセス](../integrations/api-access.md)および[認証](authentication.md)を参照してください。APIアクセスは有料機能です。有効でない場合、リクエストは `403` で拒否されます。


> **インポートにはクレジットが必要です。** ページやドキュメントを読み取ってFAQを作成すると、コンテンツの量に比例してクレジットが消費されます。大規模なクロールを実行する前に、[インポートの見積もり](#estimate-what-an-import-will-cost)を行ってください。

---

## インポートの仕組み

インポートはバックグラウンドジョブとして実行され、即座に完了するものではありません。すべてのインポートエンドポイントは即座に `source_id` を返します。完了するまでそのソースをポーリングしてください。

1. **インポートを開始する** — `POST /kb-sources/url`（1ページ）、`POST /kb-sources/file`（アップロードされたドキュメント）、または `POST /kb-sources/bulk-import`（最大100ページ）を使用します。ソースIDと `status: "queued"` が返されます。
2. **ポーリング** — `status` が `queued` または `processing` ではなくなるまで `GET /kb-sources/{sourceId}` を実行します。
3. **FAQを読み取る** — ステータスが `ready` になると、生成されたエントリがFAQライブラリ（`GET /faqs`）に保存されます。

すべてのソースは、以下のいずれかのステータスを報告します。

| ステータス | 意味 |
|---|---|
| `queued` | 読み取り待ち。まだ課金は発生していません。 |
| `processing` | 現在読み取り中で、FAQに変換中です。 |
| `ready` | 完了。FAQがライブラリに追加されました。 |
| `failed` | インポートできませんでした。`error_message` に理由が記載されています。 |
| `cancelled` | 読み取り前に停止されました（[インポートの停止](#stop-an-import)を参照）。 |
| `paused` | インポート中にAIキーの認証に失敗したため停止されました（[一時停止したインポートの再開](#resume-a-paused-import)を参照）。 |
| `deleting` | 一括削除処理が進行中です。 |
| `unknown` | レコードにステータスがありません。準備ができていないものとして扱ってください。 |

> **インポートと同時にアタッチする。** 任意のインポートエンドポイントで `autoLinkToAgentId` を渡すと、ソースとそこから生成されるすべてのFAQが、追加のリンク手順なしでそのエージェントのナレッジに直接追加されます。`autoLinkToCampaignId` を使用すると、従来のキャンペーンに対しても同様の操作が可能です。リンクはベストエフォートで行われます。存在しないIDや別のアカウントに属するIDは警告なしにスキップされ、インポート自体は実行されます。そのため、エージェントを読み戻してリンクが正しく行われたかを確認してください。

---

## Webページをインポートする

`POST /kb-sources/url`

Webページを1つ、ナレッジベースに追加します。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `url` | はい | ページの完全な `http` または `https` アドレス。 |
| `autoLinkToAgentId` | いいえ | インポートしたソースを紐付けるAIエージェントのID。 |
| `autoLinkToCampaignId` | いいえ | レガシー。インポートしたソースを紐付けるキャンペーンのID。 |

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

**応答** — `202 Accepted`

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

ステータスが `ready` または `failed` になるまで、[ソースの確認](#check-a-source) で `source_id` をポーリングします。

同じページがすでにナレッジベースに存在する場合、新しいキューは作成されず、代わりに `200` が返されます。自動リンクを要求していた場合は、既存のソースが自動的にリンクされます。

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

`url` が欠落している場合、または有効な `http`/`https` アドレスではない場合、`400` が返されます。

---

## アップロード済みドキュメントのインポート

`POST /kb-sources/file`

**アカウントのファイルストレージにすでに存在する**ドキュメントをナレッジソースとして追加します。サポートされている形式: PDF、DOCX、TXT、MD、CSV、XLSX。

> **このエンドポイントはファイルを直接送信しません。** マルチパートアップロード、base64ボディ、URLからのダウンロード機能はありません。すでに存在するファイルの保存場所を指定する必要があります。そのファイルは自身のアップロードフォルダ内に存在しなければなりません（`storage_path` は `users/{your user id}/uploads/` で始まる必要があります）。そうでない場合、リクエストは `403` で拒否されます。ダッシュボードにファイルをドラッグ＆ドロップすると、ファイルはそこに配置されます。ファイルをそこに配置できない場合は、代わりに [Webページのインポート](#import-a-web-page) を使用してください。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `storage_path` | はい | アップロードされたファイルの場所。`users/{your user id}/uploads/` で始まる必要があります。 |
| `filename` | はい | 拡張子を含む元のファイル名。これによりファイルタイプが検出されます。 |
| `mime_type` | はい | ファイルのMIMEタイプ（例: `application/pdf`）。 |
| `autoLinkToAgentId` | いいえ | ドキュメントを紐付けるAIエージェントのID。 |
| `autoLinkToCampaignId` | いいえ | レガシー。ドキュメントを紐付けるキャンペーンのID。 |

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

**応答** — `202 Accepted`

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

| ステータス | 内容 |
|---|---|
| `400` | 必須フィールドが欠落しているか、読み取り不可能なファイルタイプです。 |
| `403` | `storage_path` が自身のアップロードフォルダの外側にあります。 |

---

## ソースの確認

`GET /kb-sources/{sourceId}`

すべてのインポートおよび更新の後に続くポーリングです。ステータスが `ready` または `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()
```

**レスポンス**

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

| フィールド | 型 | 説明 |
|---|---|---|
| `status` | string | パイプライン内でのソースの位置（[ステータステーブル](#how-an-import-works)を参照）。 |
| `faq_count` | integer | このソースからこれまでに生成されたFAQの数。 |
| `section_count` | integer | ソースが分割されたコンテンツセクションの数。 |
| `error_message` | string \| null | ステータスが `failed` の場合にインポートが失敗した理由。それ以外の場合は `null`。 |

---

## ソースの削除

`DELETE /kb-sources/{sourceId}`

知識ソースを1つ削除します。**デフォルトでは、そのソースから生成されたFAQは保持されます**。それらも削除するには `delete_faqs=true` を追加してください。

**クエリパラメータ**

| パラメータ | 必須 | 説明 |
|---|---|---|
| `delete_faqs` | いいえ | このソースから生成されたすべてのFAQも削除するには `true` に設定します。デフォルトは `false` です。 |

**cURL**

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

**レスポンス**

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

`delete_faqs=true` を要求しない限り、`faqs_deleted` は `0` になります。

---

## 複数のページを一度にインポートする

`POST /kb-sources/bulk-import`

1回の呼び出しで最大100件のWebページを追加します。これは通常、[Webサイト上のページを検出](#discover-pages-on-a-website)または[Webサイト上の新しいページを検索](#find-new-pages-on-a-website)の後のステップとして行われます。すでにナレッジベースにあるページは重複して追加されることはなくスキップされます（要求した場合は、引き続きエージェントにリンクされます）。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `urls` | はい | インポートするアドレス。1回の呼び出しにつき最低1件、最大100件まで。 |
| `autoLinkToAgentId` | いいえ | インポートしたすべてのページを関連付けるAIエージェントのID。 |
| `autoLinkToCampaignId` | いいえ | レガシー。インポートしたすべてのページを関連付けるキャンペーンのID。 |

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

**応答** — `202 Accepted`

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

`queued_source_ids` 内の各IDを[ソースの確認](#check-a-source)でポーリングします。空の `urls` 配列、文字列以外のエントリ、または100件を超えるエントリを送信すると `400` が返されます。

---

## 複数のソースを一度に削除する

`POST /kb-sources/bulk-delete`

1回の呼び出しで最大2,000件の知識ソースを削除します。削除はバックグラウンドで実行され、完了するとメールで通知されます。

> **一括削除ではFAQも常に削除されます。** [ソースの削除](#delete-a-source)とは異なり（指定しない限りFAQは保持されます）、このエンドポイントは各ソースを、それによって生成されたFAQとともに削除します。FAQを保持するオプションはありません。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `sourceIds` | はい | 削除するソースのID。1回の呼び出しにつき最低1つ、最大2,000まで。 |
| `domainLabel` | いいえ | このクリーンアップのわかりやすい名前。完了メールでのみ使用されます。 |

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

**応答** — `202 Accepted`

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

---

## ウェブサイト上のページを検出する

`POST /kb-sources/discover-pages`

1つの開始アドレスからウェブサイトを探索し、同じドメイン内で見つかったページをリストアップします。各ページについて、インポートする価値があるかどうかの評価も行います。**何もインポートされず、自動的に選択されることもありません**。これは、[一度に多数のページをインポートする](#import-many-pages-at-once)際に何を送信するかを決定する前に行う「サイト上に何があるか」を確認するためのステップです。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `url` | はい | 探索を開始するアドレス（通常はサイトのホームページ）。 |
| `maxPages` | いいえ | 返されるページ数の上限。 |

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

**レスポンス**

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

| フィールド | 型 | 説明 |
|---|---|---|
| `source_type` | string | ページの検出方法 — `sitemap`（サイト自身のサイトマップ）または `link_discovery`（リンクを辿る）。 |
| `url` | string | ページの完全なアドレス。 |
| `title` | string \| null | 読み取り可能な場合のページタイトル。 |
| `depth` | integer | 開始ページから何リンク先でそのページが見つかったか。 |
| `score` | integer | 知識としてどの程度有用か（`0`から`100`まで）。 |
| `recommendation` | string | `add`（インポートする価値が十分にある、スコア90以上）、`maybe`（境界線）、または `skip`（変更履歴、法的ページ、重複した翻訳など、アシスタントの役に立つことがほとんどないコンテンツ）。 |
| `reason_key` | string | 推奨の背後にある、機械可読な安定した理由（例: `core_page`、`changelog_history`、`legal_page`、`locale_duplicate`）。 |

> **探索はベストエフォートで行われます。** サイトが読み取れない場合でもレスポンスは `200` となり、`success: false`、空の `pages` リスト、および `error` メッセージが返されます。`pages` を読み取る前に `success` を確認してください。

`url` が欠落していると `400` が返されます。

---

## インポートにかかるコストを見積もる

`POST /kb-sources/estimate-cost`

インポートを実行する前に、提案されたインポートで何クレジット消費するかを算出します。ページがフェッチされ、ドキュメントが読み取られてサイズが測定されますが、何もインポートされず、見積もり自体でクレジットが消費されることはありません。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `urls` | いいえ | インポートを検討しているページのアドレス。 |
| `files` | いいえ | 検討中のアップロード済みファイル。各エントリには `storage_path`、`filename`、`mime_type` が必要です。 |
| `tier` | いいえ | インポートを実行するAI品質ティア。これにより、実際に請求される金額と一致する見積もりが得られます。標準レートの場合は省略してください。 |

`urls`、`files`、またはその両方を送信してください。

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

**レスポンス**

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

各行は `ref` 内のURLまたはストレージパスをエコーバックするため、入力と照合できます。読み取れなかったページやファイルも1つのチャンクとしてカウントされ、行が作成され、`error` が付与されます。

---

## インポートを停止する

`POST /kb-sources/cancel-import`

インポートキューで待機中のページを停止します。予想以上に大規模になったクロールの「インポートを停止」ボタンです。待機中のページのキャンセルには費用はかかりません。まだ読み取られていないためです。

すでに処理中のページは停止**されません**。処理が進行中であり、いずれにせよ課金されるため、そのまま完了します。レスポンスには、それらがいくつあったかが報告されます。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `host` | いいえ | このウェブサイト上の待機中のページのみを停止します（例: `docs.example.com`）。指定しない場合、アカウント内のすべての待機中のインポートが停止されます。 |

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

**レスポンス**

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

---

## 一時停止したインポートを再開する

`POST /kb-sources/resume-import`

お客様自身のAIキーが機能しなくなったために一時停止されたインポートを再開します。

> これを呼び出すことは、現在有効なキーでインポートを完了することへの同意**となります**。お客様自身のキーがまだダウンしている場合は、プラットフォームのクレジットを消費する可能性があることに注意してください。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `host` | いいえ | このウェブサイト上で一時停止されたページのみを再開します。指定しない場合、一時停止中のすべてが再開されます。 |

**cURL**

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

**レスポンス**

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

---

## ウェブサイト上の新しいページを見つける

`POST /kb-sources/refresh-domain`

すでにインポート済みのウェブサイトを探索し、まだナレッジベースに含まれていないページのみを報告します。各ページにはページ探索と同じ推奨事項が示されます。何もインポートされず、何も変更されません。

2つのフォローアップは意図的に別々の呼び出しとなっているため、この呼び出しを中断しても費用はかかりません。

- [一度に複数のページをインポート](#import-many-pages-at-once)して、新しいページを取り込みます。
- [ウェブサイトの全ページを更新](#refresh-every-page-on-a-website)して、既存のページを再読み込みします。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `baseUrl` | はい | ウェブサイト上の任意のアドレス、またはホスト名のみ。 |
| `maxPages` | いいえ | 探索するページ数の上限。 |

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

**レスポンス**

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

| フィールド | 型 | 説明 |
|---|---|---|
| `discovered` | 整数 | サイト内で合計で見つかったページ数。 |
| `new_pages` | 配列 | まだナレッジベースに含まれていないページ。自動的にキューには入りません。必要なものをインポートしてください。 |
| `new_urls_queued` | 整数 | 常に `0`。後方互換性のために保持されています。このエンドポイントは何もキューに入れません。 |
| `existing_refresh_queued` | 整数 | このサイトから既にインポート済みで、再読み込みの準備ができているページ数。この呼び出しによってキューに入るものはありません。 |
| `batch_id` | 文字列 | バッチが作成された場合にのみ存在します。 |

ディスカバリーと同様に、これもソフトに失敗します。読み取れないサイトでも `200` を返し、`success: false`、空の `new_pages`、および `error` が含まれます。`baseUrl` が欠落しているか空の場合は、`400` を返します。

---

## ウェブサイトの全ページを更新

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

ウェブサイトから既にインポートしたすべてのページを再読み込みし、FAQがサイトの現在のコンテンツに追従するようにします。変更されたセクションは更新され、新しいセクションは追加され、削除されたセクションは破棄されます。

これは処理をキューに入れ、即座に値を返します。その後に [ウェブサイトの更新を追跡](#track-a-website-refresh) を実行し、[ウェブサイトの更新を停止](#stop-a-website-refresh) で停止します。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `baseUrl` | はい | ウェブサイト上の任意のアドレス、またはホスト名のみ。 |

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

**レスポンス**

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

---

## ウェブサイトの更新を追跡

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

ウェブサイトの更新がどの程度進んでいるかを示し、「249ページ中221ページ完了」のような進捗を表示できるようにします。

**クエリパラメータ**

| パラメータ | 必須 | 説明 |
|---|---|---|
| `baseUrl` | はい | ウェブサイト上の任意のアドレス、またはホスト名のみ。 |

**cURL**

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

**レスポンス**

```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` は `null` になります。これまでに完了したページ数は `total` から `pending` を引いたものです。ジョブの `status` は、`refreshing`（ページ処理中）、`deduplicating`（終了時のクリーンアップパス）、または最終的な `completed`、`failed`、`cancelled` のいずれかです。`domainBatchId` は保持しておいてください。これはキャンセルエンドポイントに渡す値です。

`baseUrl` が欠落しているか空の場合は、`400` を返します。

---

## ウェブサイトの更新を停止する

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

まだページ処理中のウェブサイトの更新を停止します。完了済みのページは更新されたコンテンツを保持しますが、未開始のページは破棄され、再読み込み中だったページは以前の状態に戻ります。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `jobId` | はい | [ウェブサイトの更新を追跡](#track-a-website-refresh)によって返される `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" }'
```

**レスポンス**

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

| フィールド | 型 | 説明 |
|---|---|---|
| `status` | string | この呼び出し後の更新の状態: `cancelled`、`deduplicating`、`completed`、または `failed`。 |
| `cancelled_units` | integer | キャンセルが実行された時点で残っていた作業量。繰り返しキャンセルした場合は `0` となります。 |
| `sources_reset` | integer | 処理から取り除かれ、`ready` に戻されたページ数。 |
| `sources_cancelled` | integer | この更新で新規に追加され、キューに入っていたもののキャンセルされたページ数。 |

2回キャンセルしても問題はありません。2回目の呼び出しでも同じ最終状態が報告されます。更新がクリーンアップフェーズに移行すると停止できなくなり、応答には `success: false` と `reason: "already_finalizing"` が含まれます。`jobId` が欠落している場合は `400` が返され、アカウント内に存在しないジョブを指定した場合は `404` が返されます。

---

## 単一ソースを更新する

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

すでにインポート済みのウェブページを再読み込みし、FAQをそのページの現在のコンテンツと同期させます。変更されたセクションは更新され、新しいセクションは追加され、削除されたセクションは破棄されます。

**cURL**

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

**応答** — `202 Accepted`

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

ステータスが `queued` および `processing` ではなくなるまでソースをポーリングします。アカウント内に存在しないソースIDを指定した場合は `404` が返されます。

---

## 最も関連性の高いページを選択する

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

AIに、候補リストの中からビジネスを最もよく説明している5つのページを選択させます。これはウェブサイトからキャンペーンのプレイブックを生成する際に使用されます。これにはクレジットを消費します。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `urls` | はい | 選択対象となる候補ページのURL。通常はページ検出から取得します。 |
| `homeUrl` | はい | 選択のコンテキストとして使用されるサイトのホームページ。 |

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

**レスポンス**

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

これはリソースではなくヘルパーです。失敗した場合でも `200` を返し、`success: false`、空の `pages` リスト、および `error` メッセージが含まれます。

---

## ナレッジグループ

**ナレッジグループ**とは、「配送と返品」、「オンボーディング」といったFAQの名前付きバンドルであり、1回の呼び出しでエージェントやキャンペーンに適用できます。グループはコピーではなく参照を保持します。FAQ自体は単一のライブラリ内に留まるため、[FAQs API](faqs.md) を使用してFAQを編集すると、それが使用されているすべての場所で更新が反映されます。

グループの適用は不足しているものを**追加**するだけであるため、同じグループを2回適用しても問題はなく、2回目には `added_count` が `0` として返されます。

---

## ナレッジグループを作成する

`POST /kb-groups`

グループを作成します。最初は空の状態です。[グループにFAQを追加](#add-a-faq-to-a-group) を使用してFAQを追加してください。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `name` | はい | グループの名前。 |

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

**レスポンス** — `201 Created`

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

---

## ナレッジグループの名前を変更する

`PUT /kb-groups/{groupId}`

グループの名前を変更します。グループ内のFAQには影響しません。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `name` | はい | グループの新しい名前。 |

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

**レスポンス**

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

---

## ナレッジグループを削除する

`DELETE /kb-groups/{groupId}`

グループを削除します。削除されるのはバンドルのみであり、グループ内のFAQはライブラリに残ります。また、すでにグループが適用されていたものについては、そのFAQが保持されます。

**cURL**

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

**レスポンス**

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

---

## FAQをグループに追加する

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

既存のFAQをグループに追加します。これはバンドルを変更するだけで、FAQ自体をエージェントに紐付けるわけではありません。エージェントへの紐付けにはグループの適用を行ってください。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `faq_id` | はい | 追加するFAQの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" }'
```

**レスポンス**

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

---

## FAQをグループから削除する

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

FAQをグループから削除します。FAQ自体は削除されず、グループが既に適用されているエージェントは引き続きそのFAQを保持します。

**cURL**

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

**レスポンス**

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

---

## エージェントにグループを適用する

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

グループ内のすべてのFAQを1回の呼び出しでAIエージェントの知識に追加します。既にキュレーション済みの知識ベースを新しいエージェントに素早く付与する方法です。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `agent_id` | はい | グループを適用するAIエージェントのID。 |

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

**レスポンス**

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

`added_count` は実際に何件のFAQが追加されたかを示します。グループが空の場合や既に適用済みの場合、値は `0` になります。

---

## キャンペーンにグループを適用する

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

上記呼び出しのクラシックキャンペーン版です。エージェントベースのアカウントでは、代わりに[エージェントにグループを適用する](#apply-a-group-to-an-agent)を使用してください。

**リクエストフィールド**

| フィールド | 必須 | 説明 |
|---|---|---|
| `campaign_id` | はい | グループを適用するキャンペーンのID。 |

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

**レスポンス**

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

---

## ナレッジベースAPIエラー

これらのエンドポイントは、標準のエラーエンベロープを返します：

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

| ステータス | ナレッジベースエンドポイントで発生する場合 |
|---|---|
| `400` | 必須フィールドが欠落しているか無効です。空の `url`、欠落している `baseUrl` または `jobId`、一括インポートで100件を超えるURL、一括削除で2,000件を超えるID、または読み取り不可能なファイルタイプなどが該当します。 |
| `402` | インポートを実行するためのクレジットが不足しています。チャージしてから再度お試しください。 |
| `403` | 自身のアップロードフォルダー外の `storage_path`、またはプランにAPIアクセスが含まれていません。 |
| `404` | ソース、グループ、FAQ、エージェント、キャンペーン、または更新ジョブが見つかりませんでした。存在しないか、別のアカウントに属しています。 |

> **ソフトフェイルはエラーではありません。** ディスカバリー（`discover-pages`、`refresh-domain`）およびページ選択ヘルパーは、Webサイトを読み取れない場合、リクエストを失敗させるのではなく、`200` と `success: false`、および `error` メッセージを返します。データを読み取る前に、必ず `success` を確認してください。

すべてのエンドポイントが返す共通コード（`401`、`403`（プランにAPIアクセスが含まれていない）、`429`（レート制限）、`500`）については、再試行のガイダンスと共に[エラーとページネーション](errors-and-pagination.md)に記載されています。

---

## 関連情報

- [FAQs API](faqs.md) — ソースが生成するFAQの読み取り、編集、リンクを行います。
- [FAQの管理](../ai-automation/faq-management.md) — ダッシュボード上の同じナレッジベースです。
- [AIエージェント](../ai-agents/ai-agents.md) — ソースやグループを紐付けるエージェントです。
- [APIアクセス](../integrations/api-access.md) — APIキーを生成します。
- [認証](authentication.md) — キーを渡すためのすべての方法です。
