# قائمة الحجوزات عبر API بالطلب GET /api/v1/bookings

> قائمة الحجوزات عبر API في مُجيب بحسب أيام الفرع وحالة الحجز، مقسّمة إلى صفحات، بوقتها المحلي وبتوقيت UTC، مع أمثلة بـ curl وJavaScript وPython وكل حقل.

قائمة الحجوزات عبر API يعيدها الطلب `GET /api/v1/bookings`: مواعيد نشاطك بترتيبها الزمني، مع وقت كل موعد المحلي في فرعه ولحظته بتوقيت UTC، وتختارها بالأيام وبالحالة. يحتاج الطلب إلى مفتاح بصلاحية `bookings.read`.

## ما الذي يعيده طلب قائمة الحجوزات؟

يعيد الطلب صفحة من الحجوزات في `data`، من الأقدم موعدًا إلى الأحدث، ومعها `nextCursor` للصفحة التالية، أو `null` إذا كانت هذه آخر صفحة.

- إذا لم ترسل `from` ولا `to`، فتأتي كل الحجوزات من أقدمها، الماضية والقادمة.
- تظهر المواعيد التي حجزها الوكيل أو فريقك في مُجيب. أما السجلات التاريخية المستوردة من سجل قديم فليست جزءًا من الواجهة.
- يظهر خيار «قراءة الحجوزات» عند إنشاء المفتاح فقط إذا كان نشاطك يستخدم المواعيد.

## ما المعاملات التي يقبلها الطلب؟

كل المعاملات اختيارية، وأي معامل غيرها يعود بالخطأ 400:

