
# واجهة برمجة تطبيقات التحليلات والتقارير

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

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

تحتاج كل نقطة نهاية في هذه الصفحة إلى نطاق دقيق، وليس كلاهما: مرر نطاقاً واحداً على الأكثر من `campaign_id` (قديم) أو `agent_id` حيث تقبل نقطة النهاية ذلك. إرسال كليهما يعيد `400`، ومعرف غير موجود في حسابك يعيد `404` بدلاً من `403`، بحيث تظل معرفات الحسابات الأخرى غير قابلة للتخمين.

جميع المسارات أدناه نسبية إلى عنوان URL الأساسي لواجهة برمجة التطبيقات:

```
https://api.youraiconnector.com/v1
```

يجب مصادقة كل طلب. راجع [المصادقة](authentication.md) لمعرفة الطرق الأربع المقبولة. تستخدم الأمثلة هنا رأس `X-API-Key` (ونموذج معلمة استعلام واحد لـ cURL).

---

## نطاق التاريخ

تقبل نقاط النهاية الثلاث جميعها نفس عوامل تصفية التاريخ الاختيارية:

| المعلمة | الوصف |
|---|---|
| `from` | بداية النطاق، `YYYY-MM-DD`، شامل. القيمة الافتراضية هي قبل 30 يوماً. |
| `to` | نهاية النطاق، `YYYY-MM-DD`، شامل. القيمة الافتراضية هي اليوم. |

يتم تفسير التواريخ بتوقيت UTC. النطاق الافتراضي هو **آخر 30 يوماً** ومحدد بـ **366 يوماً** — النطاق الأوسع يعيد `400`. يجب ألا يكون `from` بعد `to`.

### علامة `truncated`

تحدد نقاط النهاية **الملخص** و **الأرصدة** عدد السجلات التي يقوم الطلب الواحد بمسحها. إذا كان نطاقك مشغولاً بما يكفي للوصول إلى هذا الحد، فإن الاستجابة تتضمن `"truncated": true`. عندما تراه، تكون الأرقام مبنية على مسح جزئي — قم بتضييق نطاق التاريخ (أو التنقل عبر الصفحات بنافذة أصغر) للحصول على أرقام كاملة.

::: note
**ملاحظة:** يتم تضمين أرقام التكلفة والرموز فقط لطلبات الذكاء الاصطناعي التي تتم محاسبتها على مفاتيح واجهة برمجة تطبيقات (API) الخاصة بمزودك. عندما تكون أرقام التكلفة مخفية لحسابك، تقوم الاستجابة بتعيين `"costs_redacted": true` وتتم إعادة حقول التكلفة كأصفار.
:::


---

## ملخص حجم الرسائل

يعيد عدادات أحداث الرسائل المجمعة لحسابك، كإجماليات للنطاق وكسلسلة يومية. يظهر كل يوم في النطاق في `by_date` — الأيام الهادئة يتم ملؤها بأصفار. يمكنك التصفية اختيارياً لحملة واحدة باستخدام `campaign_id`.

`GET /analytics/summary`

