Landing Pages API
صفحة الهبوط هي صفحة عامة يبنيها فريقك في محرر Joryio (السحب والإفلات أو HTML)، وينشرها على عنوان، ويمكن إضافة نموذج إليها. النموذج المُرسل يحدد الشخص، ويكتب السمات والاشتراكات في القوائم إلى ملفه الشخصي، ويسجل الحدثين Landing Page Viewed وLanding Page Form Submitted، اللذين يمكن للشرائح والقمع والرحلات والحملات المحفَّزة استخدامهما كأي حدث آخر.
كل نقاط النهاية في هذه الصفحة نسبية إلى العنوان الأساسي: https://api-eu1.joryio.com/api - انظر نظرة عامة على API.
الصلاحيات: landing_pages:read وlanding_pages:write وlanding_pages:publish (انظر مفاتيح API).
أين تعيش الصفحة
تُخدم الصفحة المنشورة على <pages host>/<workspace handle>/<slug>. الـ handle لمساحة العمل هو معرّفها نفسه - مبهم ودائم ولا يُختار ولا يُغيَّر (https://<workspace id>.eu1.jrypages.com/<slug> على نطاق الصفحات)؛ والـ slug فريد داخل مساحة العمل ومشتق من اسم الصفحة ما لم تحدده. يمكن لمساحة العمل بدلًا من ذلك أن تخدم صفحاتها على نطاق فرعي خاص بها (https://pages.yourbrand.com/<slug>) - انظر استخدام نطاقك الخاص. لكل صفحة أيضًا رابط معاينة (?preview=<signature>، من previewUrl): المسودة الحالية، يراها من يملك الرابط دون تسجيل دخول إلى Joryio، لا تُخزَّن مؤقتًا ولا تُفهرس؛ يتوقف عن العمل عند سحب نشر الصفحة.
مخطط النموذج
form هو ما يتحقق منه مسار الإرسال العام. لا تحمل ترميز الصفحة سوى أسماء الحقول.
{
"fields": [
{ "key": "email", "type": "email", "label": "Email", "required": true },
{ "key": "first_name", "type": "text", "label": "First name", "attribute": "firstName" },
{ "key": "size", "type": "radio", "options": [{ "label": "S", "value": "s" }, { "label": "M", "value": "m" }] },
{ "key": "marketing", "type": "checkbox", "label": "Email me offers", "lists": ["<listId>"] },
{ "key": "lists", "type": "subscriptions", "lists": ["<listId>", "<listId>"] },
{ "key": "src", "type": "hidden", "value": "utm_source" }
],
"submit": { "action": "message", "message": "Thanks - check your inbox." },
"identity": "email"
}
| النوع | يكتب | ملاحظات |
|---|---|---|
email, phone | بريد جهة الاتصال / هاتفها | واحد على الأكثر من كل نوع؛ phone مع lists يشترك في تلك القوائم |
text, number, date, dropdown, radio | السمة المسماة في attribute (افتراضيًا: المفتاح) | dropdown وradio يحتاجان options؛ radio مطلوب دائمًا |
checkbox | سمة منطقية؛ مع lists يشترك عند التحديد | مربعات الموافقة لا تكون محددة مسبقًا أبدًا |
checkbox_group | سمة مصفوفة | options مطلوب |
subscriptions | يشترك في القوائم المحددة | lists مطلوب |
hidden | سمة من value ثابتة، أو utm_source أو utm_medium أو utm_campaign أو utm_content أو utm_term أو referrer أو page |
submit.eventName (اختياري) يطلق هذا الحدث المخصص على الشخص إضافة إلى حدث المنصة، مع القيم المُرسلة كخصائص؛ وsubmit.setAttributes (اختياري، { "lead_source": "spring_sale" }) يكتب قيم سمات ثابتة في كل إرسال. يمكن ضبط كليهما أيضًا على زر الإرسال في المحرر. submit.action إما message (عرض message في مكانه) أو redirect (إلى url، https فقط). يحتاج النموذج إلى حقل بريد أو هاتف ليمكن تحديد الشخص؛ يمكن لرابط من رسالة Joryio أن يحمل رمز الشخص بدلًا من ذلك (مخطط له).
نقاط النهاية
| الطريقة | المسار | الصلاحية | ما تفعله |
|---|---|---|---|
GET | /landing-pages | landing_pages:read | قائمة مقسّمة إلى صفحات ({ data, pagination }) مع الحالة والإحصاءات ومن أنشأ ومن عدّل آخر مرة والعنوان العام. ?templates=true يسرد القوالب (قوالبك ثم المدمجة)؛ مرشحات ?status= (مفصولة بفواصل)، ?q=، ?tags=، ?createdBy=، ?editedBy=؛ ترتيب على كامل القائمة عبر ?sortBy= (name, status, views, submissions, createdAt, editedAt, publishedAt) و?sortOrder=؛ ?limit= (حتى 100)، ?offset= |
GET | /landing-pages/:id/history | landing_pages:read | سجل التدقيق لصفحة واحدة، الأحدث أولاً: إنشاء وتحديث ونشر وإزالة وحذف مع الفاعل. ?limit= من 1 إلى 200 |
POST | /landing-pages | landing_pages:write | إنشاء مسودة: name، slug، mode (dnd أو html)، html، css، grapejsData، form، seo (title، description، faviconUrl، ogImageUrl، noIndex)، language، dir، tags، sdkEnabled، personalized |
GET | /landing-pages/:id | landing_pages:read | صفحة واحدة كاملة مع publicUrl وpreviewUrl |
PUT | /landing-pages/:id | landing_pages:write | تحديث؛ الصفحة الحية لا تتغير إلا عند النشر التالي |
DELETE | /landing-pages/:id | landing_pages:write | حذف مسودة (اسحب النشر أولًا) |
POST | /landing-pages/:id/duplicate | landing_pages:write | نسخ صفحة أو إنشاء صفحة من قالب؛ { "asTemplate": true } يحفظ النسخة كقالب |
POST | /landing-pages/:id/publish | landing_pages:publish | تجميد المستند المنقّى وخدمته |
POST | /landing-pages/:id/unpublish | landing_pages:publish | السحب؛ يتغير رمز التوقيع |
GET | /landing-pages/:id/preview | landing_pages:read | المسودة معروضة كما ستكون الصفحة الحية (HTML)؛ تُهمَل إرسالاتها |
GET | /landing-pages/:id/submissions | landing_pages:read | سجل الإرسالات، الأحدث أولًا؛ البيانات الشخصية مقنّعة بدون pii:view. ?limit= (حتى 200)، ?before= |
GET | /landing-pages/:id/submissions.csv | landing_pages:read | كل الإرسالات كملف CSV مُتدفق، الأقدم أولًا: submitted_at، عمود لكل حقل في النموذج (كل إجابة، مربوطة بسمة أم لا)، person_id، identified_by، lists_subscribed، referrer وقيم utm_*؛ البيانات الشخصية مقنّعة بدون pii:view |
GET | /landing-pages/:id/report | landing_pages:read | المشاهدات والمشاهدات الأولى والإرسالات لكل يوم (UTC)، والإجماليات ومعدل التحويل للمدة، وعدادات كل الوقت. ?days= من 1 إلى 365 (الافتراضي 30) |
GET | /landing-pages/:id/review | landing_pages:read | مراجعة الإطلاق: نتائج (code، severity مانع أو توصية، scope، params). الموانع توقف النشر؛ يجيب POST .../publish بـ 400 مع النتائج نفسها |
GET | /landing-pages/handle | landing_pages:read | عنوان صفحات مساحة العمل: { handle, host, example, customHost }. الـ handle هو معرّف مساحة العمل نفسه، أول جزء في كل عنوان صفحة - مبهم ودائم ولا يُختار ولا يُغيَّر؛ وcustomHost هو نطاق مساحة العمل النشط الخاص بها، عندما يكون لها واحد |
GET | /landing-pages/domain | landing_pages:publish | نطاق مساحة العمل الخاص: { domain, limit, used, pagesHost } - domain (أو null) مع id وhostname وstatus (pending أو active أو failed) وverifiedAt وtarget وrecords (سجلات DNS المطلوب إضافتها) وproviderConfigured وlastError؛ ويَعدّ limit وused نطاقات صفحات الهبوط في المؤسسة |
POST | /landing-pages/domain | landing_pages:publish | إضافة نطاقك الخاص: { "hostname": "pages.yourbrand.com" }. يرد بالنطاق بحالة pending مع سجلات DNS الخاصة به. 409 عندما يكون لمساحة العمل نطاق بالفعل أو تكون المؤسسة عند حدها (تذكر الرسالة الحد) |
POST | /landing-pages/domain/:id/verify | landing_pages:publish | إعادة فحص DNS والشهادة على الحافة؛ يرد بالنطاق وحالته الحالية |
DELETE | /landing-pages/domain/:id | landing_pages:publish | إزالة النطاق؛ تعود عناوين الصفحات فورًا إلى نطاق الصفحات |
GET | /landing-pages/capabilities | landing_pages:read | { botCheck }: هل يمكن للخادم التحقق من Cloudflare Turnstile، ليتمكن النموذج من ضبط botCheck: true |
المسارات العامة (بدون مصادقة)
| الطريقة | المسار | ما تفعله |
|---|---|---|
GET | /p/:handle/:slug | الصفحة المنشورة |
POST | /p/:id/view | إشارة المشاهدة التي ترسلها الصفحة نفسها |
POST | /p/:id/submit | إرسال النموذج؛ يحمل الجسم التوقيع المضمَّن في المستند المنشور، فلا يمكن الإرسال إلا من الصفحة كما نُشرت |
GET | /p/go/:workspaceId/:slug | وجهة {{ 'slug' | landing_page_url }} في رسالة: تحويل 302 إلى العنوان القياسي للصفحة مع سلسلة الاستعلام (رمز الشخص وقيم UTM) |
GET | /p/confirm/:token | الرابط في بريد التأكيد المزدوج: يشترك في القوائم التي يسميها الرمز ويعرض صفحة تأكيد |
تُحدَّد حدود المعدل حسب من يرسل الطلب، لا حسب عنوان IP - قد يضع مشغل الهاتف المحمول أو مكتب آلاف الأشخاص خلف عنوان واحد. للصفحة وإشارة المشاهدة الخاصة بها و/p/go سقف للإغراق فقط قدره 30,000 طلب في الدقيقة لكل IP. لا يُقيَّد رابط التأكيد الصالح أبدًا؛ أما الروابط غير الصالحة فتُرفض بعد 300 في الدقيقة من IP واحد. إرسال النماذج: 15 في الدقيقة و60 في الساعة من الشخص نفسه (البريد الإلكتروني، وإلا الهاتف) على النموذج نفسه، و3,000 في الدقيقة لكل صفحة، و2,000 في الدقيقة لكل IP؛ ويعرض الإرسال المرفوض رسالة بلغة الصفحة. يقتصر جسم الصفحة على 500 كيلوبايت و50 حقلًا. يحمل كل نموذج حقل honeypot ومدة بقاء دنيا قدرها ثانيتان.
استخدام نطاقك الخاص
بدلًا من https://<workspace id>.eu1.jrypages.com/<slug>، يمكن لمساحة العمل أن تخدم صفحاتها على نطاق فرعي تملكه - https://pages.yourbrand.com/<slug>. يُعدّ النطاق من الإعدادات -> صفحات الهبوط (بطاقة "نطاقك") أو عبر المسارات الأربعة أعلاه؛ ويحتاج إلى landing_pages:publish.
- أضف النطاق الفرعي (
POST /landing-pages/domain). نطاق فرعي تملكه، مثلpages.yourbrand.com- ليس نطاقًا جذريًا، ولا نطاقًا لـ Joryio أبدًا. تسجّله Joryio على الحافة وترد بالنطاق بحالةpendingمع سجلات DNS المطلوب ضبطها. - أضف سجلات DNS لدى مزوّد DNS الخاص بك: سجل
CNAMEمن النطاق الفرعي إلى الهدف الذي تعطيك إياه Joryio، إضافة إلى سجلات التحقق من الشهادة (TXT). تعرضها الإعدادات -> صفحات الهبوط مع زر نسخ؛ ويحملrecordsالقائمة نفسها. - تحقق (
POST /landing-pages/domain/:id/verify). بمجرد تحليل CNAME تُصدر الشهادة خلال بضع دقائق وتصبح الحالةactive؛ كما يُعاد فحص النطاقات المعلقة تلقائيًا كل خمس دقائق. التحقق الذي تنتهي مهلته يصبحfailedمع السبب فيlastError- صحّح السجلات وتحقق مجددًا، أو أزل النطاق وأضفه من جديد.
ما دام النطاق active، يستخدمه كل عنوان صفحة تكتبه Joryio - publicUrl الصفحة، ورابط المعاينة، و{{ 'slug' | landing_page_url }} في الرسائل وإعادة التوجيه /p/go خلفه؛ ويستمر عنوان الصفحات في خدمة الصفحات نفسها، فلا يتعطل شيء قبل ذلك أو بعده. إزالة النطاق (DELETE /landing-pages/domain/:id) تعيد العناوين فورًا إلى عنوان الصفحات؛ وتبقى الصفحات منشورة.
كم عددها. لمساحة العمل نطاق واحد على الأكثر. يجوز للمؤسسة افتراضيًا نطاق واحد لصفحات الهبوط عبر جميع مساحات عملها؛ يبلّغ GET /landing-pages/domain عن limit وكم منها used، والإضافة فوق الحد ترد بـ 409 مع رسالة تذكره. اطلب منا رفع الحد لمزيد من مساحات العمل أو العلامات التجارية.
الموافقة: التأكيد المزدوج وفحص الروبوتات
القائمة التي تتطلب تأكيدًا مزدوجًا (إعدادات القائمة) لا يُشترك فيها مباشرة من نموذج أبدًا. يُكتب الشخص ويُسجَّل الحدث، ويطلب الرد التحقق من البريد الوارد، ويحمل بريد واحد (بلغة الصفحة، عبر إعداد البريد الخاص بمساحة العمل) رابطًا موقعًا صالحًا سبعة أيام؛ يشترك GET /p/confirm/:token في القوائم مع optInSource: double_opt_in ويعرض صفحة تأكيد. يسرد صف السجل تلك القوائم تحت listsPending؛ وتذكر مراجعة الإطلاق أي القوائم ستطلب تأكيدًا.
يعرض form.botCheck: true أداة Cloudflare Turnstile قبل زر الإرسال ويرفض الإرسال الذي لا يتحقق رمزه. متاح فقط عندما يكون الخادم مهيأً لـ Turnstile (GET /landing-pages/capabilities). النماذج داخل الرسائل في التطبيق لا تحتاجه أبدًا: يصادقها SDK.
الزوار وWeb SDK والتخصيص
تعدّ الصفحة المنشورة بنفسها المشاهدات والمشاهدات الأولى والإرسالات؛ والزائر الذي يصل عبر رابط رسالة يحمل رمزه (?jp=، انظر مرشح Liquid أدناه) يُكتب له Landing Page Viewed في ملفه. مفتاحان لكل صفحة يذهبان أبعد:
sdkEnabledيحمّل Web SDK لمساحة العمل على الصفحة الحية (يتطلب تطبيق ويب نشطًا في الإعدادات > التطبيقات، وإلا يُرفض الحفظ). يحصل كل زائر على جلسة وأحداث كأي صفحة فيها SDK؛ يسجل وقت التشغيل Landing Page Viewed عبر SDK، ويُحدَّد الزائر الحامل للرمز عند الوصول، ويحدد النموذج المُرسل الزائر بوصفه الشخص الذي كُتب إليه، فيندمج تاريخه المجهول في الملف الشخصي. يمكن أن تظهر الرسائل داخل التطبيق الموجهة إلى تطبيق الويب على الصفحة. لا تحمّل معاينة المحرر SDK أبدًا.personalizedيعرض Liquid الصفحة للزائر الذي يصل برمز، كما تفعل الرسالة ({{ user.firstName | default: "there" }}، السمات،landing_page_url)؛ وبدون رمز تُعرض الصفحة نفسها بشخص فارغ فتظهر القيم الافتراضية. يُقدَّم العرض الشخصي معCache-Control: private, no-store؛ ومرشح catalog غير متاح في الصفحات.
القوالب والذكاء الاصطناعي والروابط من الرسائل
القوالب المدمجة. يسرد ?templates=true قوالب مساحة العمل وخمسة قوالب مدمجة (الاشتراك في النشرة، التسجيل في فعالية، قائمة انتظار منتج، سحب على جائزة، قريبًا). للقالب المدمج معرّف ثابت؛ وPOST /landing-pages/:id/duplicate عليه ينشئ صفحة عادية في مساحة العمل. أي صفحة تصبح قالبًا بـ { "asTemplate": true }.
التصميم والمراجعة بالذكاء الاصطناعي (جلسة لوحة التحكم فقط، landing_pages:write): POST /ai/pages/design مع brief، واختياريًا language وbrandVoiceId وarchetype (bold، editorial، minimal، product، event) وcolorStrategy (restrained، committed، drenched) وgoal (signup، waitlist، event، download، contest، other) يعيد { name, seo, design, html, css, form, language, dir } - يخطط النموذج الأقسام ويكتب النص، وكود حتمي يبني الترميز على مجموعة العلامة التجارية، ولا يُحفظ شيء حتى تحفظ. POST /ai/pages/revise مع source (HTML الصفحة) وinstruction يعيد { source, reply }، المستند المراجَع كاملًا؛ تُرفض مراجعة تحذف النموذج أو تضيف سكريبتًا.
الربط بصفحة من رسالة. في أي نص بريد أو SMS أو WhatsApp، يولّد {{ 'spring-sale' | landing_page_url }} رابطًا إلى الصفحة المنشورة بهذا الـ slug. يحمل الرابط رمز المستلم (?jp=)، فتُكتب المشاهدة وإرسال النموذج إلى ذلك الشخص حتى قبل أن يكتب بريده؛ ويضيف وسيط ثانٍ سلسلة استعلام: {{ 'spring-sale' | landing_page_url: 'utm_campaign=spring' }}. الـ slug غير المنشور يولّد سلسلة فارغة.
الأحداث. يظهر Landing Page Viewed وLanding Page Form Submitted في كل منتقي أحداث (محفزات الرحلات، الحملات المحفَّزة، الشرائح) ضمن أحداث المنصة مع خصائصها.
ما يفعله الإرسال
- يتحقق من القيم مقابل المخطط؛ تُتجاهل الحقول غير المعروفة، وتعود الأخطاء كـ
{ "ok": false, "errors": [...] }. - يحدد الشخص: يُحدَّث الملف الموجود بنفس البريد، وإلا يُنشأ ملف بمعرّف خارجي مولَّد و
sourceبقيمةlanding_page:<slug>. لا يُملأ البريد أو الهاتف إلا حيث لا يملك الملف أيًا منهما؛ والشخص المحدَّد برمز الرابط (jp) يمكنه تحديث هاتفه، ولا يمكنه تغيير بريده أبدًا. - يكتب السمات المعيَّنة، ويشترك في القوائم المحددة، ويسجل Landing Page Form Submitted مع
pageIdوpageSlugوpageNameومفاتيح الحقول وlistsSubscribedوreferrerوقيم UTM، وemailوphoneمن النموذج معphoneUpdated(trueعندما يحمل الملف الآن هاتف النموذج، وfalseعندما احتفظ بهاتف مختلف؛ ويغيب عندما لا يحتوي النموذج على هاتف أو يحتوي على الهاتف نفسه). - يحفظ صفًا في السجل (تبويب الإرسالات) ويزيد عداد
submissionsللصفحة. - يجيب
{ "ok": true, "message": "..." }أو{ "ok": true, "redirect": "https://..." }.
انظر أيضًا: صفحات الهبوط والنماذج في دليل المستخدم - الميزة نفسها من جهة المسوّق.