# الاستخدام

نقطتا نهاية لرؤية ما استهلكه متجرك وللتنبؤ بحاجة الشهر القادم.

## `GET /v1/usage`[​](#get-v1usage "رابط مباشر إلى get-v1usage")

الشهر الميلادي الحالي مجموعًا حسب نوع نقطة النهاية.

**المصادقة:** مفتاح منصة بصلاحية `usage:read`.

### الاستجابة 200[​](#الاستجابة-200 "رابط مباشر إلى الاستجابة 200")

```
{

  "data": {

    "period": "2026-04",

    "tier":   "enterprise",

    "usage": {

      "request": { "total": 31, "billable": 0 },

      "signup":  { "total": 3,  "billable": 2 }

    },

    "limits": {

      "requests_per_month":  -1,

      "signups_per_month":   -1,

      "webhooks_per_month":  -1,

      "requests_per_minute": 600

    }

  }

}
```

### مرجع الحقول[​](#مرجع-الحقول "رابط مباشر إلى مرجع الحقول")

| الحقل                    | المعنى                                                                                                                                                          |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `period`                 | دائمًا `YYYY-MM` — أي الشهر الجاري بتوقيت **Africa/Algiers (UTC+01:00، بلا توقيت صيفي)**. والمجاميع هي مجاميع الشهر حتى تاريخه، محسوبة من اليوم الأول في 00:00. |
| `tier`                   | خطة حدود المعدل الحالية — دائمًا `enterprise` (الواجهة البرمجية حصرية لخطة Enterprise).                                                                         |
| `usage.<group>.total`    | كل الطلبات في تلك المجموعة، بما فيها المكررة/المرفوضة.                                                                                                          |
| `usage.<group>.billable` | الطلبات المحسوبة فعلًا (مثلًا الاشتراكات المكررة لا تُحاسَب).                                                                                                   |
| `limits`                 | الحدود الفعلية — `tier_limits` يطغى عليها أي تجاوز خاص بالمتجر. `-1` تعني غير محدود.                                                                            |

`usage` **متناثر (sparse)** — لا تظهر فيه إلا المجموعات التي سُجّل لها نشاط في الشهر التقويمي الحالي (عمليًا `request`، إضافةً إلى `signup` / `event` لحركة المفاتيح العامة). وإن لم يكن للمتجر أي استخدام إطلاقًا، فإن `usage` يُسلسَل كـ **مصفوفة** JSON فارغة `[]` لا ككائن. اجعل المجموعات الغائبة أصفارًا من جانب عميلك واحتمل `[]`؛ وإلا فسيفشل أي محلّل صارم الأنواع.

### مجموعات نقاط النهاية[​](#مجموعات-نقاط-النهاية "رابط مباشر إلى مجموعات نقاط النهاية")

| المجموعة  | ماذا يُحسب                                                                                                                                                                                                                                                                                                                                                                  |
| --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `request` | كل نداء اجتاز مصادقة المفتاح وحدود المعدل، ويُحسب **قبل** معالجة الطلب، فتُحسب أيضًا استجابات 4xx/5xx ورفض الصلاحيات؛ أما النداءات المرفوضة بـ `429` أو `402` فلا تُحسب. وتُحسب هنا أيضًا النداءات التي يجريها على متجرك Copilot أو مساعد ذكاء اصطناعي متصل (Claude أو ChatGPT) أو تطبيق مثبّت. و`billable` فيه دائمًا `0`. أما `GET /v1/ping` فغير موثَّق ولا يُحسب أبدًا. |
| `signup`  | كل نداء `/v1/signups`. المكررات تُحسب في `total` وليس في `billable`.                                                                                                                                                                                                                                                                                                        |
| `event`   | كل نداء `/v1/events`. لا تُحسب إلا الأحداث المسجَّلة حديثًا — أما المكررة (نفس المتجر + nonce) فتُسقَط ولا تظهر في `total` ولا في `billable`. وهذا يختلف عن `signup`.                                                                                                                                                                                                       |
| `webhook` | محجوزة. التسليمات الصادرة **غير مُقاسة** في v1، لذا لا تظهر هذه المجموعة في الاستجابة أبدًا.                                                                                                                                                                                                                                                                                |

## `GET /v1/usage/history`[​](#get-v1usagehistory "رابط مباشر إلى get-v1usagehistory")

تجميعات ساعية على مدى زمني — مفيد للرسوم البيانية وتحليل الاتجاهات.