| المعلمة | مطلوبة | الوصف |
|---|---|---|
| `from` | لا | بداية النطاق، `YYYY-MM-DD`. |
| `to` | لا | نهاية النطاق، `YYYY-MM-DD`. |
| `campaign_id` | لا | احتساب الأحداث التي تنتمي إلى هذه الحملة فقط. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/summary?from=2026-05-01&to=2026-05-31&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({ from: "2026-05-01", to: "2026-05-31" });
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/summary?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/summary",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"from": "2026-05-01", "to": "2026-05-31"},
)
data = res.json()
```

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

```json
{
  "success": true,
  "from": "2026-05-01",
  "to": "2026-05-31",
  "totals": {
    "total": 1240,
    "sent": 800,
    "delivered": 760,
    "read": 540,
    "replied": 210,
    "booked": 35,
    "contact_created": 120,
    "credits_spent": 412.5,
    "credits_recharged": 500
  },
  "by_date": [
    {
      "date": "2026-05-01",
      "total": 40,
      "sent": 25,
      "delivered": 24,
      "read": 18,
      "replied": 7,
      "booked": 1,
      "contact_created": 4,
      "credits_spent": 13.5,
      "credits_recharged": 0
    }
  ],
  "truncated": false
}
```

يحتوي كل إدخال في `by_date` على نفس حقول العدادات الموجودة في `totals`، بالإضافة إلى `date`.

إذا قمت بتمرير `campaign_id` لا ينتمي إلى حسابك، فستكون الاستجابة `404` مع `{ "success": false, "error": "Campaign not found" }`.

---

## استخدام الرصيد

يعيد استخدام الرصيد خلال النطاق: قائمة مرقمة من السجلات الفردية، بالإضافة إلى إجماليات النطاق وتفصيلاتها حسب السبب وحسب الحملة.

`GET /analytics/credits`

| المعلمة | مطلوبة | الوصف |
|---|---|---|
| `from` | لا | بداية النطاق، `YYYY-MM-DD`. |
| `to` | لا | نهاية النطاق، `YYYY-MM-DD`. |
| `campaign_id` | لا | تضمين الاستخدام المنسوب إلى هذه الحملة فقط. |
| `limit` | لا | حجم الصفحة لـ `records`، من 1 إلى 100. القيمة الافتراضية هي 50. |
| `cursor` | لا | مرر `next_cursor` الصفحة السابقة لجلب الصفحة التالية. |

> **التعديلات مقابل الاستهلاك:** يتم **استبعاد** تغييرات الرصيد مثل المكافآت وتجديدات الخطط والتصحيحات من `totals` والتفصيلات — فهي لا تُعد استهلاكاً فعلياً. ومع ذلك، فهي تظهر في قائمة `records`، مميزة بـ `"is_adjustment": true`.

**تظهر الإجماليات والتفصيلات في الصفحة الأولى فقط** (عند عدم توفير `cursor`). في الصفحات اللاحقة، يتم إرجاع `totals` و `by_reason` و `by_reason_cost` و `by_campaign` كـ `null` — مصفوفة `records` فقط هي التي تستمر. هذا يتجنب إعادة مسح النطاق بالكامل لكل صفحة.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/credits?from=2026-05-01&to=2026-05-31&limit=50&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({
  from: "2026-05-01",
  to: "2026-05-31",
  limit: "50",
});
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/credits?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();

// To page: pass data.next_cursor as ?cursor on the next request, until it is null.
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/credits",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"from": "2026-05-01", "to": "2026-05-31", "limit": 50},
)
data = res.json()

# To page: pass data["next_cursor"] as cursor on the next request, until it is None.
```

**الاستجابة** (الصفحة الأولى)

```json
{
  "success": true,
  "from": "2026-05-01",
  "to": "2026-05-31",
  "totals": {
    "credits_used": 412.5,
    "cost_usd": 1.284512,
    "records": 318
  },
  "by_reason": {
    "AI Message": 380.0,
    "Campaign Message": 32.5
  },
  "by_reason_cost": {
    "AI Message": 1.284512,
    "Campaign Message": 0
  },
  "by_campaign": {
    "Spring Promo": 250.0,
    "Reactivation": 162.5
  },
  "records": [
    {
      "id": "rec_abc123",
      "amount": 1,
      "timestamp": "2026-05-31T14:02:11.000Z",
      "reason": "AI Message",
      "is_adjustment": false,
      "campaign_id": "campaign123",
      "campaign_name": "Spring Promo",
      "contact_id": "contact456",
      "contact_name": "Jane Smith",
      "credit_type": "ai",
      "custom_keys_used": false,
      "description": null,
      "cost_usd": 0,
      "input_tokens": 0,
      "output_tokens": 0,
      "cache_read_tokens": 0,
      "cache_creation_tokens": 0,
      "ai_model": null,
      "request_id": null,
      "is_test": false
    }
  ],
  "next_cursor": "rec_abc123",
  "costs_redacted": false,
  "truncated": false
}
```

**ملاحظات ميدانية:**

- `amount` — الأرصدة المحتسبة للسجل. تكون صفراً للسجلات المفوترة لمفتاح واجهة برمجة تطبيقات (API) الخاص بمزودك.
- `is_adjustment` — `true` لتغييرات الرصيد (مستبعدة من الإجماليات/التفصيلات).
- `cost_usd`، `input_tokens`، `output_tokens`، `cache_read_tokens`، `cache_creation_tokens`، `ai_model`، `request_id` — يتم ملؤها فقط في السجلات المفوترة لمفتاح واجهة برمجة تطبيقات (API) الخاص بمزودك؛ وإلا تكون صفراً أو `null`.
- `is_test` — `true` لعمليات التشغيل التجريبية/الاختبارية، والتي لا يتم فوترتها أبداً.
- `next_cursor` — المؤشر للصفحة التالية، أو `null` عندما لا توجد سجلات أخرى.

