
# واجهة برمجة تطبيقات قاعدة المعرفة

قاعدة معرفتك هي ما يقرأ منه الذكاء الاصطناعي. وهي تتكون من جزأين، وتغطي هذه الصفحة كلاً منهما:

- **مصادر المعرفة** (`/kb-sources`) — صفحات الويب والمستندات التي تقوم برفعها إلى المنصة. يتم قراءة كل منها، وتقسيمها إلى أقسام، وتحويلها إلى أسئلة شائعة يمكن للذكاء الاصطناعي الخاص بك الإجابة عليها.
- **مجموعات المعرفة** (`/kb-groups`) — حزم مسماة من الأسئلة الشائعة التي يمكنك تطبيقها على وكيل أو حملة في استدعاء واحد، بحيث يمكن إعادة استخدام مجموعة المعرفة التي قمت بتنظيمها بالفعل على الوكيل التالي الذي تنشئه.

تستقر الأسئلة الشائعة التي ينتجها المصدر في نفس المكتبة التي توجد بها الأسئلة التي تكتبها يدويًا، لذا بمجرد انتهاء الاستيراد، يمكنك قراءتها وتعديلها وربطها باستخدام [واجهة برمجة تطبيقات الأسئلة الشائعة](faqs.md).

جميع نقاط النهاية أدناه نسبية إلى عنوان URL الأساسي `https://api.youraiconnector.com/v1`. يجب أن تكون كل طلبية مصادقاً عليها — راجع [الوصول إلى واجهة برمجة التطبيقات](../integrations/api-access.md) و[المصادقة](authentication.md). الوصول إلى واجهة برمجة التطبيقات هو ميزة مدفوعة؛ وبدونها، يتم رفض الطلبات مع `403`.