**المصادقة:** مفتاح منصة بصلاحية `usage:read`.

### معاملات الاستعلام[​](#معاملات-الاستعلام "رابط مباشر إلى معاملات الاستعلام")

| المعامل | النوع    | الافتراضي  | ملاحظات  |
| ------- | -------- | ---------- | -------- |
| `from`  | ISO date | قبل 7 أيام | شامل     |
| `to`    | ISO date | الآن       | غير شامل |

السقف الأقصى للمدى: 90 يومًا. و`from` شامل و`to` غير شامل، ويُقرَّب كلاهما إلى بداية الساعة لأغراض *الاستعلام* فقط — أما قيمتا `from` / `to` المُعادتان في الاستجابة فهما مدخلاتك كما جرى تحليلها، دون تقريب. وتُقبَل صيغ التاريخ والوقت الشائعة (`2026-04-01` و`2026-04-01T12:00:00Z` و`-7 days` …)؛ أما القيمة غير القابلة للتحليل أو `to` أقدم من `from` فتُرجع `400 bad_request` ("from/to must be valid date strings, to >= from")، والمدى الذي يتجاوز 90 يومًا يُرجع `400` ("range too large (max 90 days)").

وأوعية `period_hour` هي ساعات كاملة مختومة بتوقيت Africa/Algiers (UTC+01:00) في لحظة احتساب كل طلب.

### الأخطاء[​](#الأخطاء "رابط مباشر إلى الأخطاء")

| HTTP | الكود         | السبب                                            |
| ---- | ------------- | ------------------------------------------------ |
| 400  | `bad_request` | "from/to must be valid date strings, to >= from" |
| 400  | `bad_request` | "range too large (max 90 days)"                  |
| 403  | `forbidden`   | "Missing scope: usage<!-- -->:read<!-- -->"      |

`usage:read` ضمن مجموعة الصلاحيات الافتراضية للمفاتيح التي تُنشئها من لوحة التحكم. والمفتاح المُنشأ عبر `POST /v1/keys` لا يحملها إلا إذا كان المفتاح المنادي يحملها، ورمز التطبيق المثبّت لا يمكنه حملها أبدًا، لذا يتلقى التطبيق `403` على هاتين النقطتين وعلى `/v1/quotas`.

### الطلب[​](#الطلب "رابط مباشر إلى الطلب")

```
curl 'https://api.dzbuild.app/v1/usage/history?from=2026-04-01&to=2026-05-01' \

  -H "Authorization: Bearer $DZ_KEY"
```

### الاستجابة 200[​](#الاستجابة-200-1 "رابط مباشر إلى الاستجابة 200")

```
{

  "data": {

    "from": "2026-04-01T00:00:00+01:00",

    "to":   "2026-05-01T00:00:00+01:00",

    "rows": [

      { "period_hour": "2026-04-30 19:00:00", "endpoint_group": "request", "count": 26, "billable_count": 0 },

      { "period_hour": "2026-04-30 20:00:00", "endpoint_group": "request", "count": 5,  "billable_count": 0 },

      { "period_hour": "2026-04-30 20:00:00", "endpoint_group": "signup",  "count": 3,  "billable_count": 2 }

    ]

  }

}
```

الصفوف مرتبة تصاعديًا حسب `period_hour`. الساعات ذات الاستخدام الصفري في أي مجموعة تُحذف (sparse).

## نصائح للرسم[​](#نصائح-للرسم "رابط مباشر إلى نصائح للرسم")

* **التجميع اليومي:** اجمع الصفوف حسب أول 10 أحرف من `period_hour` (بادئة التاريخ).
* **مساحة مكدّسة:** جمّع حسب `endpoint_group` ثم الساعة على المحور الأفقي.
* **معدل استنزاف الحصة:** اقسم `signup.billable_count` التراكمي على نسبة الشهر المنقضية، وتوقّع نهاية الشهر.

مثال Python بسيط:

```
import collections, datetime, requests, os



r = requests.get('https://api.dzbuild.app/v1/usage/history',

    params={'from': '2026-04-01', 'to': '2026-05-01'},

    headers={'Authorization': f"Bearer {os.environ['DZ_KEY']}"})

rows = r.json()['data']['rows']



by_day = collections.defaultdict(lambda: collections.Counter())

for row in rows:

    day = row['period_hour'][:10]

    by_day[day][row['endpoint_group']] += row['count']



for day, counts in sorted(by_day.items()):

    print(day, dict(counts))
```