---

## تجميع تكاليف الذكاء الاصطناعي

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

`GET /analytics/ai-cost`

| المعلمة | مطلوبة | الوصف |
|---|---|---|
| `from` | لا | بداية النطاق، `YYYY-MM-DD`. |
| `to` | لا | نهاية النطاق، `YYYY-MM-DD`. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/ai-cost?from=2026-05-01&to=2026-05-31&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({ from: "2026-05-01", to: "2026-05-31" });
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/ai-cost?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/ai-cost",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"from": "2026-05-01", "to": "2026-05-31"},
)
data = res.json()
```

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

```json
{
  "success": true,
  "from": "2026-05-01",
  "to": "2026-05-31",
  "totals": {
    "total_usd": 12.4821,
    "byok_usd": 12.4821,
    "platform_usd": 0,
    "calls": 4210
  },
  "days": [
    {
      "date": "2026-05-01",
      "total_usd": 0.4012,
      "byok_usd": 0.4012,
      "platform_usd": 0,
      "input_usd": 0.18,
      "output_usd": 0.19,
      "cache_creation_usd": 0.02,
      "cache_read_usd": 0.0112,
      "calls": 140,
      "by_provider": { "anthropic": 0.4012 }
    }
  ],
  "costs_redacted": false
}
```

**ملاحظات ميدانية:**

- `byok_usd` — الإنفاق الذي يتم تحميله على مفاتيح API الخاصة بمزود الخدمة الخاص بك.
- `platform_usd` — جزء الإنفاق الذي تم تشغيله على المنصة بدلاً من مفتاحك الخاص.
- `input_usd`، `output_usd`، `cache_creation_usd`، `cache_read_usd` — مكونات التكلفة التي تشكل `total_usd`.
- `by_provider` — الإنفاق بالدولار الأمريكي مصنفاً حسب اسم مزود الذكاء الاصطناعي.
- يتم إرجاع أرقام الدولار الأمريكي فقط للحسابات التي تستخدم مفتاح المزود الخاص بها. بالنسبة للحسابات التي تدفع بالرصيد، يكون كل حقل دولار أمريكي صفراً ويكون `costs_redacted` هو `true` (تظل أعداد المكالمات مرئية).

---

## سلسلة المقاييس

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

`GET /analytics/series`

تحمل كل استجابة مصفوفة `labels` (محور الوقت، مملوء بالأصفار عبر النطاق بأكمله) ومدخلاً واحداً في `series` لكل مجموعة، يحتوي كل منها على مصفوفة واحدة لكل مقياس مطلوب محاذٍ لـ `labels`. السلاسل التي تتجاوز `limit` لا يتم إسقاطها — بل تنهار في `other_bucket`، والتي يتم حسابها كإجمالي النطاق مطروحاً منه السلسلة المعادة، بحيث يضيف المخطط المعروض دائماً ما يصل إلى أرقامك الحقيقية؛ `truncated` تكون `true` كلما حدث ذلك.

من أين تأتي الأرقام: `sent`، و`delivered`، و`read`، و`replied` تأتي من سجلات الرسائل، التي تحمل القناة ورقم الإرسال. `booked`، و`contact_created`، و`credits_spent` تأتي من دفق الأحداث، الذي لا يحمل رقم إرسال، لذا تهبط هذه المقاييس في دلو الرقم `null` عند التجميع حسب `number`.

| المعلمة | مطلوبة | الوصف |
|---|---|---|
| `from` | لا | بداية النطاق، `YYYY-MM-DD`. الافتراضي هو قبل 30 يوماً. |
| `to` | لا | نهاية النطاق، `YYYY-MM-DD`. الافتراضي هو اليوم. |
| `metrics` | لا | قائمة مفصولة بفواصل من `sent`، `ai_sent`، `human_sent`، `delivered`، `read`، `replied`، `booked`، `contact_created`، `credits_spent`. الافتراضي هو `sent,replied`. المقياس غير المعروف يعيد `400`. |
| `group_by` | لا | قائمة مفصولة بفواصل تصل إلى بُعدين من `date`، `campaign`، `channel`، `agent`، `number`. يتم قبول `date` ولكن ليس له تأثير — كل استجابة تحمل بالفعل محور الوقت. احذفها للحصول على سلسلة واحدة على مستوى الحساب. |
| `granularity` | لا | `day` (افتراضي)، أو `week`، أو `month`. تبدأ دلاء الأسبوع يوم الاثنين، ودلاء الشهر في اليوم الأول. |
| `limit` | لا | عدد السلاسل التي يجب إرجاعها قبل أن تنهار البقية في `other_bucket`، من 1 إلى 50. الافتراضي هو 12. |
| `campaign_id` | لا | احتساب النشاط الذي ينتمي لهذه الحملة فقط. قديم؛ يفضل استخدام `agent_id`. |
| `agent_id` | لا | احتساب النشاط الذي ينتمي لوكيل الذكاء الاصطناعي هذا فقط. |
| `channel` | لا | احتساب النشاط على هذه القناة فقط، على سبيل المثال `whatsapp`. |

نطاق التاريخ لنقطة النهاية هذه محدود بـ **92 يوماً** (أضيق من حد الـ 366 يوماً المستخدم في أماكن أخرى في هذه الصفحة).

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/series?from=2026-05-01&to=2026-05-31&metrics=sent,replied,booked&group_by=campaign,channel&limit=10&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({
  from: "2026-05-01",
  to: "2026-05-31",
  metrics: "sent,replied,booked",
  group_by: "campaign,channel",
  limit: "10",
});
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/series?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/series",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={
        "from": "2026-05-01",
        "to": "2026-05-31",
        "metrics": "sent,replied,booked",
        "group_by": "campaign,channel",
        "limit": 10,
    },
)
data = res.json()
```

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