> **الاستيراد يستهلك رصيداً.** قراءة صفحة أو مستند وكتابة أسئلة شائعة منه يستهلك رصيداً، يتناسب تقريباً مع حجم المحتوى الموجود. استخدم [تقدير تكلفة الاستيراد](#estimate-what-an-import-will-cost) قبل البدء في عملية زحف كبيرة.

---

## كيف يعمل الاستيراد

الاستيراد هو مهمة في الخلفية، وليس شيئاً ينتهي أثناء انتظارك. تجيب كل نقطة نهاية للاستيراد فوراً بـ `source_id`، وتقوم أنت بالاستعلام عن ذلك المصدر حتى ينتهي:

1. **بدء الاستيراد** — `POST /kb-sources/url` (صفحة واحدة)، أو `POST /kb-sources/file` (مستند مرفوع)، أو `POST /kb-sources/bulk-import` (ما يصل إلى 100 صفحة). ستحصل على معرف المصدر و `status: "queued"`.
2. **الاستعلام** — `GET /kb-sources/{sourceId}` حتى لا تعود `status` تساوي `queued` أو `processing`.
3. **قراءة الأسئلة الشائعة** — عندما تكون الحالة `ready`، تكون الإدخالات التي أنتجها المصدر موجودة في مكتبة الأسئلة الشائعة الخاصة بك: `GET /faqs`.

يقدم كل مصدر إحدى هذه الحالات:

| الحالة | ماذا تعني |
|---|---|
| `queued` | في انتظار القراءة. لم يتم خصم أي رصيد بعد. |
| `processing` | يتم قراءتها وتحويلها إلى أسئلة شائعة الآن. |
| `ready` | انتهت. الأسئلة الشائعة موجودة في مكتبتك. |
| `failed` | تعذر الاستيراد. يوضح `error_message` السبب. |
| `cancelled` | تم إيقافها قبل قراءتها (راجع [إيقاف استيراد](#stop-an-import)). |
| `paused` | تم إيقافها لأن مفتاح الذكاء الاصطناعي الخاص بك فشل في منتصف الاستيراد (راجع [استئناف استيراد متوقف](#resume-a-paused-import)). |
| `deleting` | عملية حذف جماعي تعمل عليها حالياً. |
| `unknown` | السجل لا يحمل أي حالة. تعامل معه على أنه غير جاهز. |

> **الإلحاق أثناء الاستيراد.** مرر `autoLinkToAgentId` في أي نقطة نهاية للاستيراد وسينضم المصدر — بالإضافة إلى كل سؤال شائع ينتجه — إلى معرفة ذلك الوكيل في نفس الاستدعاء، دون الحاجة إلى خطوة ربط لاحقة. يقوم `autoLinkToCampaignId` بنفس الشيء لحملة كلاسيكية. الربط هو محاولة بأفضل جهد: المعرف الذي لا وجود له، أو الذي ينتمي لحساب آخر، يتم تخطيه بصمت ويستمر الاستيراد في العمل، لذا تأكد من الربط عن طريق قراءة بيانات الوكيل مرة أخرى.

---

## استيراد صفحة ويب

`POST /kb-sources/url`

يضيف صفحة ويب واحدة إلى قاعدة معرفتك.

**حقول الطلب**

| الحقل | مطلوب | الوصف |
|---|---|---|
| `url` | نعم | عنوان `http` أو `https` الكامل للصفحة. |
| `autoLinkToAgentId` | لا | مُعرّف وكيل ذكاء اصطناعي (AI Agent) لإرفاق المصدر المستورد به. |
| `autoLinkToCampaignId` | لا | قديم. مُعرّف حملة لإرفاق المصدر المستورد بها. |

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

قم باستطلاع `source_id` باستخدام [التحقق من مصدر](#check-a-source) حتى تصبح الحالة `ready` أو `failed`.

إذا كانت الصفحة نفسها موجودة بالفعل في قاعدة معرفتك، فلن يتم وضع أي شيء جديد في قائمة الانتظار وستحصل على `200` بدلاً من ذلك — وإذا طلبت رابطاً تلقائياً، فسيتم ربط المصدر الموجود لك على أي حال:

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

يؤدي فقدان `url`، أو إذا كان العنوان ليس عنوان `http`/`https` صالحاً، إلى إرجاع `400`.

---

## استيراد مستند مرفوع

`POST /kb-sources/file`

يضيف مستنداً **موجوداً بالفعل في مساحة تخزين ملفات حسابك** كمصدر معرفة. الأنواع المدعومة: PDF و DOCX و TXT و MD و CSV و XLSX.

> **لا يحمل هذا الطرف (endpoint) الملف.** لا يوجد رفع متعدد الأجزاء (multipart)، ولا جسم base64، ولا تنزيل من رابط URL: أنت ترسل موقع تخزين ملف موجود بالفعل، ويجب أن يكون موجوداً ضمن مجلد الرفع الخاص بك (يجب أن يبدأ `storage_path` بـ `users/{your user id}/uploads/`) وإلا سيتم رفض الطلب بـ `403`. تضع لوحة التحكم الملفات هناك عند سحبها وإفلاتها. إذا لم تكن لديك طريقة لوضع ملف هناك، فقم باستيراد صفحة ويب باستخدام [استيراد صفحة ويب](#import-a-web-page) بدلاً من ذلك.

**حقول الطلب**

| الحقل | مطلوب | الوصف |
|---|---|---|
| `storage_path` | نعم | مكان وجود الملف المرفوع. يجب أن يبدأ بـ `users/{your user id}/uploads/`. |
| `filename` | نعم | اسم الملف الأصلي بما في ذلك امتداده — بهذه الطريقة يتم اكتشاف نوع الملف. |
| `mime_type` | نعم | نوع MIME الخاص بالملف، على سبيل المثال `application/pdf`. |
| `autoLinkToAgentId` | لا | مُعرّف وكيل ذكاء اصطناعي (AI Agent) لإرفاق المستند به. |
| `autoLinkToCampaignId` | لا | قديم. مُعرّف حملة لإرفاق المستند بها. |

**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 | عدد الأسئلة الشائعة التي تم إنشاؤها من هذا المصدر حتى الآن. |
| `section_count` | integer | عدد أقسام المحتوى التي تم تقسيم المصدر إليها. |
| `error_message` | string \| null | سبب فشل الاستيراد، عندما تكون الحالة `failed`. و`null` بخلاف ذلك. |

---

## حذف مصدر

`DELETE /kb-sources/{sourceId}`

يزيل مصدر معرفة واحداً. **افتراضياً، يتم الاحتفاظ بالأسئلة الشائعة التي أنتجها** — أضف `delete_faqs=true` لإزالتها أيضاً.

**معلمات الاستعلام**

| المعلمة | مطلوبة | الوصف |
|---|---|---|
| `delete_faqs` | لا | اضبطها على `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
}
```

`faqs_deleted` هي `0` ما لم تطلب `delete_faqs=true`.

---

## استيراد صفحات متعددة دفعة واحدة

`POST /kb-sources/bulk-import`

يضيف ما يصل إلى 100 صفحة ويب في طلب واحد — وهو الإجراء المعتاد المتبع بعد [اكتشاف الصفحات على موقع ويب](#discover-pages-on-a-website) أو [العثور على صفحات جديدة على موقع ويب](#find-new-pages-on-a-website). يتم تخطي الصفحات الموجودة بالفعل في قاعدة معرفتك بدلاً من تكرارها (ولا تزال مرتبطة بالوكيل عندما تطلب ذلك).

**حقول الطلب**

| الحقل | مطلوب | الوصف |
|---|---|---|
| `urls` | نعم | العناوين المراد استيرادها. على الأقل 1، وبحد أقصى 100 لكل طلب. |
| `autoLinkToAgentId` | لا | معرف وكيل الذكاء الاصطناعي لربط كل صفحة مستوردة به. |
| `autoLinkToCampaignId` | لا | قديم. معرف حملة لربط كل صفحة مستوردة بها. |

**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` باستخدام [التحقق من مصدر](#check-a-source). إرسال مصفوفة `urls` فارغة، أو إدخال ليس نصياً، أو أكثر من 100 إدخال يعيد `400`.

---

## حذف مصادر متعددة دفعة واحدة

`POST /kb-sources/bulk-delete`

يزيل ما يصل إلى 2000 مصدر معرفة في طلب واحد. تتم عملية الإزالة في الخلفية وستتلقى بريداً إلكترونياً عند انتهائها.

> **يؤدي الحذف المجمع دائمًا إلى إزالة الأسئلة الشائعة أيضًا.** على عكس [حذف مصدر](#delete-a-source)، الذي يحتفظ بها ما لم تطلب خلاف ذلك، يقوم نقطة النهاية هذه بحذف كل مصدر مع الأسئلة الشائعة التي أنتجها. لا يوجد خيار للاحتفاظ بها.

**حقول الطلب**

| الحقل | مطلوب | الوصف |
|---|---|---|
| `sourceIds` | نعم | معرفات المصادر المراد إزالتها. بحد أدنى 1، وبحد أقصى 2000 لكل طلب. |
| `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`

يستكشف موقع ويب بدءًا من عنوان واحد ويسرد الصفحات التي تم العثور عليها في نفس النطاق، مع تقديم رأي حول ما إذا كان الأمر يستحق الاستيراد. **لا يتم استيراد أي شيء ولا يتم تحديد أي شيء نيابة عنك** — هذه هي خطوة "ما الموجود في هذا الموقع" التي تقوم بتشغيلها قبل اتخاذ قرار بشأن ما يجب إرساله إلى [استيراد صفحات متعددة دفعة واحدة](#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`. تحقق من `success` قبل قراءة `pages`.

فقدان `url` يؤدي إلى إرجاع `400`.

---

## تقدير تكلفة الاستيراد

`POST /kb-sources/estimate-cost`

يحسب عدد الرصيد الذي سيستهلكه استيراد مقترح، قبل الالتزام به. يتم جلب الصفحات وقراءة المستندات لقياس حجمها، ولكن لا يتم استيراد أي شيء ولا يستهلك التقدير نفسه أي رصيد.

**حقول الطلب**

| الحقل | مطلوب | الوصف |
|---|---|---|
| `urls` | لا | عناوين الصفحات التي تفكر في استيرادها. |
| `files` | لا | الملفات التي تم تحميلها مسبقًا والتي تفكر فيها. يحتاج كل إدخال إلى `storage_path` و `filename` و `mime_type`. |
| `tier` | لا | مستوى جودة الذكاء الاصطناعي الذي سيتم تشغيل الاستيراد عليه، بحيث يتطابق التقدير مع ما سيتم محاسبتك عليه فعليًا. اتركه فارغًا للحصول على السعر القياسي. |

أرسل `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
}
```

يعكس كل صف عنوان URL أو مسار التخزين في `ref` حتى تتمكن من مطابقته مع مدخلاتك. الصفحة أو الملف الذي تعذر قراءته يحصل أيضاً على صف، ويُحتسب كجزء واحد، مع وجود `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`

يعيد تشغيل عملية استيراد تم إيقافها مؤقتاً لأن مفتاح الذكاء الاصطناعي الخاص بك توقف عن العمل.

> استدعاء هذا **يعتبر** موافقة منك على إنهاء عملية الاستيراد باستخدام أي مفتاح نشط حالياً — وهو ما قد يعني استهلاك أرصدة المنصة إذا كان مفتاحك الخاص لا يزال معطلاً.

**حقول الطلب**

| الحقل | مطلوب | الوصف |
|---|---|---|
| `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`

يستكشف موقعاً إلكترونياً قمت بالاستيراد منه بالفعل ويبلغ فقط عن الصفحات التي **ليست** في قاعدة معارفك بعد، مع تقديم نفس التوصية لكل منها كما في اكتشاف الصفحات. لا يتم استيراد أي شيء ولا يتم تغيير أي شيء.

عمليتا المتابعة هما استدعاءان منفصلان عمداً، لذا فإن التراجع عن هذه العملية لا يكلف شيئاً:

- استورد الصفحات الجديدة التي تريدها باستخدام [استيراد صفحات متعددة دفعة واحدة](#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`

يعيد قراءة كل صفحة استوردتها بالفعل من موقع إلكتروني، بحيث تتبع الأسئلة الشائعة الخاصة به محتوى الموقع الحالي: يتم تحديث الأقسام التي تغيرت، وإضافة أقسام جديدة، وحذف الأقسام التي تمت إزالتها.

يضع هذا العمل في قائمة الانتظار ويعود فوراً. اتبعه بـ [تتبع تحديث الموقع الإلكتروني](#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`

مدى تقدم تحديث الموقع الإلكتروني، حتى تتمكن من عرض التقدم مثل "221 من 249".

**معلمات الاستعلام**

| المعلمة | مطلوب | الوصف |
|---|---|---|
| `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` | نعم | الـ `domainBatchId` الذي تم إرجاعه بواسطة [تتبع تحديث موقع إلكتروني](#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" }'
```

**الاستجابة**

```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 | الصفحات الجديدة تماماً لهذا التحديث التي كانت لا تزال في قائمة الانتظار وتم إلغاؤها الآن. |

إلغاء العملية مرتين غير ضار — حيث يبلغ الاستدعاء الثاني عن نفس الحالة النهائية. بمجرد انتقال التحديث إلى مرحلة التنظيف، لا يمكن إيقافه بعد الآن، ويأتي الرد بـ `success: false` و `reason: "already_finalizing"`. الـ `jobId` المفقود يرجع `400`، والوظيفة التي ليست في حسابك ترجع `404`.

---

## تحديث مصدر واحد

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

يعيد قراءة صفحة ويب قمت باستيرادها مسبقاً ويجعل الأسئلة الشائعة (FAQs) الخاصة بها متوافقة مع المحتوى الحالي للصفحة: يتم تحديث الأقسام المتغيرة، وإضافة أقسام جديدة، وإسقاط الأقسام المحذوفة.

**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`. معرف المصدر الذي ليس في حسابك يرجع `404`.

---

## اختيار الصفحات الأكثر صلة

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

يطلب من الذكاء الاصطناعي اختيار الصفحات الخمس، من قائمة المرشحين، التي تصف النشاط التجاري بشكل أفضل — تُستخدم عند إنشاء دليل حملة من موقع إلكتروني. هذا يستهلك أرصدة.

**حقول الطلب**

| الحقل | مطلوب | الوصف |
|---|---|---|
| `urls` | نعم | عناوين الصفحات المرشحة للاختيار من بينها، عادةً من اكتشاف الصفحات. |
| `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`.

---

## مجموعات المعرفة

تُعد **مجموعة المعرفة** حزمة مسماة من الأسئلة الشائعة — مثل "الشحن والإرجاع"، "التأهيل" — التي يمكنك تطبيقها على وكيل أو حملة في استدعاء واحد. تحتفظ المجموعة بمراجع، وليس نسخاً: تظل الأسئلة الشائعة نفسها في مكتبتك الموحدة، لذا فإن تعديل أحدها باستخدام [واجهة برمجة تطبيقات الأسئلة الشائعة](faqs.md) يؤدي إلى تحديثه في كل مكان يُستخدم فيه.

لا يؤدي تطبيق مجموعة ما إلا إلى **إضافة** ما هو مفقود، لذا فإن تطبيق نفس المجموعة مرتين لا يسبب أي ضرر، وستعود `added_count` كـ `0` في المرة الثانية.

---

## إنشاء مجموعة معرفة

`POST /kb-groups`

ينشئ مجموعة. تبدأ المجموعة فارغة — أضف إليها أسئلة شائعة باستخدام [إضافة سؤال شائع إلى مجموعة](#add-a-faq-to-a-group).

**حقول الطلب**

| الحقل | مطلوب | الوصف |
|---|---|---|
| `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}`

يغير اسم المجموعة. تظل الأسئلة الشائعة الموجودة فيها دون تغيير.

**حقول الطلب**

| الحقل | مطلوب | الوصف |
|---|---|---|
| `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}`

يحذف المجموعة. تتم إزالة الحزمة فقط — تظل الأسئلة الشائعة الموجودة فيها في مكتبتك، وأي شيء تم تطبيق المجموعة عليه مسبقاً يحتفظ بتلك الأسئلة الشائعة.

**cURL**

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

**الاستجابة**

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

---

## إضافة أسئلة شائعة إلى مجموعة

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

يضع سؤالاً شائعاً موجوداً ضمن مجموعة. هذا الإجراء يغير الحزمة فقط — ولا يربط السؤال الشائع بأي وكيل (Agent) بحد ذاته؛ استخدم المجموعة للقيام بذلك.

**حقول الطلب**

| الحقل | مطلوب | الوصف |
|---|---|---|
| `faq_id` | نعم | معرف (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"
}
```

---

## إزالة سؤال شائع من مجموعة

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

يخرج سؤالاً شائعاً من مجموعة. لا يتم حذف السؤال الشائع نفسه، ويحتفظ الوكلاء الذين تم تطبيق المجموعة عليهم مسبقاً بهذا السؤال.

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

---

## تطبيق مجموعة على وكيل (Agent)

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

يضيف كل سؤال شائع في المجموعة إلى معرفة وكيل الذكاء الاصطناعي في استدعاء واحد — وهي الطريقة السريعة لمنح وكيل جديد قاعدة معرفية قمت بتنظيمها مسبقاً.

**حقول الطلب**

| الحقل | مطلوب | الوصف |
|---|---|---|
| `agent_id` | نعم | معرف (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` هو عدد الأسئلة الشائعة التي تمت إضافتها فعلياً — `0` عندما تكون المجموعة فارغة أو مطبقة بالفعل.

---

## تطبيق مجموعة على حملة

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

نسخة الحملة الكلاسيكية من الاستدعاء أعلاه. في الحسابات القائمة على الوكلاء، استخدم [تطبيق مجموعة على وكيل](#apply-a-group-to-an-agent) بدلاً من ذلك.

**حقول الطلب**

| الحقل | مطلوب | الوصف |
|---|---|---|
| `campaign_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
}
```

---

## أخطاء واجهة برمجة تطبيقات قاعدة المعرفة

تُرجع نقاط النهاية هذه غلاف الخطأ القياسي:

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

| الحالة | متى يحدث ذلك في نقطة نهاية قاعدة المعرفة |
|---|---|
| `400` | حقل مطلوب مفقود أو غير صالح — مثل `url` فارغ، أو `baseUrl` أو `jobId` مفقود، أو أكثر من 100 رابط URL في استيراد مجمع، أو أكثر من 2000 معرف في حذف مجمع، أو نوع ملف لا يمكننا قراءته. |
| `402` | لا توجد أرصدة كافية لتشغيل الاستيراد. قم بشحن الرصيد وحاول مرة أخرى. |
| `403` | `storage_path` خارج مجلد التحميلات الخاص بك — أو أن خطتك لا تتضمن الوصول إلى واجهة برمجة التطبيقات. |
| `404` | لم يتم العثور على المصدر أو المجموعة أو الأسئلة الشائعة (FAQ) أو الوكيل (Agent) أو الحملة أو مهمة التحديث — إما أنها غير موجودة أو أنها تنتمي إلى حساب آخر. |

> **الإخفاقات الطفيفة ليست أخطاء.** تستجيب عمليات الاكتشاف (`discover-pages`، `refresh-domain`) ومساعد اختيار الصفحة بـ `200` مع `success: false` ورسالة `error` عندما يتعذر قراءة موقع الويب، بدلاً من إفشال الطلب. تحقق دائماً من `success` قبل قراءة البيانات.

الرموز المشتركة التي يمكن أن تُرجعها كل نقطة نهاية — `401`، و `403` (خطتك لا تتضمن الوصول إلى واجهة برمجة التطبيقات)، و `429` (حد المعدل)، و `500` — مدرجة مع إرشادات إعادة المحاولة في [الأخطاء والترقيم](errors-and-pagination.md).

---

## ذات صلة

- [واجهة برمجة تطبيقات الأسئلة الشائعة](faqs.md) — قراءة وتعديل وربط الأسئلة الشائعة التي تنتجها مصادرك.
- [إدارة الأسئلة الشائعة](../ai-automation/faq-management.md) — نفس قاعدة المعرفة في لوحة التحكم.
- [وكلاء الذكاء الاصطناعي](../ai-agents/ai-agents.md) — الوكلاء الذين تقوم بإرفاق المصادر والمجموعات بهم.
- [الوصول إلى واجهة برمجة التطبيقات](../integrations/api-access.md) — إنشاء مفتاح واجهة برمجة التطبيقات الخاص بك.
- [المصادقة](authentication.md) — جميع الطرق لتمرير مفتاحك.
