
# الأخطاء والترقيم الصفحي

تغطي هذه الصفحة أمرين يجب على كل عملية تكامل التعامل معهما: كيف يبدو الطلب الفاشل، وكيفية التنقل عبر الصفحات لنقاط النهاية التي تُرجع قوائم.

---

## غلاف الخطأ

عند فشل الطلب، تكون الاستجابة دائماً بتنسيق JSON بنفس الشكل — علامة `success` مضبوطة على `false`، ورسالة `error` مقروءة بشرياً، ورمز `error_code` رقمي يطابق حالة HTTP:

```json
{
  "success": false,
  "error": "Invalid cursor",
  "error_code": 400
}
```

نظراً لأن `success` و `error_code` موجودان دائماً، يمكنك التفرع بناءً عليهما دون فحص رموز حالة HTTP الأولية إذا كنت تفضل ذلك. الاستجابة الناجحة تحتوي دائماً على `success: true`.

---

## رموز الحالة

| Status | `error_code` | Meaning | What to do |
|---|---|---|---|
| `200` | — | Success | Read the response data. |
| `201` | — | Resource created | Save the returned ID (e.g. `campaign_id`, `contactId`). |
| `400` | `400` | Bad request | A parameter is missing or invalid. Read the `error` message and fix the request. |
| `401` | `401` | Unauthorized | Your API key is missing or invalid. Check the key and how you are sending it — see [Authentication](authentication.md). |
| `403` | `403` | Forbidden | Your plan does not include API access. See [API Access](../integrations/api-access.md) or contact [<span data-t="supportEmail">hi@youraiconnector.com</span>](mailto:hi@youraiconnector.com). |
| `404` | `404` | Not found | The resource (e.g. a contact, campaign, or task ID) does not exist on your account. |
| `409` | `409` | Conflict | The resource already exists — for example, creating a contact whose phone number is already on your account. |
| `429` | `429` | Rate limited | You have exceeded 300 requests per minute (or the wider 1,200/minute account ceiling). Back off and retry shortly. |
| `500` | `500` | Server error | Something went wrong on our side. Retry after a short wait; email [<span data-t="supportEmail">hi@youraiconnector.com</span>](mailto:hi@youraiconnector.com) if it persists. |

بعض الأمثلة على كيفية ظهور هذه الأخطاء في الواقع:

```json
{
  "success": false,
  "error_code": 401,
  "error": "Invalid API key"
}
```

```json
{
  "success": false,
  "error": "A contact with this phone number already exists",
  "error_code": 409
}
```

```json
{
  "success": false,
  "error_code": 429,
  "error": "Rate limit exceeded. Please try again later."
}
```

### التعامل الجيد مع الأخطاء

- **تحقق من `success` (أو رمز الحالة) قبل قراءة البيانات.** لا تفترض أن نص الاستجابة يحتوي على الحقل الذي تتوقعه.
- **أعد محاولة `429` و `500` مع فترة انتظار قصيرة** — انتظر، ثم حاول مرة أخرى. لا تعد محاولة `400` أو `401` أو `403` أو `404` أو `409`؛ ستستمر هذه في الفشل حتى تقوم بتغيير الطلب.
- **اقرأ رسالة `error`.** عادةً ما تخبرك بالضبط أي حقل هو غير الصحيح.

---

## الترقيم الصفحي

نقاط نهاية القوائم (مثل `GET /contacts` و `GET /campaigns` و `GET /tasks`) تُرجع النتائج في صفحات بحيث لا يضطر أي استدعاء واحد إلى تحميل حسابك بالكامل. يستخدم الترقيم الصفحي مؤشراً (cursor) غير شفاف.

تتحكم فيه معلمتان للاستعلام:

| المعلمة | الوصف |
|---|---|
| `limit` | عدد العناصر التي سيتم إرجاعها في كل صفحة. تختلف القيم الافتراضية حسب نقطة النهاية (غالباً 50)؛ الحد الأقصى هو **100**. |
| `cursor` | مؤشر غامض للصفحة التالية. اتركه فارغاً للصفحة الأولى. |

