# الرسائل

أرسل الرسائل واقرأ حالتها.

كل ما ترسله يمر عبر نقطة واحدة هي [`POST /messages`](/docs/reference/messages#sendMessage). تختار `type`، وتضع المحتوى تحت مفتاح بالاسم نفسه، ثم تتابع ما يحدث عبر أحداث `message.*`.

## نافذة الـ24 ساعة {#window}

يحدد واتساب ما يمكنك إرساله بقاعدة واحدة:

- **خلال 24 ساعة** من آخر رسالة للعميل تكون المحادثة مفتوحة: أرسل أي نوع وبنص حر.
- **في غير ذلك** لا يُسلَّم إلا **قالب** معتمد. أي نوع آخر يُرفض بالخطأ [`window_closed`](/docs/errors#window_closed) قبل أن يصل إلى واتساب، فلا تُحاسب أبدًا على رسالة لم يكن بالإمكان تسليمها.

إذا رد العميل على قالب تُفتح النافذة من جديد. ويخبرك [`GET /conversations/{id}`](/docs/reference/conversations#getConversation) متى تُغلق (`reply_window_expires_at`).

:::tip
رد بسرعة على العملاء الذين يبدؤون بالكتابة، واحتفظ بالقوالب لبدء المحادثات: تحديثات الطلبات والتذكيرات ورموز التحقق.
:::

## النص {#text}

```json
{ "to": "+966501234567", "type": "text", "text": { "body": "أهلًا سارة! طلبك جاهز 🎉", "preview_url": true } }
```

حتى 4096 حرفًا. يعرض `preview_url` معاينة لأول رابط في النص.

## الوسائط {#media}

الصور والفيديو والصوت والمستندات والملصقات تأتي من رابط `https://` عام يحمّله واتساب، أو من ملف رفعته مرة واحدة عبر [`POST /media`](/docs/reference/media#uploadMedia):

```json
{ "to": "+966501234567", "type": "document", "document": { "media_id": "med_381", "filename": "invoice-10482.pdf", "caption": "فاتورتك" } }
```

| النوع | الصيغ | الحد الأقصى | تعليق |
|---|---|---|---|
| `image` | JPEG وPNG | 5 ميجابايت | نعم |
| `video` | MP4 و3GPP | 16 ميجابايت | نعم |
| `audio` | AAC وMP4 وMPEG وAMR وOGG/Opus | 16 ميجابايت | لا |
| `document` | أي ملف | 100 ميجابايت | نعم، مع `filename` |
| `sticker` | WebP بمقاس 512×512 | 100 كيلوبايت (500 للمتحرك) | لا |

يُفحص الملف المرفوع وفق هذه الحدود عند رفعه، فلا يصل ملف سيرفضه واتساب إلى مرحلة الإرسال أصلًا.

## الأزرار والقوائم والروابط {#interactive}

يجيب العميل عن رسائل `interactive` بلمسة. يعود اختياره إليك كحدث `message.received` من نوع `interactive` يحمل `id` الذي حددته، فاعتمد عليه في منطقك.

```json
{
  "to": "+966501234567",
  "type": "interactive",
  "interactive": {
    "type": "button",
    "body": "هل تؤكد موعدك غدًا الساعة 4 عصرًا؟",
    "buttons": [
      { "id": "confirm_10482", "title": "تأكيد" },
      { "id": "reschedule_10482", "title": "تغيير الموعد" }
    ]
  }
}
```

| `interactive.type` | ما يراه العميل | الحدود |
|---|---|---|
| `button` | حتى 3 أزرار رد | العنوان 20 حرفًا، والمعرّف 256 |
| `list` | زر يفتح حتى 10 خيارات موزعة على أقسام | 10 صفوف إجمالًا، عنوان الصف 24 حرفًا والوصف 72 |
| `cta_url` | زر واحد يفتح رابطًا | العنوان 20 حرفًا، و`https://` فقط |
| `location_request` | زر لمشاركة موقعه | النص فقط |

كل الأنواع تأخذ `body`، وكلها عدا `location_request` تقبل `footer` و`header` اختياريين (نصًا، أو في `cta_url` رابط صورة أو فيديو أو مستند).

## الموقع وبطاقات الاتصال والتفاعلات {#more}

- `location`: القيمتان `latitude` و`longitude`، واختياريًا `name` و`address`.
- `contacts`: قائمة بطاقات، تحتاج كل منها إلى `name.formatted_name`، والرقم الذي يحمل `wa_id` يُظهر زر "مراسلة".
- `reaction`: القيمة `{"message_id": "imsg_…", "emoji": "👍"}` تتفاعل مع رسالة، و`emoji` الفارغ يزيل التفاعل. التفاعلات مجانية ولا تُحتسب كرسائل.

## الردود وإشعارات القراءة والكتابة {#replies}

- أرسل `reply_to` (معرّف `msg_…` أو `imsg_…` أو معرّف واتساب) لتقتبس رسالة العميل في ردك.
- يُظهر [`POST /messages/{id}/read`](/docs/reference/messages#markMessageRead) للعميل علامتي القراءة الزرقاوين. أضف `"typing_indicator": true` لتظهر له عبارة "يكتب…" بينما تجهّز الرد (حتى 25 ثانية أو حتى ترد).

## ما يحدث بعد الإرسال {#lifecycle}

تعود الاستجابة فور قبول واتساب للرسالة بحالة `status: accepted`، ثم تتوالى الأحداث:

| الحدث | المعنى |
|---|---|
| `message.sent` | أرسلها واتساب |
| `message.delivered` | وصلت إلى هاتف العميل |
| `message.read` | فتحها العميل (إن كان يشارك إشعارات القراءة) |
| `message.failed` | تعذّر تسليمها، ويوضح `error.code` سبب واتساب |

ضع معرّفك الخاص في `reference` (رقم طلب أو رقم تذكرة): يعود في الاستجابة وفي كل حدث، فلا تحتاج إلى جدول ربط.

## إنستغرام وماسنجر {#social}

النقطة نفسها ترد على إنستغرام وماسنجر: حدّد `channel` وأرسل `to` بمعرّف العميل من حقل `from` في رسالته. تقبل هاتان القناتان النص والصورة والفيديو والصوت والمستند، خلال 24 ساعة من آخر رسالة للعميل فقط، ولا قوالب فيهما: بعد إغلاق النافذة لا يمكنك الكتابة إلا بعد أن يكتب العميل.

```json
{ "channel": "instagram", "to": "17841400000000000", "type": "text", "text": { "body": "شكرًا لتواصلك! المقاس متوفر ✨" } }
```

## أي رقم يُرسل {#sender}

إن لم ترسل `from` تخرج الرسالة من الرقم الذي راسله العميل آخر مرة، وإلا من رقمك الافتراضي. للاختيار أرسل `from` بمعرّف رقم من [`GET /numbers`](/docs/reference/numbers#listNumbers)، الذي يوضح أيضًا هل يستطيع كل رقم الإرسال الآن.

## عرض الرسائل المرسلة عبر الواجهة

```
GET https://api.saei.automize.sa/v1/messages
```

الأحدث أولًا. مفاتيح التشغيل تعرض الرسائل المرسلة عبر الواجهة، ومفاتيح الاختبار تعرض رسائل وضع الاختبار (المرسلة والواردة المحاكاة).

- الصلاحية: messages:read
- يعمل في وضع الاختبار

### المعاملات

- `limit` (query): عدد العناصر المطلوبة، من 1 إلى 100.
- `cursor` (query): قيمة `next_cursor` من الصفحة السابقة.
- `reference` (query): فقط الرسائل التي أرسلتها بهذا `reference`.
- `to` (query): فقط الرسائل المرسلة إلى هذا الرقم (E.164).

### الاستجابة 200

صفحة من الرسائل.

```json
{
  "object": "list",
  "data": [
    {
      "id": "msg_48213",
      "object": "message",
      "livemode": false,
      "direction": "outbound",
      "channel": "whatsapp",
      "from": "+966112345678",
      "to": "+966501234567",
      "type": "text",
      "text": {
        "body": "string"
      },
      "template": {
        "name": "string",
        "language": "string",
        "variables": {},
        "body": "string"
      },
      "image": {},
      "video": {},
      "audio": {},
      "document": {},
      "sticker": {},
      "location": {},
      "contacts": [],
      "interactive": {},
      "reaction": {},
      "status": "accepted",
      "error": {
        "code": "string",
        "title": "string",
        "message": "string"
      },
      "reference": "string",
      "conversation_id": "string",
      "provider_message_id": "string",
      "contact": {
        "name": "string"
      },
      "context": {
        "provider_message_id": "string"
      },
      "created_at": "2026-10-01T09:30:00Z",
      "updated_at": "2026-10-01T09:30:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": "string"
}
```

### الاستجابة 401

مفتاح API مفقود أو غير صالح أو ملغى أو منتهي الصلاحية.

```json
{
  "error": {
    "type": "authentication_error",
    "code": "api_key_invalid",
    "message": "The API key is not valid.",
    "doc_url": "https://app.example.com/docs/errors#api_key_invalid",
    "request_id": "req_01j9x3k2m4n5p6q7r8s9t0v1w2"
  }
}
```

### الاستجابة 403

المفتاح ينقصه صلاحية، أو الباقة لا تشمل الوصول للواجهة، أو الطلب غير متاح في هذا الوضع.

```json
{
  "error": {
    "type": "permission_error",
    "code": "insufficient_scope",
    "message": "This API key does not have the \"messages:send\" scope. Create a key with it in Developers > API keys.",
    "required_scope": "messages:send",
    "doc_url": "https://app.example.com/docs/errors#insufficient_scope",
    "request_id": "req_01j9x3k2m4n5p6q7r8s9t0v1w2"
  }
}
```

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

`parameter_invalid`, `rate_limited`

## إرسال رسالة

```
POST https://api.saei.automize.sa/v1/messages
```

نقطة واحدة لكل أنواع الرسائل: حدّد `type` وضع المحتوى تحت مفتاح بنفس الاسم: `text` أو `template` أو `image` أو `video` أو `audio` أو `document` أو `sticker` أو `location` أو `contacts` أو `interactive` (أزرار رد، قوائم، أزرار روابط، طلب موقع) أو `reaction`.

- **خلال 24 ساعة** من آخر رسالة أرسلها العميل يمكنك إرسال أي نوع.
- **خارج هذه النافذة** (أو لبدء محادثة) لا يُسلَّم إلا `template` معتمد. أي نوع آخر يُرجع `window_closed`.
- **إنستغرام وماسنجر** (`channel`) للردود فقط: نص ووسائط خلال الـ24 ساعة.

تصلك الاستجابة فور قبول القناة للرسالة (`status: accepted`). أما تحديثات التسليم والقراءة فتصلك كأحداث ويب هوك `message.*`. مع مفتاح اختبار تكون الرسالة محاكاة ولا تصل إلى واتساب أبدًا.


- الصلاحية: messages:send
- محاكاة في وضع الاختبار
- يقبل Idempotency-Key

### المعاملات

- `Idempotency-Key` (header): أي نص فريد (يُفضّل UUID). إعادة الطلب بنفس المفتاح ونفس الجسم تُرجع الاستجابة الأولى بدل التنفيذ مرتين. يُحفظ لمدة 24 ساعة.

### الطلب: رد نصي

```json
{
  "to": "+966501234567",
  "type": "text",
  "text": {
    "body": "أهلًا سارة! طلبك جاهز للاستلام 🎉"
  },
  "reference": "order-10482"
}
```

### الطلب: قالب معتمد

```json
{
  "to": "+966501234567",
  "type": "template",
  "template": {
    "name": "order_update",
    "language": "ar",
    "variables": {
      "body": [
        "سارة",
        "#10482"
      ]
    }
  },
  "reference": "order-10482"
}
```

### الطلب: الرد على رسالة عميل

```json
{
  "to": "+966501234567",
  "type": "text",
  "text": {
    "body": "تم، سنتواصل معك خلال دقائق."
  },
  "reply_to": "imsg_88213"
}
```

### الطلب: فاتورة PDF

```json
{
  "to": "+966501234567",
  "type": "document",
  "document": {
    "link": "https://files.example.com/invoices/10482.pdf",
    "filename": "invoice-10482.pdf",
    "caption": "فاتورة طلبك رقم 10482"
  }
}
```

### الطلب: صورة مرفوعة

```json
{
  "to": "+966501234567",
  "type": "image",
  "image": {
    "media_id": "med_381",
    "caption": "هذه صورة منتجك قبل الشحن 📦"
  }
}
```

### الطلب: فيديو برابط

```json
{
  "to": "+966501234567",
  "type": "video",
  "video": {
    "link": "https://files.example.com/guides/setup.mp4",
    "caption": "طريقة تركيب الجهاز في دقيقة"
  }
}
```

### الطلب: رسالة صوتية

```json
{
  "to": "+966501234567",
  "type": "audio",
  "audio": {
    "media_id": "med_412"
  }
}
```

### الطلب: ملصق

```json
{
  "to": "+966501234567",
  "type": "sticker",
  "sticker": {
    "link": "https://files.example.com/stickers/thanks.webp"
  }
}
```

### الطلب: بطاقة اتصال

```json
{
  "to": "+966501234567",
  "type": "contacts",
  "contacts": [
    {
      "name": {
        "formatted_name": "خدمة العملاء",
        "first_name": "خدمة العملاء"
      },
      "phones": [
        {
          "phone": "+966112345678",
          "type": "WORK",
          "wa_id": "966112345678"
        }
      ],
      "org": {
        "company": "متجر النخبة"
      }
    }
  ]
}
```

### الطلب: أزرار رد

```json
{
  "to": "+966501234567",
  "type": "interactive",
  "interactive": {
    "type": "button",
    "body": "هل تؤكد موعدك غدًا الساعة 4 عصرًا؟",
    "footer": "عيادة النخبة",
    "buttons": [
      {
        "id": "confirm_10482",
        "title": "تأكيد"
      },
      {
        "id": "reschedule_10482",
        "title": "تغيير الموعد"
      }
    ]
  }
}
```

### الطلب: قائمة خيارات

```json
{
  "to": "+966501234567",
  "type": "interactive",
  "interactive": {
    "type": "list",
    "body": "اختر الفرع الأقرب لك",
    "button": "الفروع",
    "sections": [
      {
        "title": "الرياض",
        "rows": [
          {
            "id": "br_olaya",
            "title": "فرع العليا",
            "description": "يوميًا 9 ص – 11 م"
          },
          {
            "id": "br_malqa",
            "title": "فرع الملقا"
          }
        ]
      },
      {
        "title": "جدة",
        "rows": [
          {
            "id": "br_tahlia",
            "title": "فرع التحلية"
          }
        ]
      }
    ]
  }
}
```

### الطلب: زر رابط

```json
{
  "to": "+966501234567",
  "type": "interactive",
  "interactive": {
    "type": "cta_url",
    "body": "طلبك في الطريق. تابع الشحنة لحظة بلحظة.",
    "display_text": "تتبّع الطلب",
    "url": "https://shop.example.com/track/10482"
  }
}
```

### الطلب: موقع على الخريطة

```json
{
  "to": "+966501234567",
  "type": "location",
  "location": {
    "latitude": 24.6958,
    "longitude": 46.6853,
    "name": "فرع العليا",
    "address": "طريق العليا، الرياض"
  }
}
```

### الطلب: تفاعل مع رسالة

```json
{
  "to": "+966501234567",
  "type": "reaction",
  "reaction": {
    "message_id": "imsg_88213",
    "emoji": "👍"
  }
}
```

### الطلب: رد على إنستغرام

```json
{
  "channel": "instagram",
  "to": "17841400000000000",
  "type": "text",
  "text": {
    "body": "شكرًا لتواصلك! المقاس متوفر ✨"
  }
}
```

### الاستجابة 202

قبلها واتساب (أو المحاكي في وضع الاختبار).

```json
{
  "id": "msg_48213",
  "object": "message",
  "livemode": true,
  "direction": "outbound",
  "channel": "whatsapp",
  "from": "+966112345678",
  "to": "+966501234567",
  "type": "text",
  "text": {
    "body": "أهلًا سارة! طلبك جاهز للاستلام 🎉"
  },
  "status": "accepted",
  "error": null,
  "reference": "order-10482",
  "conversation_id": "conv_311",
  "provider_message_id": "wamid.HBgMOTY2NTAxMjM0NTY3FQIAERgSMEM4",
  "created_at": "2026-10-01T09:30:00Z",
  "updated_at": "2026-10-01T09:30:00Z"
}
```

### الاستجابة 401

مفتاح API مفقود أو غير صالح أو ملغى أو منتهي الصلاحية.

```json
{
  "error": {
    "type": "authentication_error",
    "code": "api_key_invalid",
    "message": "The API key is not valid.",
    "doc_url": "https://app.example.com/docs/errors#api_key_invalid",
    "request_id": "req_01j9x3k2m4n5p6q7r8s9t0v1w2"
  }
}
```

### الاستجابة 403

المفتاح ينقصه صلاحية، أو الباقة لا تشمل الوصول للواجهة، أو الطلب غير متاح في هذا الوضع.

```json
{
  "error": {
    "type": "permission_error",
    "code": "insufficient_scope",
    "message": "This API key does not have the \"messages:send\" scope. Create a key with it in Developers > API keys.",
    "required_scope": "messages:send",
    "doc_url": "https://app.example.com/docs/errors#insufficient_scope",
    "request_id": "req_01j9x3k2m4n5p6q7r8s9t0v1w2"
  }
}
```

### الاستجابة 409

المستلِم لم يوافق على الاستقبال، أو ما زال طلب سابق بنفس Idempotency-Key قيد التنفيذ.

```json
{
  "error": {
    "type": "authentication_error",
    "code": "string",
    "message": "string",
    "param": "string",
    "doc_url": "string",
    "request_id": "string",
    "details": [
      {
        "param": "string",
        "code": "string",
        "message": "string"
      }
    ],
    "channel_error": {
      "provider": "string",
      "code": 0,
      "subcode": 0,
      "title": "string",
      "message": "string"
    }
  }
}
```

### الاستجابة 422

لا يمكن الإرسال كما طُلب، مثل انتهاء نافذة الـ24 ساعة أو قالب غير معتمد.

```json
{
  "error": {
    "type": "invalid_request_error",
    "code": "window_closed",
    "message": "The 24-hour customer service window is closed. Send an approved template instead.",
    "param": "type",
    "last_inbound_at": "2026-09-29T08:12:00+00:00",
    "window_expires_at": "2026-09-30T08:12:00+00:00",
    "doc_url": "https://app.example.com/docs/errors#window_closed",
    "request_id": "req_01j9x3k2m4n5p6q7r8s9t0v1w2"
  }
}
```

### الاستجابة 429

طلبات كثيرة جدًا. انتظر عدد الثواني الموجود في `Retry-After`.

```json
{
  "error": {
    "type": "authentication_error",
    "code": "string",
    "message": "string",
    "param": "string",
    "doc_url": "string",
    "request_id": "string",
    "details": [
      {
        "param": "string",
        "code": "string",
        "message": "string"
      }
    ],
    "channel_error": {
      "provider": "string",
      "code": 0,
      "subcode": 0,
      "title": "string",
      "message": "string"
    }
  }
}
```

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

`parameter_missing`, `parameter_invalid`, `resource_missing`, `window_closed`, `template_not_found`, `template_not_approved`, `template_variables_mismatch`, `recipient_not_consented`, `sender_not_configured`, `sender_not_sendable`, `channel_not_connected`, `channel_error`, `test_mode_unsupported`, `quota_exceeded`, `subscription_inactive`, `api_access_not_in_plan`, `idempotency_key_reused`, `idempotency_in_progress`, `send_outcome_unknown`, `platform_paused`, `rate_limited`

## جلب رسالة

```
GET https://api.saei.automize.sa/v1/messages/{id}
```

الرسالة وحالتها الحالية. يعمل مع الرسائل التي أرسلتها (`msg_…`) ورسائل العملاء الواردة في أحداث الويب هوك (`imsg_…`).

- الصلاحية: messages:read
- يعمل في وضع الاختبار

### المعاملات

- `id` (path, مطلوب): معرّف العنصر.

### الاستجابة 200

الرسالة.

```json
{
  "id": "msg_48213",
  "object": "message",
  "livemode": false,
  "direction": "outbound",
  "channel": "whatsapp",
  "from": "+966112345678",
  "to": "+966501234567",
  "type": "text",
  "text": {
    "body": "string"
  },
  "template": {
    "name": "string",
    "language": "string",
    "variables": {},
    "body": "string"
  },
  "image": {},
  "video": {},
  "audio": {},
  "document": {},
  "sticker": {},
  "location": {},
  "contacts": [],
  "interactive": {},
  "reaction": {},
  "status": "accepted",
  "error": {
    "code": "string",
    "title": "string",
    "message": "string"
  },
  "reference": "string",
  "conversation_id": "string",
  "provider_message_id": "string",
  "contact": {
    "name": "string"
  },
  "context": {
    "provider_message_id": "string"
  },
  "created_at": "2026-10-01T09:30:00Z",
  "updated_at": "2026-10-01T09:30:00Z"
}
```

### الاستجابة 401

مفتاح API مفقود أو غير صالح أو ملغى أو منتهي الصلاحية.

```json
{
  "error": {
    "type": "authentication_error",
    "code": "api_key_invalid",
    "message": "The API key is not valid.",
    "doc_url": "https://app.example.com/docs/errors#api_key_invalid",
    "request_id": "req_01j9x3k2m4n5p6q7r8s9t0v1w2"
  }
}
```

### الاستجابة 403

المفتاح ينقصه صلاحية، أو الباقة لا تشمل الوصول للواجهة، أو الطلب غير متاح في هذا الوضع.

```json
{
  "error": {
    "type": "permission_error",
    "code": "insufficient_scope",
    "message": "This API key does not have the \"messages:send\" scope. Create a key with it in Developers > API keys.",
    "required_scope": "messages:send",
    "doc_url": "https://app.example.com/docs/errors#insufficient_scope",
    "request_id": "req_01j9x3k2m4n5p6q7r8s9t0v1w2"
  }
}
```

### الاستجابة 404

لا يوجد عنصر بهذا المعرّف في مساحة العمل هذه (وفي هذا الوضع).

```json
{
  "error": {
    "type": "invalid_request_error",
    "code": "resource_missing",
    "message": "No such message: msg_999.",
    "param": "id",
    "doc_url": "https://app.example.com/docs/errors#resource_missing",
    "request_id": "req_01j9x3k2m4n5p6q7r8s9t0v1w2"
  }
}
```

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

`resource_missing`, `rate_limited`

## تعليم رسالة العميل كمقروءة

```
POST https://api.saei.automize.sa/v1/messages/{id}/read
```

تظهر للعميل علامتا القراءة الزرقاوان على رسالته (وعلى كل ما أرسله قبلها). أضف `typing_indicator: true` لتظهر له أيضًا عبارة "يكتب…" بينما تجهّز الرد، وتستمر حتى 25 ثانية أو حتى ترد.

تعمل على رسائل واتساب التي استقبلتها (`imsg_…` من أحداث `message.received`).


- الصلاحية: messages:send
- محاكاة في وضع الاختبار

### المعاملات

- `id` (path, مطلوب): معرّف العنصر.

### الطلب

```json
{
  "typing_indicator": true
}
```

### الاستجابة 200

يرى العميل الآن رسالته مقروءة.

```json
{
  "object": "read_receipt",
  "message_id": "imsg_88213",
  "livemode": true,
  "typing_indicator": true
}
```

### الاستجابة 401

مفتاح API مفقود أو غير صالح أو ملغى أو منتهي الصلاحية.

```json
{
  "error": {
    "type": "authentication_error",
    "code": "api_key_invalid",
    "message": "The API key is not valid.",
    "doc_url": "https://app.example.com/docs/errors#api_key_invalid",
    "request_id": "req_01j9x3k2m4n5p6q7r8s9t0v1w2"
  }
}
```

### الاستجابة 403

المفتاح ينقصه صلاحية، أو الباقة لا تشمل الوصول للواجهة، أو الطلب غير متاح في هذا الوضع.

```json
{
  "error": {
    "type": "permission_error",
    "code": "insufficient_scope",
    "message": "This API key does not have the \"messages:send\" scope. Create a key with it in Developers > API keys.",
    "required_scope": "messages:send",
    "doc_url": "https://app.example.com/docs/errors#insufficient_scope",
    "request_id": "req_01j9x3k2m4n5p6q7r8s9t0v1w2"
  }
}
```

### الاستجابة 404

لا يوجد عنصر بهذا المعرّف في مساحة العمل هذه (وفي هذا الوضع).

```json
{
  "error": {
    "type": "invalid_request_error",
    "code": "resource_missing",
    "message": "No such message: msg_999.",
    "param": "id",
    "doc_url": "https://app.example.com/docs/errors#resource_missing",
    "request_id": "req_01j9x3k2m4n5p6q7r8s9t0v1w2"
  }
}
```

### الاستجابة 422

الطلب غير صالح. يوضّح `details` كل حقل به خطأ.

```json
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_missing",
    "message": "The to field is required.",
    "param": "to",
    "details": [
      {
        "param": "to",
        "code": "parameter_missing",
        "message": "The to field is required."
      }
    ],
    "doc_url": "https://app.example.com/docs/errors#parameter_missing",
    "request_id": "req_01j9x3k2m4n5p6q7r8s9t0v1w2"
  }
}
```

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

`resource_missing`, `sender_not_configured`, `channel_error`, `rate_limited`