```json
{
  "success": true,
  "from": "2026-05-01",
  "to": "2026-05-31",
  "granularity": "day",
  "labels": ["2026-05-01", "2026-05-02"],
  "group_by": ["campaign", "channel"],
  "metrics": ["sent", "replied", "booked"],
  "series": [
    {
      "key": {
        "campaign_id": "campaign123",
        "campaign_name": "Spring Promo",
        "channel": "whatsapp"
      },
      "total": 812,
      "metrics": {
        "sent": [40, 35],
        "replied": [12, 9],
        "booked": [2, 1]
      }
    }
  ],
  "other_bucket": {
    "series_count": 6,
    "total": 340,
    "metrics": {
      "sent": [18, 20],
      "replied": [5, 6],
      "booked": [0, 1]
    }
  },
  "truncated": true
}
```

**ملاحظات ميدانية:**

- `key` — هوية سلسلة واحدة. توجد فقط المفاتيح للأبعاد المطلوبة `group_by`؛ البعد الذي تكون قيمته غير معروفة لصف ما (رسالة بدون حملة، حدث بدون قناة) يعود كـ `null` بدلاً من إسقاطه، بحيث تظل السلاسل تضيف إلى الإجماليات.
- `other_bucket` — `null` عندما لا يتم طي أي شيء.
- تعيد نقطة النهاية هذه `503` مع `"error_code": "analytics_unavailable"` عندما لا تستطيع قاعدة بيانات التقارير الإجابة عن حسابك، بدلاً من `200` مليئة بالأصفار — المخطط المليء بالأصفار سيُقرأ كحقيقة.

---

## نتائج المحادثة

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

`GET /analytics/outcomes`

مرر `group_by=tag` لطي محور الوقت والحصول على إجماليات النطاق لكل علامة فقط — في هذا الوضع تكون `labels` فارغة وتكون مصفوفة `counts` لكل علامة فارغة، بينما تظل `total` مأهولة.

| المعلمة | مطلوبة | الوصف |
|---|---|---|
| `from` | لا | بداية النطاق، `YYYY-MM-DD`. القيمة الافتراضية هي قبل 30 يوماً. |
| `to` | لا | نهاية النطاق، `YYYY-MM-DD`. القيمة الافتراضية هي اليوم. |
| `campaign_id` | لا | احتساب المحادثات مع جهات الاتصال الموجودة حالياً في هذه الحملة فقط. قديم؛ يُفضل استخدام `agent_id`. |
| `agent_id` | لا | احتساب النتائج التي تنتمي إلى وكيل الذكاء الاصطناعي هذا فقط. |
| `group_by` | لا | `date` (افتراضي) يحتفظ بالعدد اليومي؛ `tag` يدمج النتائج في إجمالي النطاق. |

