# البدء السريع مع REST API في Shager: من مفتاح جديد إلى منشور متتبَّع على 40 حسابًا في سبعة استدعاءات

_2026-09-19 · جولة عملية في REST API الخاص بـ Shager بـ curl وTypeScript: المصادقة، ومساحات العمل، والحسابات، والوسائط، ومسودات لكل حساب، والجدولة، والحالة، والنقرات._

يعمل REST API الخاص بـ Shager على العنوان `https://app.shager.ai/api/v1`، ويصادق عبر `Authorization: Bearer shgr_live_...`، ويُعيد كل نتيجة بالشكل `{ "data": ... }` وكل خطأ بالشكل `{ "error": { "code", "message" } }`. تتكون عملية توزيع كاملة من سبعة استدعاءات: التحقق من المفتاح، واختيار مساحة عمل، وسرد حساباتها، ورفع الوسائط، وإنشاء مسودة بنص لكل حساب، وجدولتها، ثم قراءة الحالة والنقرات. والمواصفة المقروءة آليًا هي [مستند OpenAPI 3.1](https://app.shager.ai/api/v1/openapi.json).

كل ما يلي يعمل كما هو بمجرد ضبط متغيرَي بيئة. والعمليات نفسها متاحة أدواتٍ في MCP بالأسماء ذاتها، فما تتعلمه هنا ينطبق أيضًا على Claude Code وCodex وCursor.

## ماذا تحتاج قبل الاستدعاء الأول؟

مفتاحًا. إما أن ينشئه شخص على https://app.shager.ai/dashboard/agents بالصلاحيات التي تحتاج إليها، وإما أن ينشئ وكيلك بيئة اختبار عبر [التسجيل الذاتي](/ar/blog/agent-self-signup-and-claim). وتعمل الصلاحيات على النحو التالي:

| الصلاحية | ما تسمح به |
|---|---|
| `read` | `whoami`، وسرد مساحات العمل والحسابات والمجموعات والمنشورات، وقراءة منشور، والتحليلات |
| `write` | إنشاء مساحات العمل والمجموعات والوسائط ومسودات المنشورات وروابط الربط وطلبات الموافقة، والإلغاء |
| `publish` | الجدولة، بما في ذلك `create_post` مع `schedule_at` |

```bash
export SHAGER_API_KEY="shgr_live_your_key_here"
export API="https://app.shager.ai/api/v1"
```

## الاستدعاء 1: من أنا؟

```bash
curl -s "$API/me" -H "Authorization: Bearer $SHAGER_API_KEY"
```

```json
{ "data": { "organization_id": "...", "organization": "Northwind Agency", "sandbox": false, "scopes": ["read", "write"] } }
```

إذا كانت قيمة `sandbox` هي true، فالجدولة وروابط الربط محظورة إلى أن يتولى إنسان ملكية المفتاح. وإذا غابت `publish` عن `scopes`، فبإمكانك بناء مسودات لكن لا يمكنك جدولتها. معرفة ذلك مسبقًا تجنّبك لاحقًا خطأ 403 محيّرًا.

## الاستدعاء 2: اختر مساحة عمل أو أنشئ واحدة

مساحة العمل تمثل عادةً عميلًا واحدًا أو علامة تجارية واحدة.

```bash
curl -s "$API/workspaces" -H "Authorization: Bearer $SHAGER_API_KEY"

curl -s -X POST "$API/workspaces" \
  -H "Authorization: Bearer $SHAGER_API_KEY" -H "Content-Type: application/json" \
  -d '{"name": "Summit Physio", "timezone": "Europe/London", "approval_required": true}'
```

اضبط دائمًا `timezone` (اسمًا من قاعدة IANA) عند الإنشاء. تُخزَّن أوقات الجدولة مع فارقها الزمني، والمنطقة الزمنية لمساحة العمل هي ما يعتمده Shager لعرضها على البشر. وتعني `approval_required: true` أن المنشورات يجب أن يوافق عليها العميل قبل جدولتها، وهو إعداد افتراضي جيد للعملاء الجدد.

صدّر المعرّف من الاستجابة كي تعمل الأوامر التالية:

```bash
export WS="the_workspace_id"
```

## الاستدعاء 3: اسرد الحسابات والمجموعات

```bash
curl -s "$API/workspaces/$WS/channels" -H "Authorization: Bearer $SHAGER_API_KEY"
curl -s "$API/workspaces/$WS/groups" -H "Authorization: Bearer $SHAGER_API_KEY"
```

يعود كل حساب مع `id` و`network` و`name` و`handle` و`status`، والصيغ التي يدعمها في `formats`، و`connected_by_client`. وتُعيد المجموعات `id` و`name` و`channel_ids`. المجموعات هي طريقتك لمخاطبة أربعين حسابًا دون سرد أربعين معرّفًا؛ مرّر `group_ids` إلى `create_post` فيُضمَّن كل حساب نشط في المجموعة.

إن لم تكن في مساحة العمل حسابات بعد، فأنشئ رابط ربط عبر `POST /workspaces/{workspace_id}/connect-links` وأرسله إلى صاحب الحسابات. سيربط بنفسه حسابات Facebook أو Instagram أو YouTube أو X أو LinkedIn أو TikTok، من دون تسجيل الدخول إلى Shager.

## الاستدعاء 4: ارفع الوسائط من رابط

```bash
curl -s -X POST "$API/workspaces/$WS/media" \
  -H "Authorization: Bearer $SHAGER_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "url": "https://cdn.summitphysio.example/video/knee-mobility.mp4",
    "file_name": "knee-mobility.mp4",
    "width": 1080, "height": 1920, "duration_ms": 42000
  }'
```

يُنزّل Shager الملف على الخادم ويُعيد `id` و`kind` و`mime_type` و`size_bytes`. وفي الريلز وShorts والقصص، مرّر `width` و`height` و`duration_ms` إن كنت تعرفها. بذلك يتحقق Shager من قواعد الصيغة في كل شبكة قبل جدولة المنشور، بدلًا من أن يفشل عند الإرسال.

## الاستدعاء 5: أنشئ مسودة بنص لكل حساب

هذا هو الاستدعاء الأهم، وهذه صيغته بلغة TypeScript مع `fetch` عادية، ومعها دالة مساعدة صغيرة ستعيد استخدامها:

```typescript
const API = "https://app.shager.ai/api/v1";

async function shager<T>(method: string, path: string, body?: unknown): Promise<T> {
  const res = await fetch(`${API}${path}`, {
    method,
    headers: {
      Authorization: `Bearer ${process.env.SHAGER_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: body ? JSON.stringify(body) : undefined,
  });
  const json = await res.json();
  if (!res.ok) {
    const err = new Error(`${res.status} ${json.error.code}: ${json.error.message}`);
    (err as any).status = res.status;
    throw err;
  }
  return json.data as T;
}