| المعامل | النوع | معناه |
| --- | --- | --- |
| `from` | تاريخ `YYYY-MM-DD` | أول يوم، ويدخل في النتائج |
| `to` | تاريخ `YYYY-MM-DD` | آخر يوم، ويدخل في النتائج |
| `status` | نص | حالة واحدة فقط (انظر الجدول التالي) |
| `limit` | عدد صحيح | عدد الحجوزات في الصفحة، 50 إذا لم ترسله وحتى 100 |
| `cursor` | نص | `nextCursor` من الصفحة السابقة. انظر [التقسيم إلى صفحات](https://docs.mujib.ai/developers/pagination/) |

- `from` و`to` أيام بتقويم كل فرع وبمنطقته الزمنية، لا بتوقيت UTC. حجز الساعة العاشرة صباحًا في فرعك يقع في يومه كما تراه في لوحة التحكم.
- يجب أن يكون التاريخ يومًا حقيقيًا: `2026-02-31` يُرفض بالخطأ 400، وكذلك أن يقع `from` بعد `to`.
- لحجوزات يوم واحد اجعل `from` و`to` اليوم نفسه.

قيم `status`، وما يقابلها في تقويم لوحة التحكم:

| القيمة | في لوحة التحكم |
| --- | --- |
| `requested` | «قيد الانتظار» |
| `confirmed` | «مؤكّد» |
| `cancelled` | «ملغى» |
| `completed` | «حضر» |
| `no_show` | «لم يحضر» |

## كيف أرسل الطلب؟

هذا المثال يطلب الحجوزات المؤكدة في شهر كامل:

```bash
curl "https://api.mujib.ai/api/v1/bookings?from=2026-11-01&to=2026-11-30&status=confirmed&limit=100" \
  -H "Authorization: Bearer $MUJIB_API_KEY"
```

```js
const url = new URL('https://api.mujib.ai/api/v1/bookings');
url.searchParams.set('from', '2026-11-01');
url.searchParams.set('to', '2026-11-30');
url.searchParams.set('status', 'confirmed');
url.searchParams.set('limit', '100');

const res = await fetch(url, {
  headers: { Authorization: `Bearer ${process.env.MUJIB_API_KEY}` },
});
const body = await res.json();
if (!res.ok) throw new Error(`${res.status} ${body.error.code}: ${body.error.message}`);
for (const b of body.data) console.log(b.localTime, b.branch?.name, b.customer.name);
```

```python
import os
import requests

res = requests.get(
    "https://api.mujib.ai/api/v1/bookings",
    params={"from": "2026-11-01", "to": "2026-11-30", "status": "confirmed", "limit": 100},
    headers={"Authorization": f"Bearer {os.environ['MUJIB_API_KEY']}"},
    timeout=30,
)
body = res.json()
if not res.ok:
    raise RuntimeError(f"{res.status_code} {body['error']['code']}: {body['error']['message']}")
for b in body["data"]:
    print(b["localTime"], (b["branch"] or {}).get("name"), b["customer"]["name"])
```

لقراءة كل الصفحات حتى النهاية، استخدم الدالة في [التقسيم إلى صفحات](https://docs.mujib.ai/developers/pagination/).

## كيف يبدو الرد؟

رد ناجح بالرمز 200. البيانات مثال مختلَق لفرع في عمّان:

```json
{
  "data": [
    {
      "id": "3f0c9a52-7d1e-4b8a-9c41-2e6f8a1b0d77",
      "status": "confirmed",
      "source": "agent",
      "service": "consultation",
      "startsAt": "2026-11-12T07:30:00Z",
      "localTime": "2026-11-12T10:30:00",
      "timezone": "Asia/Amman",
      "durationMinutes": 30,
      "branch": { "id": "e7f6a5b4-3c2d-4e1f-9a8b-7c6d5e4f3a21", "name": "الفرع الرئيسي" },
      "specialist": "ليلى",
      "customer": { "contactId": "5d8f2a61-0c4e-4b7a-9f13-6e2b8c0d4a57", "name": "سارة", "phone": "962790000000" },
      "createdAt": "2026-11-04T18:22:09.117Z"
    },
    {
      "id": "c2a7e915-6f3b-4d80-b4e1-7a9d5c0f2b36",
      "status": "requested",
      "source": "staff",
      "service": "followup",
      "startsAt": "2026-11-12T09:00:00Z",
      "localTime": "2026-11-12T12:00:00",
      "timezone": "Asia/Amman",
      "durationMinutes": null,
      "branch": { "id": "e7f6a5b4-3c2d-4e1f-9a8b-7c6d5e4f3a21", "name": "الفرع الرئيسي" },
      "specialist": null,
      "customer": { "contactId": null, "name": "أحمد", "phone": "0790000000" },
      "createdAt": "2026-11-05T08:01:44.360Z"
    }
  ],
  "nextCursor": "MjAyNi0xMS0xMlQxMjowMDowMHxjMmE3ZTkxNS02ZjNiLTRkODAtYjRlMS03YTlkNWMwZjJiMzY"
}
```

كل حجز فيه هذه الحقول دائمًا، والحقل الذي لا قيمة له يأتي `null`:

| الحقل | النوع | معناه |
| --- | --- | --- |
| `id` | نص | معرّف الحجز الثابت، تستخدمه في [قراءة حجز واحد](https://docs.mujib.ai/developers/api-booking/) |
| `status` | نص | حالة الحجز (انظر الجدول السابق) |
| `source` | نص | من أنشأ الحجز: `agent` الوكيل في محادثة، أو `staff` فريقك من لوحة التحكم |
| `service` | نص | معرّف نوع الزيارة كما عرّفه نشاطك، مثل `consultation`، لا اسمه المعروض. انظر [أنواع الزيارات](https://docs.mujib.ai/bookings/visit-types/) |
| `startsAt` | لحظة UTC | بداية الموعد بتوقيت UTC، بالصيغة `YYYY-MM-DDTHH:MM:SSZ` |
| `localTime` | نص | بداية الموعد بساعة الفرع، دون فرق توقيت، بالصيغة `YYYY-MM-DDTHH:MM:SS`. هذا هو الوقت الذي أُعطي للعميل |
| `timezone` | نص | المنطقة الزمنية لـ `localTime`، مثل `Asia/Amman`: منطقة الفرع، وإلا منطقة نشاطك |
| `durationMinutes` | عدد صحيح أو `null` | مدة الموعد بالدقائق، أو `null` إذا انطبقت المدة الافتراضية لنشاطك |
| `branch` | كائن أو `null` | الفرع بالحقلين `id` و`name`، أو `null` إذا لم يكن للحجز فرع |
| `specialist` | نص أو `null` | اسم الأخصائي، أو `null` إذا لم يُحدَّد |
| `customer.contactId` | نص أو `null` | معرّف العميل لـ [قراءة عميل واحد](https://docs.mujib.ai/developers/api-contact/)، أو `null` لحجز بلا عميل مسجّل |
| `customer.name` | نص أو `null` | الاسم المكتوب على الحجز، وإلا اسم العميل |
| `customer.phone` | نص أو `null` | الرقم المكتوب على الحجز، وإلا رقم العميل |
| `createdAt` | لحظة UTC | متى أُنشئ الحجز |

## ما الأخطاء المحتملة؟

| HTTP | `code` | السبب |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | معامل غير معروف، أو تاريخ بغير الصيغة `YYYY-MM-DD` أو ليس يومًا حقيقيًا، أو `from` بعد `to`، أو `status` غير معروف، أو `limit` خارج المسموح، أو مؤشر لا يُقرأ |
| 401 | `UNAUTHORIZED` | لا مفتاح، أو مفتاح غير صالح |
| 403 | `FORBIDDEN` | المفتاح لا يحمل `bookings.read` |
| 429 | `RATE_LIMITED` | تجاوزت حدود الطلبات |
| 500 | `INTERNAL` | خطأ غير متوقع في الخادم |

التفاصيل في [الأخطاء وحدود الطلبات](https://docs.mujib.ai/developers/errors-limits/).

## الأسئلة الشائعة

### هل from وto بتوقيت UTC؟

لا. هما أيام بتقويم كل فرع وبمنطقته الزمنية، ويشملان اليومين نفسيهما. أما startsAt في الرد فلحظة بتوقيت UTC.

### هل تظهر الحجوزات القديمة التي استوردتها من سجل سابق؟

لا. السجلات التاريخية المستوردة من سجل قديم ليست جزءًا من الواجهة. تظهر المواعيد المحجوزة في مُجيب.

### ماذا يعني durationMinutes بقيمة null؟

أن الحجز لا يحمل مدة خاصة به، فتنطبق عليه المدة الافتراضية التي ضبطها نشاطك.

### هل أعرف من القائمة الحجوزات التي تغيّرت حديثًا؟

لا يوجد معامل لذلك. اقرأ نافذة الأيام التي تهمك من جديد، أو استخدم Webhooks ليصلك كل حجز جديد أو ملغى لحظة حدوثه.

---

المصدر: https://docs.mujib.ai/developers/api-bookings/ · آخر تحديث: 2026-11-04