نطاق التاريخ لهذا الطرف (endpoint) محدود بـ **92 يوماً**.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/outcomes?from=2026-05-01&to=2026-05-31&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({ from: "2026-05-01", to: "2026-05-31" });
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/outcomes?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/outcomes",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"from": "2026-05-01", "to": "2026-05-31"},
)
data = res.json()
```

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

```json
{
  "success": true,
  "from": "2026-05-01",
  "to": "2026-05-31",
  "group_by": "date",
  "labels": ["2026-05-01", "2026-05-02"],
  "by_tag": [
    { "tag": "interested", "total": 84, "counts": [3, 5] },
    { "tag": "not_interested", "total": 40, "counts": [1, 2] },
    { "tag": null, "total": 12, "counts": [0, 1] }
  ],
  "totals": {
    "sessions": 260,
    "replied": 210,
    "booked": 35,
    "human_alerted": 18,
    "unresolved": 12
  }
}
```

**ملاحظات ميدانية:**

- `by_tag[].tag` — `null` للمحادثات التي لم يقم الذكاء الاصطناعي بتعيين وسم نتيجة لها.
- `totals.human_alerted` — المحادثات التي تم تحويلها إلى بشري؛ يتم كتابة هذا في كل عملية تحويل ولم يكن متاحاً سابقاً عبر أي طرف (endpoint).
- نفس وضع `503`/`analytics_unavailable` مثل سلسلة المقاييس عندما لا تستطيع قاعدة بيانات التقارير الإجابة.

---

## رؤى لوحة التحكم

يعيد حمولة لوحة التحكم الكاملة لنطاق تاريخي في طلب واحد: خريطة حرارية لمعدل الرد حسب يوم الأسبوع والساعة، ولوحة صدارة الحملات، وحجم الرسائل لكل قناة، وإجمالي الاتصالات الدقيق، وتفاصيل المقاييس اليومية (على مستوى الحساب، لكل قناة، ولكل رقم)، ومصادر جهات الاتصال، ووقت الاستجابة في صندوق الوارد، وخلاصة النشاط الأخير. هذه هي أغنى حمولة تقارير في واجهة برمجة التطبيقات (API) — وهي التي تشغل لوحة التحكم داخل التطبيق مباشرة.

`GET /analytics/dashboard-insights`

| المعلمة | مطلوبة | الوصف |
|---|---|---|
| `startDate` | نعم | بداية النطاق، `YYYY-MM-DD`. |
| `endDate` | نعم | نهاية النطاق، `YYYY-MM-DD`. |
| `campaignId` | لا | تضمين النشاط الذي ينتمي إلى هذه الحملة فقط (يُقبل أيضاً `campaign_id`). قديم؛ يُفضل استخدام `agent_id`. |
| `agent_id` | لا | تضمين النشاط الذي ينتمي إلى وكيل الذكاء الاصطناعي هذا فقط (يُقبل أيضاً `agentId`). تحت نطاق الوكيل، يتم بناء لوحة صدارة الحملات من نشاط ذلك الوكيل فقط. |

يستخدم هذا الطرف (endpoint) `startDate`/`endDate` (وليس `from`/`to`) لأنه يتشارك في تنفيذه مع لوحة التحكم داخل التطبيق. النطاق محدود بـ 92 يوماً ويتم **تقييده (clamped) وليس رفضه** عندما يكون أوسع من ذلك.

> **تعني القيمة Null أنها غير متاحة، وليست صفراً.** يتم حساب العديد من الكتل (`numberStats`، `channelDailySeries`، `metricDailyBreakdown`، `contactsByCountry`) من قاعدة بيانات التقارير وتعود كـ `null` عندما لا تستطيع الإجابة لحسابك. لا تقم بعرض كتلة `null` كرسم بياني فارغ.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/dashboard-insights?startDate=2026-05-01&endDate=2026-05-31&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({ startDate: "2026-05-01", endDate: "2026-05-31" });
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/dashboard-insights?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/dashboard-insights",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"startDate": "2026-05-01", "endDate": "2026-05-31"},
)
data = res.json()
```