تتضمن كل صفحة حقل `next_cursor` في الاستجابة:

- إذا كانت `next_cursor` عبارة عن سلسلة نصية، فهذا يعني وجود المزيد من النتائج — قم بتمريرها كـ `cursor` في طلبك التالي.
- إذا كانت `next_cursor` تساوي `null`، فقد وصلت إلى الصفحة الأخيرة. توقف.

تبدو الصفحة الواحدة من جهات الاتصال كالتالي:

```json
{
  "success": true,
  "contacts": [
    { "id": "abc123", "first_name": "Jane", "phone_number": "+15551234567" },
    { "id": "def456", "first_name": "John", "phone_number": "+15557654321" }
  ],
  "next_cursor": "eyJsYXN0IjoiZGVmNDU2In0"
}
```

::: note
**ملاحظة:** المؤشر (cursor) غير شفاف — لا تحاول تحليله أو بنائه أو تعديله. لا تقم أبداً بإعادة تمرير قيمة `next_cursor` إلا إذا كنت قد تلقيتها من استجابة سابقة.
:::


---

## التنقل بين صفحات جميع جهات الاتصال

لجمع قائمة كاملة، ابدأ بدون مؤشر واستمر في إجراء الطلبات حتى تعود `next_cursor` بقيمة `null`.

**cURL**

يوضح هذا المثال كيفية تصفح أول صفحتين يدوياً. قم بتشغيل الطلب الأول، وانسخ `next_cursor` من استجابته إلى `CURSOR`، ثم قم بتشغيل الطلب الثاني. كرر العملية حتى تصبح `next_cursor` مساوية لـ `null`.

```bash
# First page
curl "https://api.youraiconnector.com/v1/contacts?apiKey=YOUR_API_KEY&limit=100"

# Next page — paste the next_cursor from the previous response
CURSOR="eyJsYXN0IjoiZGVmNDU2In0"
curl "https://api.youraiconnector.com/v1/contacts?apiKey=YOUR_API_KEY&limit=100&cursor=$CURSOR"
```

**JavaScript**

```javascript
async function getAllContacts() {
  const all = [];
  let cursor = null;

  do {
    const url = new URL("https://api.youraiconnector.com/v1/contacts");
    url.searchParams.set("limit", "100");
    if (cursor) url.searchParams.set("cursor", cursor);

    const res = await fetch(url, {
      headers: { "X-API-Key": "YOUR_API_KEY" },
    });
    const data = await res.json();

    if (!data.success) throw new Error(data.error);

    all.push(...data.contacts);
    cursor = data.next_cursor;
  } while (cursor);

  return all;
}
```

**Python**

```python
import requests

def get_all_contacts():
    all_contacts = []
    cursor = None

    while True:
        params = {"limit": 100}
        if cursor:
            params["cursor"] = cursor

        res = requests.get(
            "https://api.youraiconnector.com/v1/contacts",
            params=params,
            headers={"X-API-Key": "YOUR_API_KEY"},
        )
        data = res.json()

        if not data["success"]:
            raise Exception(data["error"])

        all_contacts.extend(data["contacts"])
        cursor = data["next_cursor"]

        if not cursor:
            break

    return all_contacts
```

تعمل الحلقة البرمجية نفسها مع أي نقطة نهاية (endpoint) تدعم الترقيم — فقط قم بتغيير المسار والحقل الذي تقرأ منه في الاستجابة (`campaigns`، و`tasks`، وهكذا).

---

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

- [المصادقة](authentication.md) — الطرق الأربع لإرسال مفتاحك.
- [جهات الاتصال](contacts.md) — نقاط نهاية جهات الاتصال الكاملة المستخدمة في الأمثلة أعلاه.
- [مفاتيح API](api-keys.md) — تحقق من استخدامك المباشر لحدود المعدل لتجنب `429`.
