# صفحات المتجر

صفحات المتجر هي صفحات النص التي يكتبها التاجر، مثل من نحن أو التوصيل أو الإرجاع. كل صفحة مكتوبة بلغة Markdown. الصفحة المنشورة تظهر على الرابط `/pages/{slug}` في المتجر، وتُدرج في `sitemap.xml` و`llms.txt` الخاصين بالمتجر. والمسودة تُرجع `404` في المتجر. هذه النقاط الخمس تعرض الصفحات وتقرأها وتنشئها وتعدّلها وتحذفها.

يعدّل التاجر الصفحات نفسها من لوحة التحكم، في صفحة التخصيص، سطر **الصفحات**. انظر [صفحات المتجر](https://dzbuild.com/ar/docs/storefront/pages) في دليل التاجر.

## قبل أن تبدأ[​](#قبل-أن-تبدأ "رابط مباشر إلى قبل أن تبدأ")

* تحتاج القراءة إلى `store:read` وتحتاج الكتابات إلى `store:write`. مفاتيح التاجر تحمل الاثنتين.
* تحتاج `POST` و`PATCH` و`DELETE` إلى `Idempotency-Key`. انظر [Idempotency](https://dzbuild.com/ar/ar/api-docs/idempotency.md).
* الواجهة البرمجية لا تستطيع رفع الصور. الصورة في `body_md` رابط إلى صورة موجودة على الإنترنت، تُكتب هكذا: `![text](https://...)`.

## كائن الصفحة[​](#كائن-الصفحة "رابط مباشر إلى كائن الصفحة")

| الحقل             | النوع          | ملاحظات                                                                                                                                                                                        |
| ----------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`              | int            | رقم الصفحة.                                                                                                                                                                                    |
| `slug`            | string         | آخر جزء من عنوان الصفحة، بعد `/pages/`. من 2 إلى 80 حرفاً من الحروف اللاتينية الصغيرة والأرقام والشرطات، يبدأ وينتهي بحرف أو رقم. فريد في المتجر.                                              |
| `title`           | string         | من 1 إلى 120 حرفاً.                                                                                                                                                                            |
| `body_md`         | string         | النص بلغة Markdown، حتى 65,536 بايت. انظر [كيف يُعرض النص](#how-the-body-is-rendered).                                                                                                         |
| `seo_title`       | string أو null | العنوان الذي تعرضه محركات البحث، حتى 70 حرفاً. `null` يستعمل `title`.                                                                                                                          |
| `seo_description` | string أو null | الوصف الذي تعرضه محركات البحث، حتى 160 حرفاً. `null` يستعمل أول سطور النص.                                                                                                                     |
| `status`          | string         | `draft` أو `published`.                                                                                                                                                                        |
| `translations`    | object أو null | نصوص اللغة الثانية للمتجر، مفتاحها رمز اللغة، مثل `{"fr": {"title": "...", "body_md": "...", "seo_title": null, "seo_description": null}}`، أو `null`. انظر [اللغة الثانية](#second-language). |
| `url`             | string         | العنوان الكامل للصفحة في المتجر.                                                                                                                                                               |
| `created_at`      | string         | `YYYY-MM-DD HH:MM:SS`، بتوقيت الخادم.                                                                                                                                                          |
| `updated_at`      | string         | `YYYY-MM-DD HH:MM:SS`، بتوقيت الخادم.                                                                                                                                                          |

تُحذف وسوم HTML من `title` و`seo_title` و`seo_description`، ويُقصّ النص الذي يتجاوز الحد.

### كيف يُعرض النص[​](#how-the-body-is-rendered "رابط مباشر إلى كيف يُعرض النص")

* يُعرض Markdown في الوضع الآمن: تُهرَّب شيفرة HTML الخام وتظهر نصاً.
* السطر الجديد الواحد في النص يبقى سطراً جديداً.
* الرابط إلى المتجر نفسه، مثل `/products` أو `/category/12` أو `/pages/delivery`، يُفتح في النافذة نفسها. والرابط إلى موقع آخر يُفتح في نافذة جديدة، وكذلك الرابط الذي يبدأ بـ`//`.
* رابط يوتيوب وحده في سطره يعرض الفيديو.

### اللغة الثانية[​](#second-language "رابط مباشر إلى اللغة الثانية")

لا يُكتب `translations` إلا ما دامت إضافة المتجر متعدد اللغات مفعّلة في المتجر. بدونها يُتجاهل الحقل وتبقى القيمة المحفوظة كما هي. المفتاح هو اللغة الثانية للمتجر: `fr` لمتجر عربي، و`ar` لمتجر فرنسي. الزبون الذي يتصفح المتجر بتلك اللغة يرى تلك النصوص، والحقل الفارغ يُعوَّض بالحقل الأساسي.

## `GET /v1/store/pages`[​](#get-v1storepages "رابط مباشر إلى get-v1storepages")

كل صفحات المتجر، والمسودات معها، مرتبة حسب العنوان. العناصر ملخصات بدون النص: اقرأ صفحة واحدة لتحصل على `body_md`. القائمة ليست مقسمة إلى صفحات: للمتجر 25 صفحة على الأكثر.

**المصادقة:** مفتاح منصة بصلاحية `store:read`.

### الطلب[​](#الطلب "رابط مباشر إلى الطلب")

```
curl 'https://api.dzbuild.app/v1/store/pages' \

  -H "Authorization: Bearer $DZ_KEY"
```

### الاستجابة 200[​](#الاستجابة-200 "رابط مباشر إلى الاستجابة 200")

يحمل كل عنصر `id` و`slug` و`title` و`status` و`url` و`updated_at`. `cap` هو عدد الصفحات الذي تسمح به خطة المتجر. و`max_pages` هو الحد الأقصى لكل الخطط.

```
{

  "data": {

    "items": [

      {

        "id": 7,

        "slug": "retours",

        "title": "Retours",

        "status": "published",

        "url": "https://my-store.dzbuild.app/pages/retours",

        "updated_at": "2026-11-06 10:12:40"

      }

    ],

    "cap": 25,

    "max_pages": 25

  },

  "meta": {"request_id": "3f1c9a7b20d4e865", "api_version": "v1"}

}
```

## `GET /v1/store/pages/{id}`[​](#get-v1storepagesid "رابط مباشر إلى get-v1storepagesid")

صفحة واحدة.

**المصادقة:** مفتاح منصة بصلاحية `store:read`.

### الطلب[​](#الطلب-1 "رابط مباشر إلى الطلب")

```
curl 'https://api.dzbuild.app/v1/store/pages/7' \

  -H "Authorization: Bearer $DZ_KEY"
```

### الاستجابة 200[​](#الاستجابة-200-1 "رابط مباشر إلى الاستجابة 200")

الاستجابة هي كائن الصفحة. الصفحة التي ليست في المتجر تُرجع `404 page_not_found`.

## `POST /v1/store/pages`[​](#post-v1storepages "رابط مباشر إلى post-v1storepages")

ينشئ صفحة.

**المصادقة:** مفتاح منصة بصلاحية `store:write`. **يتطلب `Idempotency-Key`.**

### الجسم[​](#الجسم "رابط مباشر إلى الجسم")

| الحقل             | النوع                  | مطلوب | ملاحظات                                                                                                                                                                                                                                                                  |
| ----------------- | ---------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `title`           | string                 | نعم   | من 1 إلى 120 حرفاً.                                                                                                                                                                                                                                                      |
| `slug`            | string                 | لا    | يُصنع من العنوان إذا لم ترسله. وإذا لم يعطِ ذلك `slug` صالحاً (عنوان ليس فيه حروف لاتينية ولا أرقام كالعنوان العربي، أو كلمة محجوزة، أو `slug` تستعمله صفحة أخرى)، تأخذ الصفحة `page-N`. الـ`slug` الذي ترسله يُحوَّل إلى حروف صغيرة، ثم يجب أن يكون صالحاً وغير مستعمل. |
| `body_md`         | string                 | لا    | Markdown، حتى 65,536 بايت.                                                                                                                                                                                                                                               |
| `seo_title`       | string أو null         | لا    | حتى 70 حرفاً.                                                                                                                                                                                                                                                            |
| `seo_description` | string أو null         | لا    | حتى 160 حرفاً.                                                                                                                                                                                                                                                           |
| `status`          | `draft` أو `published` | لا    | القيمة الافتراضية `draft`. لا تنشر إلا إذا طلب التاجر ذلك.                                                                                                                                                                                                               |
| `translations`    | object أو null         | لا    | انظر [اللغة الثانية](#second-language).                                                                                                                                                                                                                                  |

لا يجوز أن يكون `slug` كلمة يستعملها المتجر في عناوينه، مثل `products` أو `product` أو `cart` أو `checkout` أو `category` أو `track-order` أو `landing` أو `pages` أو `sitemap` أو `ar` أو `fr`. هذا الـ`slug` يُرجع `422 invalid_page`.

### الطلب[​](#الطلب-2 "رابط مباشر إلى الطلب")

```
curl -X POST 'https://api.dzbuild.app/v1/store/pages' \

  -H "Authorization: Bearer $DZ_KEY" \

  -H "Content-Type: application/json" \

  -H "Idempotency-Key: page-create-retours-1" \

  -d '{"title": "Retours", "slug": "retours", "body_md": "## Comment retourner un article\n\nÉcrivez-nous sur WhatsApp avec votre numéro de commande.", "status": "published"}'
```

### الاستجابة 201[​](#الاستجابة-201 "رابط مباشر إلى الاستجابة 201")

```
{

  "data": {

    "page": {

      "id": 7,

      "slug": "retours",

      "title": "Retours",

      "body_md": "## Comment retourner un article\n\nÉcrivez-nous sur WhatsApp avec votre numéro de commande.",

      "seo_title": null,

      "seo_description": null,

      "status": "published",

      "translations": null,

      "url": "https://my-store.dzbuild.app/pages/retours",

      "created_at": "2026-11-06 10:12:40",

      "updated_at": "2026-11-06 10:12:40"

    },

    "change_id": 90310

  },

  "meta": {"request_id": "8b2e04d1c9a7f356", "api_version": "v1"}

}
```

## `PATCH /v1/store/pages/{id}`[​](#patch-v1storepagesid "رابط مباشر إلى patch-v1storepagesid")

يغيّر الحقول التي ترسلها فقط. يأخذ الجسم حقول `POST`، كلها اختيارية. الجسم الذي لا يحمل أياً منها يُرجع `422 no_changes`، والنداء الذي لا يغيّر شيئاً يُرجع `change_id: null`.

**المصادقة:** مفتاح منصة بصلاحية `store:write`. **يتطلب `Idempotency-Key`.**

* `slug` جديد يغيّر عنوان الصفحة. ويبقى العنوان القديم يجيب بتحويل `301` إلى الجديد، فتبقى الروابط المنشورة تعمل. ويمكن إرجاع الـ`slug` القديم. وإذا لم ترسل `slug` يبقى العنوان كما هو، حتى لو تغيّر العنوان.
* `"status": "draft"` يُخرج الصفحة من المتجر دون حذفها.

### الطلب[​](#الطلب-3 "رابط مباشر إلى الطلب")

```
curl -X PATCH 'https://api.dzbuild.app/v1/store/pages/7' \

  -H "Authorization: Bearer $DZ_KEY" \

  -H "Content-Type: application/json" \

  -H "Idempotency-Key: page-7-seo-1" \

  -d '{"seo_title": "Retours et échanges", "seo_description": "Comment retourner un article commandé sur notre boutique."}'
```

### الاستجابة 200[​](#الاستجابة-200-2 "رابط مباشر إلى الاستجابة 200")

للاستجابة حقول استجابة `POST` نفسها: `page`، أي الصفحة بعد التغيير، و`change_id`.

## `DELETE /v1/store/pages/{id}`[​](#delete-v1storepagesid "رابط مباشر إلى delete-v1storepagesid")

يحذف صفحة. يتوقف عنوانها في المتجر عن العمل فوراً.

**المصادقة:** مفتاح منصة بصلاحية `store:write`. **يتطلب `Idempotency-Key`.**

### الطلب[​](#الطلب-4 "رابط مباشر إلى الطلب")

```
curl -X DELETE 'https://api.dzbuild.app/v1/store/pages/7' \

  -H "Authorization: Bearer $DZ_KEY" \

  -H "Idempotency-Key: page-7-delete-1"
```

### الاستجابة 200[​](#الاستجابة-200-3 "رابط مباشر إلى الاستجابة 200")

```
{

  "data": {

    "deleted": true,

    "id": 7,

    "change_id": 90312

  },

  "meta": {"request_id": "c40a91e7b25d3f68", "api_version": "v1"}

}
```

## التراجع[​](#التراجع "رابط مباشر إلى التراجع")

كل كتابة تُرجع `change_id`. يُلغي `POST /v1/changes/{change_id}/undo` ذلك التغيير. يحتاج التراجع إلى `store:write` وإلى `Idempotency-Key`.

* التراجع عن `PATCH` يُرجع الصفحة كما كانت قبل ذلك النداء. وإذا حُذفت الصفحة بعد ذلك، يُرجع التراجع `422 restore_target_missing`.
* التراجع عن `DELETE` يُنشئ الصفحة من جديد برقمها و`slug` القديمين.
* لا يمكن التراجع عن الإنشاء: يُرجع التراجع `422 nothing_to_restore`. احذف الصفحة بدلاً من ذلك.
* إذا أخذت صفحة أخرى رقم الصفحة المحذوفة أو `slug` الخاص بها بعد ذلك، أو صار في المتجر 25 صفحة، يُرجع التراجع عن الحذف `409 page_restore_conflict`. غيّر اسم تلك الصفحة أو احذفها، ثم أعد التراجع.
* التغيير الذي يُتراجع عنه مرة ثانية يُرجع `409 already_undone`.
* التغييرات التي يحفظها التاجر من صفحة التخصيص لا تُسجَّل، فلا يمكن التراجع عنها عبر الواجهة البرمجية.
* يعرض `GET /v1/changes?entity=store.page` تغييرات الصفحات، الأحدث أولاً، بصلاحية `store:read`. و`entity_id` هو رقم الصفحة.
* لا يستطيع رمز التطبيق المثبّت قراءة التغييرات ولا التراجع عنها: يُرجع `GET /v1/changes` والتراجع `403 forbidden` (`Apps cannot use this endpoint`). وتبقى استجابات الكتابة تحمل `change_id`.

```
curl -X POST 'https://api.dzbuild.app/v1/changes/90312/undo' \

  -H "Authorization: Bearer $DZ_KEY" \

  -H "Idempotency-Key: undo-90312"
```

```
{

  "data": {

    "undone": true,

    "change_id": 90312,

    "entity": "store.page",

    "undo_change_id": 90315

  },

  "meta": {"request_id": "71d5e0a2c8b94f36", "api_version": "v1"}

}
```

## الأخطاء[​](#الأخطاء "رابط مباشر إلى الأخطاء")

| HTTP | الرمز                    | السبب                                                                                                                                                                                                                                              |
| ---- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400  | `bad_request`            | الجسم ليس كائن JSON، أو رقم الصفحة في المسار ليس رقماً موجباً، أو `Idempotency-Key` غائب أو غير صالح.                                                                                                                                              |
| 401  | `unauthorized`           | مفتاح خاطئ أو غائب.                                                                                                                                                                                                                                |
| 402  | `quota_exceeded`         | انتهت حصة الطلبات الشهرية للمتجر. انظر [حدود المعدل](https://dzbuild.com/ar/ar/api-docs/rate-limits.md).                                                                                                                                           |
| 403  | `forbidden`              | `Missing scope: store:read` أو `Missing scope: store:write`، أو `API access requires an active Enterprise plan` لمفتاح تاجر متجره ليس على خطة Enterprise سارية.                                                                                    |
| 403  | `plan_required`          | الإنشاء يتجاوز عدد الصفحات الذي تسمح به الخطة. يحمل الخطأ `plan` و`cap`.                                                                                                                                                                           |
| 404  | `page_not_found`         | لا توجد صفحة بهذا الرقم في المتجر.                                                                                                                                                                                                                 |
| 409  | `slug_taken`             | صفحة أخرى في المتجر تستعمل هذا الـ`slug`. قيمة `fields` هي `[{"path": "slug", "code": "taken"}]`.                                                                                                                                                  |
| 409  | `write_conflict`         | وصلت كتابة أخرى في اللحظة نفسها. اقرأ الصفحة، ثم أعد المحاولة بـ`Idempotency-Key` جديد.                                                                                                                                                            |
| 409  | `already_undone`         | للتراجع فقط: سبق التراجع عن هذا التغيير.                                                                                                                                                                                                           |
| 409  | `page_restore_conflict`  | للتراجع عن الحذف فقط: صفحة أخرى تستعمل الآن رقم الصفحة أو `slug` الخاص بها، أو في المتجر 25 صفحة بالفعل.                                                                                                                                           |
| 413  | `payload_too_large`      | الجسم أكبر من 1 MB.                                                                                                                                                                                                                                |
| 422  | `invalid_page`           | قيمة مرفوضة: عنوان غائب أو فارغ، أو حقل ليس نصاً، أو `slug` غير صالح أو محجوز، أو `status` غير `draft` و`published`، أو `translations` ليس كائناً، أو `body_md` أكبر من 65,536 بايت. يذكر `fields` قيمتي `{path, code}` للحقل المرفوض، مثل `slug`. |
| 422  | `limit_reached`          | في المتجر 25 صفحة بالفعل. يحمل الخطأ `limit`.                                                                                                                                                                                                      |
| 422  | `no_changes`             | `PATCH` لا يحمل أياً من حقول الصفحة.                                                                                                                                                                                                               |
| 422  | `nothing_to_restore`     | للتراجع فقط: التغيير أنشأ الصفحة.                                                                                                                                                                                                                  |
| 422  | `restore_target_missing` | للتراجع عن `PATCH` فقط: حُذفت الصفحة بعد ذلك.                                                                                                                                                                                                      |
| 422  | `idempotency_key_reuse`  | استُعمل `Idempotency-Key` نفسه مع جسم آخر.                                                                                                                                                                                                         |
| 429  | `rate_limited`           | طلبات كثيرة، ومنها أكثر من 30 كتابة صفحات في الدقيقة للمتجر. انتظر `Retry-After`.                                                                                                                                                                  |
| 429  | `too_many_concurrent`    | أكثر من 5 كتابات صفحات تعمل في الوقت نفسه للمتجر. أعد المحاولة بعد بضع ثوانٍ.                                                                                                                                                                      |
| 500  | `server_error`           | فشل الطلب. أعد المحاولة بـ`Idempotency-Key` نفسه.                                                                                                                                                                                                  |

هكذا تبدو استجابة `invalid_page`.

```
{

  "error": {

    "code": "invalid_page",

    "message": "slug: 2 to 80 lowercase latin letters, digits or dashes, not a store route",

    "fields": [{"path": "slug", "code": "invalid"}]

  },

  "meta": {"request_id": "e9a3c17f04b26d58", "api_version": "v1"}

}
```

## الحدود[​](#الحدود "رابط مباشر إلى الحدود")

* **25 صفحة** لكل متجر (`max_pages`)، والمسودات محسوبة.
* **حد الخطة** (`cap`): 3 صفحات في الخطة المجانية أو الخطة المنتهية، و25 ابتداءً من Pro. المتجر الذي يتجاوز حده بعد تخفيض خطته يحتفظ بصفحاته ويستطيع قراءتها وتعديلها وحذفها. ويُرجع الإنشاء `403 plan_required` حتى يصبح المتجر تحت حده.
* **النص**: `body_md` حتى 65,536 بايت، والطلب حتى 1 MB.
* **الكتابات**: 30 في الدقيقة و5 في الوقت نفسه لكل متجر، فوق الحد الدقيقي للمتجر. انظر [حدود المعدل](https://dzbuild.com/ar/ar/api-docs/rate-limits.md).

## أدوات MCP[​](#أدوات-mcp "رابط مباشر إلى أدوات MCP")

يعطي خادم MCP، في نسخته 1.8.0، المساعد الذكي خمس أدوات للصفحات بالقواعد نفسها: `pages_list` و`page_get` و`page_create` و`page_update` و`page_delete`. وأداة `page_delete` تطلب من المساعد أن يتأكد من التاجر أولاً.