**الاستجابة** (مختصرة — هذه الحمولة كبيرة؛ راجع [مرجع واجهة برمجة التطبيقات](reference.md) للحصول على المخطط الكامل)

```json
{
  "success": true,
  "data": {
    "heatmap": {
      "buckets": [
        { "weekday": 1, "hour": 9, "sent": 12, "replied": 5, "replyRate": 0.42 }
      ]
    },
    "topCampaigns": [
      { "campaignId": "campaign123", "name": "Spring Promo", "sent": 420, "replied": 180, "booked": 22, "replyRate": 0.43, "creditsSpent": 210.5 }
    ],
    "channelVolume": [
      { "channel": "whatsapp", "sent": 800, "received": 540, "lastMessageAt": "2026-05-31T14:02:11.000Z" }
    ],
    "inboxSla": { "medianFirstResponseMs": 92000, "sampleSize": 140 },
    "activityFeed": [
      { "id": "evt_1", "kind": "booked", "at": "2026-05-31T14:02:11.000Z", "contactId": "contact456", "contactName": "Jane Smith", "campaignId": "campaign123", "campaignName": "Spring Promo", "label": "Jane Smith booked an appointment" }
    ],
    "numberStats": null,
    "channelDailySeries": null,
    "metricDailyBreakdown": null,
    "contactsByCountry": null,
    "ai_human_split": null
  }
}
```

**ملاحظات ميدانية:**

- `heatmap.buckets[].weekday` — `0` هو الأحد حتى `6` هو السبت.
- `numberStats`، `channelDailySeries`، `metricDailyBreakdown`، `contactsByCountry`، `ai_human_split` — كل منها `null` بشكل مستقل عندما تكون قاعدة بيانات التقارير غير متاحة لحسابك؛ كل كتلة أخرى لا تزال تعيد بيانات.

---

## رؤى الذكاء الاصطناعي للوحة التحكم

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

`GET /analytics/dashboard-ai-insights`

| المعلمة | مطلوبة | الوصف |
|---|---|---|
| `startDate` | نعم | بداية النطاق، `YYYY-MM-DD`. |
| `endDate` | نعم | نهاية النطاق، `YYYY-MM-DD`. |

نقطة النهاية هذه على مستوى الحساب بالكامل — فهي لا تأخذ نطاق حملة أو وكيل.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/dashboard-ai-insights?startDate=2026-05-01&endDate=2026-05-31&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({ startDate: "2026-05-01", endDate: "2026-05-31" });
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/dashboard-ai-insights?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/dashboard-ai-insights",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"startDate": "2026-05-01", "endDate": "2026-05-31"},
)
data = res.json()
```

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

```json
{
  "success": true,
  "data": {
    "insights": [
      { "tone": "win", "title": "Reply rate is up", "detail": "Your reply rate climbed to 43% this period, up from 36% the period before." },
      { "tone": "watch", "title": "Bookings slowed midweek", "detail": "Wednesday bookings dropped to a third of Monday's, worth a look at your Wednesday follow-up timing." },
      { "tone": "tip", "title": "Re-send to non-repliers", "detail": "212 contacts received a message but never replied — a short follow-up template often recovers 10-15% of them." }
    ]
  }
}
```

فقدان `startDate` أو `endDate` يُرجع `400`.

---

## الجدول الزمني لنشاط الكيان

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

`GET /analytics/entity-activity`

| المعلمة | مطلوبة | الوصف |
|---|---|---|
| `entityType` | نعم | `contact` أو `deal` أو `task`. |
| `entityId` | نعم | معرف السجل الذي تريد إرجاع جدوله الزمني. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/entity-activity?entityType=contact&entityId=contact456&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const params = new URLSearchParams({ entityType: "contact", entityId: "contact456" });
const res = await fetch(`https://api.youraiconnector.com/v1/analytics/entity-activity?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/analytics/entity-activity",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"entityType": "contact", "entityId": "contact456"},
)
data = res.json()
```

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

```json
{
  "success": true,
  "data": {
    "items": [
      {
        "id": "evt_9",
        "kind": "appointment_booked",
        "at": "2026-05-31T14:02:11.000Z",
        "label": "Booked an appointment for June 3",
        "detail": "Consultation call, 30 minutes"
      },
      {
        "id": "evt_8",
        "kind": "message_replied",
        "at": "2026-05-31T13:58:02.000Z",
        "label": "Replied: \"Yes, that time works\""
      }
    ]
  }
}
```

يُرجع فقدان أو عدم صلاحية `entityType`/`entityId` القيمة `400`. الكيان غير الموجود في حسابك يُرجع `404`، بحيث تظل معرفات الحسابات الأخرى غير قابلة للتخمين.

---

## إجمالي عدد الأحداث (قديم)

يُرجع نفس إجمالي عدد الأحداث مثل [ملخص حجم الرسائل](#message-volume-summary)، ولكن بتنسيق camelCase (مثل `contactCreated` بدلاً من `contact_created`، و`byDate` بدلاً من `by_date`) الذي بُنيت عليه بعض عمليات التكامل القديمة. يُفضل استخدام `/analytics/summary` لعمليات التكامل الجديدة — توجد نقطة النهاية هذه فقط لكي تتشارك لوحة تحكم التطبيق وواجهة برمجة التطبيقات في تنفيذ واحد.

`GET /analytics/aggregate`

| المعلمة | مطلوبة | الوصف |
|---|---|---|
| `startDate` | لا | بداية النطاق، تاريخ أو تاريخ ووقت بتنسيق ISO. يتم تعيينه افتراضياً على نفس النافذة التي يستخدمها `/analytics/summary`. |
| `endDate` | لا | نهاية النطاق، تاريخ أو تاريخ ووقت بتنسيق ISO. |
| `campaignId` | لا | عد الأحداث التي تنتمي لهذه الحملة فقط (يُقبل أيضاً `campaign_id`). قديم؛ يُفضل استخدام `agent_id`. |
| `agent_id` | لا | عد الأحداث التي تنتمي لهذا الوكيل الذكي (AI Agent) فقط (يُقبل أيضاً `agentId`). |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/analytics/aggregate?startDate=2026-05-01&endDate=2026-05-31&apiKey=YOUR_API_KEY"
```

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