const WS = process.env.SHAGER_WORKSPACE_ID!;
const mediaId = process.env.SHAGER_MEDIA_ID!; // the id returned by call 4
const channels = await shager<Array<{ id: string; name: string; network: string; status: string }>>(
  "GET", `/workspaces/${WS}/channels`,
);

const post = await shager<{ id: string; status: string }>("POST", `/workspaces/${WS}/posts`, {
  label: "Knee mobility, week 42",
  caption: "Three minutes a day for stiffer knees. Full routine in the video.",
  channel_ids: channels.map((c) => c.id),
  media_ids: [mediaId],
  format: "REEL",
  youtube_title: "3-minute knee mobility routine",
  youtube_privacy: "public",
  per_channel: channels.map((c) => ({
    channel_id: c.id,
    caption: `${c.name}: three minutes a day for stiffer knees. Our physios show the routine.`,
  })),
  cta_url: "https://summitphysio.example/book",
  cta_text: "Book an assessment",
  campaign: "knee-mobility-oct",
  first_comment: "Book an assessment: https://summitphysio.example/book",
  stagger_seconds: [45, 120],
});

console.log(post.id, post.status); // DRAFT
```

ما يمنحك إياه كل حقل:

1. يمنح `per_channel` كل حساب نصه الخاص. عمليًا يكتب الوكيل هذه النصوص؛ والقالب أعلاه مجرد عنصر نائب لتلك الخطوة، والمنطق وراءها مشروح في [تجنّب الحظر عند النشر على نطاق واسع](/ar/blog/avoid-spam-blocks-when-posting-at-scale).
2. تُطبَّق `format` حيث تدعمها الشبكة، وفي غير ذلك يُحسم الاختيار بين `SHORT` و`REEL` لكل شبكة على حدة. ولا تؤثر `youtube_title` و`youtube_privacy` إلا في حسابات YouTube.
3. يُنتج `cta_url` رابطًا قصيرًا ومجموعة وسوم UTM مستقلة لكل حساب، مع `utm_content` يحدد الحساب. وعلى ذلك تقوم [نسبة العملاء المحتملين إلى كل حساب](/ar/blog/utm-per-account-lead-attribution).
4. يضبط `stagger_seconds` توقفًا عشوائيًا بين الحسابات على الشبكة نفسها. القيمة الافتراضية `[30, 90]`.

من دون `schedule_at` تكون النتيجة مسودة. احتفظ بمعرّفها للاستدعاءات التالية عبر `export POST_ID="the_post_id"`.

## الاستدعاء 6: الموافقة أو الجدولة

إذا كانت مساحة العمل تتطلب موافقة، فأرسل المنشور إلى العميل. تتضمن الاستجابة `approval_url` يفتحه المراجِع من دون تسجيل الدخول:

```bash
curl -s -X POST "$API/workspaces/$WS/posts/$POST_ID/approval" \
  -H "Authorization: Bearer $SHAGER_API_KEY" -H "Content-Type: application/json" \
  -d '{"reviewer_name": "Dana Ellis", "reviewer_email": "dana@summitphysio.example", "send_email": true}'
