كل نقطة نهاية تعيش تحت `/api/v1`. هذه الصفحة هي السياسة كاملة: ما الذي تلتزم `/api/v1` بعدم فعله أبدًا، وما الذي يُعدّ تغييرًا جذريًا (breaking)، وكيف تُوقَف عملية بعينها عن الدعم دون كسر أي عميل ما يزال يستدعيها، وسجلّ كل تصحيح على مستوى العقد قمنا به.

## ثبات /api/v1

داخل `/api/v1` نُجري تغييرات **إضافية فقط**:

- نقطة نهاية جديدة.
- حقل اختياري جديد في الطلب.
- حقل جديد في الاستجابة.
- رمز خطأ (`code`) جديد ومنفصل لحالة فشل جديدة فعلًا.

لا نفعل أبدًا داخل `/api/v1`:

- حذف حقل من استجابة.
- تضييق نوع حقل (مثال: تحويل حقل قابل لأن يكون `null` إلى غير قابل لذلك أمر مقبول؛ العكس — أو توسيع `string` إلى `string | number` — غير مقبول).
- إضافة حقل *إلزامي* جديد في الطلب.
- تغيير رمز حالة HTTP الذي تُعيده عملية لنتيجة معيّنة.
- تغيير `error.code` الذي تُعيده حالة فشل موجودة أصلًا.

إن كان تكاملك يقرأ فقط الحقول التي يعرفها ويتحمّل ظهور حقول جديدة، فسيستمر بالعمل على `/api/v1` إلى أجل غير مسمّى — هذا هو جوهر القاعدة.

## ما الذي يُعدّ تغييرًا جذريًا (breaking)

أي شيء في قائمة "لا نفعل أبدًا" أعلاه هو تغيير جذري، ولا يُطبَّق أبدًا داخل `/api/v1`. التغيير الجذري يعني بدلًا من ذلك `/api/v2`، مُعلَنًا عنه قبل **180 يومًا** على الأقل من بدء إيقاف دعم `/api/v1`. يعمل الإصداران معًا جنبًا إلى جنب طوال فترة الإشعار كاملة — لا يُسحَب شيء من تحت قدَمَي أي مُكامِل دون تحذير.

## إيقاف دعم عملية بعينها

يمكن إيقاف دعم عملية واحدة داخل `/api/v1` — تبقى تعمل بالكامل، لكنها تُعلَّم للإزالة لاحقًا (عادةً لأن `/api/v2` أو عملية أحدث تحلّ محلّها). طوال ما تبقّى من عمرها تحمل ثلاثة ترويسات و `"deprecated": true` في مستند OpenAPI:

```http
HTTP/1.1 200 OK
Deprecation: @1735689600
Sunset: Wed, 01 Jul 2026 00:00:00 GMT
Link: <https://docs.institflow.com/en/guides/versioning#deprecations>; rel="deprecation"
```

- `Deprecation` — متى بدأ إيقاف الدعم، بصيغة `@` متبوعة بثوانٍ يونكس ([RFC 9745](https://www.rfc-editor.org/rfc/rfc9745)). المثال أعلاه، `@1735689600`، هو `2025-01-01T00:00:00Z`.
- `Sunset` — أقرب تاريخ يمكن فيه إزالة العملية، بصيغة IMF-fixdate ([RFC 8594](https://www.rfc-editor.org/rfc/rfc8594))، ويكون دائمًا بعد `Deprecation` بـ 180 يومًا على الأقل.
- `Link` — يشير إلى جدول إيقافات الدعم أسفل هذه الصفحة، بحيث يجد أي عميل يكتفي بتسجيل الترويسات طريقةً لمعرفة السبب.

`replacedBy`، عند وجود بديل مباشر، وملاحظة قصيرة قابلة للقراءة `note`، تظهران في الجدول أدناه وفي مرجع API المُولَّد لتلك العملية — لا في الترويسات نفسها، التي تبقى صغيرة وقابلة للتحليل الآلي.

## ترويسات حدود معدّل الطلبات

كل استجابة — سواء كانت لعملية مُوقَفة أم لا، ناجحة أم لا — تحمل `RateLimit-Limit` و`RateLimit-Remaining` و`RateLimit-Reset`. وكل استجابة `429 RATE_LIMITED` — سواء من المُحدِّد العام لكل عنوان IP/مستخدم الذي يحمي كل مسار، أو من ميزانية مفتاح API السرّي الخاصة به — تحمل إضافةً إلى ذلك `Retry-After`، بالثواني، لكي يعرف العميل الملتزم بالضبط كم ينتظر دون تخمين من `RateLimit-Reset` وحدها.

> **العمليات الموقوفة حاليًا**
>
> لا شيء. لا توجد أي عملية موقوفة الدعم في الواجهة الحالية.

## سجلّ التغييرات

تصحيحات على مستوى العقد وحالات إيقاف الدعم، الأحدث أولًا.

| التاريخ | التغيير |
| --- | --- |
| 2026-09-07 | تصحيح توثيقي، وليس تغييرًا جذريًا: كان `nextCursor` منشورًا في مستند OpenAPI بنوع `string[]`؛ بينما كان شكل البيانات الفعلي على السلك دائمًا `string \| null`. المستند الآن يطابق ما كانت الواجهة ترسله دائمًا — لم يكن أي عميل يقرأ `nextCursor` كسلسلة قابلة لأن تكون `null` مخطئًا في أي وقت. |