```json
{
  "success": true,
  "data": {
    "from": "2026-05-01",
    "to": "2026-05-31",
    "total": 1240,
    "byAnalyticType": {
      "total": 1240,
      "sent": 800,
      "delivered": 760,
      "read": 540,
      "replied": 210,
      "booked": 35,
      "contactCreated": 120,
      "creditsSpent": 412.5,
      "creditsRecharged": 500
    },
    "byDate": [
      { "date": "2026-05-01", "byAnalyticType": { "total": 40, "sent": 25, "delivered": 24, "read": 18, "replied": 7, "booked": 1, "contactCreated": 4, "creditsSpent": 13.5, "creditsRecharged": 0 } }
    ]
  }
}
```

---

## تجميع الحسابات الفرعية للوكالة


---

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

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

```json
{
  "success": false,
  "error": "Date range too large. Maximum is 366 days."
}
```

في نقطة نهاية التحليلات، يُرجع تنسيق التاريخ غير الصالح أو النافذة خارج النطاق `400`، ويُرجع `campaign_id` أو `agent_id` غير المعروف `404`. إرسال كل من `campaign_id` و`agent_id` في نقطة نهاية تقبل أياً منهما يعد أيضاً `400` — مرر واحدة فقط كحد أقصى. تُرجع نقاط نهاية التقارير الخاصة بـ PG فقط (سلسلة المقاييس، نتائج المحادثة، تجميع الوكالة) `503` مع `"error_code": "analytics_unavailable"` بدلاً من `200` مليئة بالأصفار عندما لا تستطيع قاعدة بيانات التقارير الإجابة عن حسابك — حاول مرة أخرى بعد قليل. الرموز المشتركة التي يمكن أن تُرجعها كل نقطة نهاية — `401`، `403` (خطتك لا تتضمن الوصول إلى واجهة برمجة التطبيقات، أو في حالة تجميع الوكالة، حسابك ليس وكالة/مطور)، `429` (حد المعدل) و`500` — مدرجة مع إرشادات إعادة المحاولة في [الأخطاء والترقيم](errors-and-pagination.md).

---

## الخطوات التالية

- [المصادقة](authentication.md) — الطرق الأربع لمصادقة الطلب.
- [الأخطاء وحدود المعدل](errors-and-pagination.md) — رموز الحالة وحد 300 طلب/دقيقة.
- [واجهة برمجة تطبيقات الحملات](campaigns.md) — الحملات التي يمكن تصفية هذه الأرقام بناءً عليها.