```

بعد الموافقة (أو إن لم تكن الموافقة مطلوبة)، جدوِل المنشور. يتطلب ذلك صلاحية `publish`، ويجب أن تكون `schedule_at` بصيغة ISO 8601 مع الفارق الزمني:

```bash
curl -s -X POST "$API/workspaces/$WS/posts/$POST_ID/schedule" \
  -H "Authorization: Bearer $SHAGER_API_KEY" -H "Content-Type: application/json" \
  -d '{"schedule_at": "2026-10-20T08:30:00+01:00"}'
```

في هذه المرحلة يتحقق Shager من كل وجهة وفق قواعد شبكتها. وإن كان أي حساب سيرفض المنشور، يصلك خطأ 422 `rejected` مع السبب، ولا يدخل شيء إلى قائمة الانتظار.

## الاستدعاء 7: تحقق من الحالة والنقرات

```bash
curl -s "$API/workspaces/$WS/posts/$POST_ID" -H "Authorization: Bearer $SHAGER_API_KEY"
curl -s "$API/workspaces/$WS/posts?status=SCHEDULED&limit=50" -H "Authorization: Bearer $SHAGER_API_KEY"
curl -s "$API/workspaces/$WS/analytics?from=2026-10-01T00:00:00Z&to=2026-10-31T23:59:59Z" \
  -H "Authorization: Bearer $SHAGER_API_KEY"
```

يُعيد `get_post` صفًا لكل وجهة يتضمن `state` و`dispatch_at` و`published_at` والرابط المنشور في `url` وأي خطأ في `error`. وتُعيد التحليلات `total_clicks` و`by_account` و`by_post`، وتحسب النقرات على روابط Shager المتتبَّعة مع استبعاد زيارات الروبوتات. ولإلغاء منشور مجدول لم يبدأ نشره بعد: `POST /workspaces/{workspace_id}/posts/{post_id}/cancel`.

## ما الأخطاء التي يجب أن تتعامل معها شيفرتك؟

| الحالة والرمز | المعنى | ما العمل |
|---|---|---|
| 401 `unauthorized` | الترويسة مفقودة أو مشوهة | أرسل `Authorization: Bearer shgr_...` |
| 403 `forbidden` | المفتاح يفتقر إلى الصلاحية المطلوبة | أنشئ مسودة بدلًا من ذلك، أو اطلب `publish` من إنسان |
| 403 `sandbox_unclaimed` | مفتاح تسجيل ذاتي لم تُتولَّ ملكيته | اعرض رابط تولّي الملكية على إنسان |
| 404 `not_found` | معرّف خاطئ لمساحة العمل أو المنشور أو الحساب | أعد السرد؛ المعرّفات خاصة بكل مساحة عمل |
| 409 `not_scheduled` | إلغاء منشور غير مجدول | اقرأ حالة المنشور أولًا |
| 422 `rejected` | فشلت إحدى قواعد الشبكة | اعرض الرسالة؛ فهي تسمّي المشكلة |
| 429 `rate_limited` | تجاوز 120 طلبًا في الدقيقة لكل مفتاح | تمهّل ثم أعد المحاولة |

نادرًا ما يصطدم عميل مصمم جيدًا بحد المعدل. استدعاء `create_post` واحد يغطي مئات الحسابات، فلا حاجة إلى استدعاء لكل حساب.

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

### هل توجد SDK؟

ليس واحدة مخصصة. يعمل مستند OpenAPI 3.1 مع المولّدات القياسية إن أردت عملاء بأنواع محددة، والـ API صغير بما يكفي لأن تكون دالة مساعدة كالتي أعلاه كل ما تحتاج إليه عادةً. وأداة سطر أوامر لـ Shager في الطريق.

### هل REST وMCP متطابقان فعلًا؟

نعم. كل أداة في MCP تقابل عملية REST واحدة بالاسم والمدخلات والصلاحيات وحد المعدل وتسجيل التدقيق نفسها. استخدم REST من السكربتات والخدمات، وMCP من عملاء الوكلاء. القائمة الكاملة للأدوات في [صفحة الوكلاء](/ar/agents).

### كيف أنشر نصًا مختلفًا على Facebook وYouTube في المنشور نفسه؟

استخدم `per_channel` مع معرّف كل حساب ونصه، و`youtube_title` لعنوان YouTube. كائن منشور واحد ووجهات كثيرة، لكلٍّ منها نصها وصيغتها وتعليقها الأول إن احتجت إليه.

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

حين يعمل هذا التسلسل يدويًا بلا أخطاء، غلّفه في شيء يستطيع الوكيل تكراره. يشرح مقال [بناء مهارة Claude لـ Shager](/ar/blog/build-a-claude-skill-for-shager) كيف تجمع هذه الاستدعاءات والقواعد المحيطة بها في مهارة قابلة لإعادة الاستخدام.

---
Source: https://shager.ai/ar/blog/shager-rest-api-quickstart
