API

أدمج QueryWin في مسار عملك الخاص

يكتشف QueryWin طلبات البحث التي يحصل فيها موقعك على مرات ظهور دون أن تكون له صفحة مكتوبة لها، ويكتب مسودة المقال الناقص، ويجهّز منتجك للإرسال إلى أدلة المواقع ومنصات الإطلاق والمجتمعات والمواقع التي تستشهد بها إجابات الذكاء الاصطناعي. وتضع هذه الواجهة البرمجية المسارين بين يدي نصوصك البرمجية ومساعدي الذكاء الاصطناعي. أما النشر والإرسال فيبقيان ببيانات اعتمادك وحساباتك أنت: لا يتصل QueryWin بنظام إدارة المحتوى (CMS) لديك أبدًا، ولا يرسل أي شيء بنفسه.

البدء السريع

ثلاث خطوات. وكل ما يلي استدعاء REST عادي بترويسة واحدة.

1

إنشاء مفتاح

من لوحة التحكم في QueryWin، ضمن قسم «API». يظهر المفتاح كاملًا مرة واحدة فقط عند إنشائه. امنح المفتاح النطاقات التي تحتاجها فقط؛ فالمفتاح الذي لا تُحدَّد فيه أي خانة يكون للقراءة فقط.

2

إرسال المفتاح كرمز مميّز من نوع Bearer

أضف إلى كل طلب الترويسة Authorization: Bearer qw_live_…، وتعمل الترويسة X-API-Key أيضًا مع الأدوات التي لا تتيح إلا ترويسة واحدة.

3

معرفة ما تكتبه، ثم استلام المسودة

قائمة المواضيع مجانية ولا تستهلك أي رصيد. أما إنشاء مخطط أو مسودة فيُخصم من الرصيد، ويتطلب نطاق spend في المفتاح.

bash
# 1. المواقع التي يمكن لهذا المفتاح العمل عليها
curl "https://www.querywin.com/api/v1/sites" \
  -H "Authorization: Bearer $QUERYWIN_API_KEY"

# 2. ما تكتبه هذا الأسبوع (مجاني، لا يُخصم من الرصيد)
curl "https://www.querywin.com/api/v1/topics?siteId=YOUR_SITE_ID" \
  -H "Authorization: Bearer $QUERYWIN_API_KEY"
bash
# 3. استلام المسودة (Markdown + JSON-LD مع تعبئة البيانات)
curl "https://www.querywin.com/api/v1/topics/article?siteId=YOUR_SITE_ID&key=standard%20wardrobe%20depth" \
  -H "Authorization: Bearer $QUERYWIN_API_KEY"

# 4. ينشرها نصك البرمجي في مدونتك، ثم يعيد الرابط إلى QueryWin
curl -X POST https://www.querywin.com/api/v1/topics/published \
  -H "Authorization: Bearer $QUERYWIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "siteId": "YOUR_SITE_ID",
    "key": "standard wardrobe depth",
    "url": "https://example.com/blog/standard-wardrobe-depth"
  }'

كل استجابة مغلّفة بهذا الشكل: {"success": true, "data": …}. والأخطاء رموز تقرؤها الآلة، لا جمل؛ لأن QueryWin متعدد اللغات، وأي جملة إنجليزية مكتوبة مباشرةً في الشيفرة ستظهر كما هي على صفحة عربية.

مسار المحتوى

خمس خطوات، اثنتان منها فقط مدفوعتان. والخطوة 4 مسؤوليتك: يسلّمك QueryWin نص Markdown والبيانات المنظَّمة، وأنت من ينشر.

الخطوةنقطة النهايةالتكلفة
العثور على طلبات بحث لها مرات ظهور دون صفحةGET /v1/topicsمجاني
إنشاء مخطط مدعوم بالمصادرPOST /v1/topics/outlineيُخصم من الرصيد
تحويله إلى مسودة جاهزة للنشرPOST /v1/topics/articleيُخصم من الرصيد
نشرها في مدونتكنظام إدارة المحتوى الخاص بك—
إبلاغ QueryWin بالرابطPOST /v1/topics/publishedمجاني

لا يتصل QueryWin بنظام إدارة المحتوى لديك، ولا يحتفظ ببيانات اعتماد موقعك، ولا يضغط زر النشر نيابةً عنك أبدًا. هذه الواجهة تسلّمك المحتوى، والكتابة تجري على جهازك ببيانات اعتمادك أنت. هذا هو الحد الفاصل نفسه، وليس ثغرة فيه.

مسار الإدراج

سبع خطوات، واحدة منها فقط مدفوعة. والخطوة 6 مسؤوليتك: يسلّمك QueryWin مواد الإدراج لكل قناة، وأنت من يرسلها، أو وكيلك بحساباتك أنت. ثم يعيد QueryWin بنفسه التحقق من كل صفحة إدراج منشورة.

الخطوةنقطة النهايةالتكلفة
عرض منتجاتك ومدى اكتمال ملف كل منتجGET /v1/productsمجاني
عرض وجهات الإرسال مرتبة حسب الملاءمة، بما فيها المواقع التي تستشهد بها إجابات الذكاء الاصطناعيGET /v1/channels?productId=مجاني
إنشاء حملة من القنوات التي اخترتهاPOST /v1/campaignsمجاني
استلام المواد الجاهزة لمهمةGET /v1/tasks/{id}مجاني
إعادة صياغتها لتلك القناةPOST /v1/tasks/{id}/materialsيُخصم من الرصيد
إرسالهاحساباتك الخاصة—
الإبلاغ عن الإرسال، ثم عن النشر مع رابط صفحة الإدراجPOST /v1/tasks/{id}/statusمجاني

القيمة published تعني ما أبلغت به أنت؛ أما verified فتعني ما رآه QueryWin عند إعادة التحقق من صفحة الإدراج بعد نحو 72 ساعة: رابط إلى منتجك في أدلة المواقع وقوائم أدوات الذكاء الاصطناعي، وإشارة إليه في سائر المواقع. وهما حقلان منفصلان. والموقع الذي تستشهد به إجابات الذكاء الاصطناعي (citedByAi) موقع يستحق أن تتقدّم إليه، لكنه ليس وعدًا بأنه سيدرج منتجك.

النطاقات

يحمل كل مفتاح الصلاحيات التي مُنحت له عند إنشائه. وتعرضها نقطة النهاية GET /v1/usage، فلا تحتاج إلى اكتشافها بعد الاصطدام بالخطأ 403.

read

مفعّل دائمًا

جميع نقاط النهاية من نوع GET: المواقع، وفجوات المحتوى، والمخططات، والمسودات، والمنتجات، والقنوات، والحملات، والمهام وموادها، والاستخدام.

publish

معطّل افتراضيًا

إنشاء ملفات المنتجات وتحديثها، واستيراد الصور، وتسجيل ما حدث: رابط مقال منشور (يُرسل أيضًا إلى Bing وYandex وSeznam وNaver، وليس إلى Google)، أو حملة جديدة، أو مهمة صارت حالتها «أُرسلت» أو «منشورة». هذه الإجراءات مجانية، لكن كلًّا منها سجل له تبعات: فالحملات تُحتسب من حدود خطتك، وصفحة الإدراج المنشورة تخضع لإعادة التحقق.

spend

معطّل افتراضيًا

إنشاء المخططات والمسودات، وإعادة صياغة مواد الإدراج لقناة معينة. وهذه الإجراءات يُخصم ثمنها من الرصيد. لا تمنح هذا النطاق إلا إذا أردت أن يُنفق المستدعي، سواء كان نصًا برمجيًا أو مساعد ذكاء اصطناعي، من تلقاء نفسه.

لا يوجد تسلسل هرمي: نطاق publish لا يشمل spend، ونطاق spend لا يشمل publish؛ فهما نوعان مختلفان من المخاطر. وأي استدعاء لا يملك مفتاحك النطاق اللازم له يعيد الخطأ 403 مع رمز الخطأ missing_scope_<name> وقائمة النطاقات التي يملكها مفتاحك.

استهلاك الرصيد

هناك نقطتا نهاية تخصمان من الرصيد: POST /v1/topics/outline وPOST /v1/topics/article. وتحميهما ثلاثة ضوابط.

الضابطما يمنعه
confirmSpendنص برمجي يواصل الخصم من الرصيد بعد ارتفاع السعر.
الحد اليوميحلقة تكرار خارجة عن السيطرة تستنزف الرصيد خلال ليلة واحدة. ويُعاد الخطأ 429 مع موعد إعادة التعيين.
بصمة المدخلاتالخصم مرتين للموضوع نفسه. فالمدخلات المتطابقة تعيد النتيجة المخزّنة مؤقتًا مجانًا، لذا فإعادة محاولة طلب انتهت مهلته آمنة.

المعامل confirmSpend سقف للتفويض، وليس مبلغًا محددًا. أرسل قيمة أكبر من السعر الحالي أو مساوية له، وسيُخصم منك ما تكلّفه العملية فعلًا، وكثيرًا ما يكون صفرًا حين تأتي النتيجة من الذاكرة المؤقتة. وإذا ارتفع السعر يومًا فوق السقف الذي حددته، يفشل الاستدعاء مع الخطأ confirm_spend_too_low بدلًا من خصم مبلغ أكبر دون أن تنتبه.

القواعد العامة

ثلاث قواعد تسري على جميع نقاط النهاية.

غلاف الاستجابة

json
{ "success": true,  "data": { "...": "..." } }
{ "success": false, "error": "missing_scope_spend" }

الأخطاء رموز، لا جمل. اقرأها ولا تعرضها كما هي؛ فهي مصممة لتحويلها إلى صياغتك الخاصة.

نتائج منطق الأعمال ليست أخطاء

استدعاء الإنشاء الذي لم يتمكن من إنتاج نتيجة صالحة يعيد HTTP 200 مع data.ok = false ورمز في data.failure، لتتمكن من تمييزه عن فشل المصادقة أو انقطاع الاتصال. ولا يُخصم أي شيء مقابل هذه الاستدعاءات.

json
{
  "success": true,
  "data": { "ok": false, "failure": "no_outline", "creditsSpent": 0 }
}

حد المعدل

120 طلبًا في الدقيقة لكل مفتاح. وعند تجاوز ذلك تحصل على الخطأ 429 مع موعد إعادة التعيين. وهذا الحد منفصل عن الحد اليومي للإنشاء المذكور أعلاه.

خادم MCP لوكلاء الذكاء الاصطناعي

المساران متاحان عبر بروتوكول سياق النموذج (Model Context Protocol)، بالمفتاح نفسه والترويسة نفسها للمصادقة. أضف الخادم إلى Claude Code أو Cursor أو n8n، أو إلى أي أداة تدعم MCP عبر HTTP.

MCPhttps://www.querywin.com/api/mcp
bash
claude mcp add --transport http querywin https://www.querywin.com/api/mcp \
  --header "Authorization: Bearer $QUERYWIN_API_KEY"

19 أداة. ملفات المنتجات: create_product، get_product، update_product، import_product_image. المحتوى: list_sites، get_usage، list_content_gaps، get_outline، get_article_draft، generate_outline، generate_article_draft، mark_published. الإدراج: list_products، list_channels، create_campaign، list_tasks، get_task، write_task_materials، report_task_status. اسأل مساعدك عمّا تكتبه هذا الأسبوع، أو أين ترسل منتجك بعد ذلك، وسيتولى البحث عن الإجابة بنفسه.

موجّه
باستخدام خادم MCP من QueryWin، اعثر على أكبر ثلاث فجوات في محتوى موقعي،
وأرني طلبات البحث وراء كل منها، وأخبرني بتكلفة كتابة مسودة لأولها.

تُصفّى الأدوات حسب النطاق. فمع مفتاح للقراءة فقط، لا تظهر أدوات الإنشاء في قائمة أدوات المساعد إطلاقًا، ولا يستطيع الوكيل استدعاء أداة لا يراها. امنح كل وكيل مفتاحًا خاصًا به، لتتمكن من إلغائه دون المساس بتكاملاتك الأخرى.

تعتمد المصادقة على رمز مميّز من نوع Bearer، وهو ما تسمح به مواصفة MCP (إذ التفويض فيها اختياري). وتتصل مباشرةً تطبيقات العميل التي تتيح لك تعيين ترويسة، مثل Claude Code وCursor وn8n. أما التطبيقات المضيفة التي تشترط شاشة موافقة OAuth فقد لا تتمكن من الاتصال.

Account

GET/v1/sites

عرض المواقع التي يمكن لهذا المفتاح العمل عليها

ابدأ من هنا. تأخذ جميع نقاط النهاية الأخرى قيمة siteId التي يُرجعها هذا الاستدعاء. وإذا أغفلت siteId في نقاط النهاية الأخرى، يُستخدم أول موقع رُبط بالحساب؛ وهذا لا يضر إذا كان في الحساب موقع واحد، لكنه في الحسابات الأخرى خطأ مؤجَّل لا بد أن يظهر.

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataSiteList
└sitesarray<Site>
└siteIdstring
└domainstring
└gscPropertystringخاصية Search Console كما هي حرفيًا: sc-domain:example.com أو https://example.com/.
└syncStatusenumالقيم: pendingsyncingdonefailed
└syncedThroughيقبل nullstringتتأخر بيانات Search Console من 2 إلى 3 أيام. وكل مقياس لهذا الموقع محسوب حتى هذا التاريخ، فاذكر ذلك إذا عرضت الأرقام في أي مكان.
الأخطاء المحتملة
401المفتاح غير موجود، أو صيغته غير صحيحة، أو أُلغي، أو انتهت صلاحيته

مثال

bash
curl "https://www.querywin.com/api/v1/sites" \
  -H "Authorization: Bearer $QUERYWIN_API_KEY"
json — الاستجابة
{
  "success": true,
  "data": {
    "sites": [
      {
        "siteId": "string",
        "domain": "example.com",
        "gscProperty": "string",
        "syncStatus": "pending",
        "syncedThrough": "2026-09-01T00:00:00.000Z"
      }
    ]
  }
}
GET/v1/usage

الأسعار الحالية والحصة المجانية ورصيد النقاط والحدود اليومية

اقرأ هذه البيانات قبل توليد أي شيء. فهي المصدر نفسه الذي تعتمد عليه واجهة الويب لتحديد ما يظهر على كل زر؛ إذ يقرر الخادم ما هو متاح، ولا يُكتشف ذلك بالمحاولة والفشل.

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataUsage
└scopesarray<enum>ما يُسمح لهذا المفتاح بفعله. اقرأه مرة واحدة عند بدء التشغيل بدلًا من أن تكتشف صلاحياتك بالاصطدام بخطأ 403.القيم: readpublishspend
└creditsobject
└balanceinteger
└outlineStepUsage
└availablebooleanتكون false إذا لم يكن محرك التوليد مهيّأً. وعندها لا تستدعِ نقطة النهاية POST المقابلة.
└pricePerOutlineintegerعدد النقاط لكل مخطط (يرد في outline فقط).
└pricePerArticleintegerعدد النقاط لكل مسودة (يرد في article فقط).
└pricePerTaskintegerعدد النقاط لكل إعادة كتابة لقناة (يرد في materials فقط).
└freeRemainingintegerعدد مرات التوليد المجانية المتبقية في هذا الحساب، وتُعدّ لكل موضوع مختلف (المخططات والمسودات) أو لكل مهمة مختلفة (مواد الإدراج)، لا بعدد مرات الضغط على الزر. ويظل confirmSpend مطلوبًا حتى في التوليد المجاني.
└dailyDailyLimitحاجز أمان يوقف النص البرمجي الذي خرج عن السيطرة، ويُعدّ في قاعدة البيانات عبر جميع نقاط الدخول (وتدخل فيه عمليات واجهة الويب أيضًا). يُعاد ضبطه عند منتصف الليل بالتوقيت المحلي، لا وفق نافذة زمنية متحركة.
└usedinteger
└limitinteger
└remaininginteger
└resetAtstring
└articleStepUsage
└availablebooleanتكون false إذا لم يكن محرك التوليد مهيّأً. وعندها لا تستدعِ نقطة النهاية POST المقابلة.
└pricePerOutlineintegerعدد النقاط لكل مخطط (يرد في outline فقط).
└pricePerArticleintegerعدد النقاط لكل مسودة (يرد في article فقط).
└pricePerTaskintegerعدد النقاط لكل إعادة كتابة لقناة (يرد في materials فقط).
└freeRemainingintegerعدد مرات التوليد المجانية المتبقية في هذا الحساب، وتُعدّ لكل موضوع مختلف (المخططات والمسودات) أو لكل مهمة مختلفة (مواد الإدراج)، لا بعدد مرات الضغط على الزر. ويظل confirmSpend مطلوبًا حتى في التوليد المجاني.
└dailyDailyLimitحاجز أمان يوقف النص البرمجي الذي خرج عن السيطرة، ويُعدّ في قاعدة البيانات عبر جميع نقاط الدخول (وتدخل فيه عمليات واجهة الويب أيضًا). يُعاد ضبطه عند منتصف الليل بالتوقيت المحلي، لا وفق نافذة زمنية متحركة.
└usedinteger
└limitinteger
└remaininginteger
└resetAtstring
└materialsStepUsage
└availablebooleanتكون false إذا لم يكن محرك التوليد مهيّأً. وعندها لا تستدعِ نقطة النهاية POST المقابلة.
└pricePerOutlineintegerعدد النقاط لكل مخطط (يرد في outline فقط).
└pricePerArticleintegerعدد النقاط لكل مسودة (يرد في article فقط).
└pricePerTaskintegerعدد النقاط لكل إعادة كتابة لقناة (يرد في materials فقط).
└freeRemainingintegerعدد مرات التوليد المجانية المتبقية في هذا الحساب، وتُعدّ لكل موضوع مختلف (المخططات والمسودات) أو لكل مهمة مختلفة (مواد الإدراج)، لا بعدد مرات الضغط على الزر. ويظل confirmSpend مطلوبًا حتى في التوليد المجاني.
└dailyDailyLimitحاجز أمان يوقف النص البرمجي الذي خرج عن السيطرة، ويُعدّ في قاعدة البيانات عبر جميع نقاط الدخول (وتدخل فيه عمليات واجهة الويب أيضًا). يُعاد ضبطه عند منتصف الليل بالتوقيت المحلي، لا وفق نافذة زمنية متحركة.
└usedinteger
└limitinteger
└remaininginteger
└resetAtstring
└distributionDistributionQuotaحدود الإدراج في الخطة والاستخدام الحالي. وإذا كانت قيمة الحد null فهو غير محدود.
└planstring
└limitsobject
└channelsيقبل nullintegerعدد القنوات المختلفة التي يمكن أن تكون لمنتج واحد مهام عليها، ويُعدّ خلال الفترة المحددة في channelsPeriod.
└channelsPeriodenummonth (الخطط المدفوعة): يُعدّ لكل شهر ميلادي (بتوقيت UTC)، فيتيح كل شهر دفعة جديدة من القنوات. total (الخطة المجانية): يُعدّ طوال عمر المنتج.القيم: monthtotal
└tasksPerMonthيقبل nullintegerعدد المهام التي يمكن إنشاؤها في كل شهر ميلادي (بتوقيت UTC)، لجميع المنتجات معًا.
└activeCampaignsيقبل nullintegerعدد الحملات التي يمكن أن تكون نشطة في الوقت نفسه.
└usageobject
└activeCampaignsinteger
└tasksThisMonthinteger
└channelsيقبل nullintegerيرد فقط إذا حدّد الطلب منتجًا.
الأخطاء المحتملة
401فشلت المصادقة

مثال

bash
curl "https://www.querywin.com/api/v1/usage" \
  -H "Authorization: Bearer $QUERYWIN_API_KEY"
json — الاستجابة
{
  "success": true,
  "data": {
    "scopes": [
      "read"
    ],
    "credits": {
      "balance": 0
    },
    "outline": {
      "available": true,
      "pricePerOutline": 0,
      "pricePerArticle": 0,
      "pricePerTask": 0,
      "freeRemaining": 0,
      "daily": {
        "used": 0,
        "limit": 0,
        "remaining": 0,
        "resetAt": "2026-09-01T00:00:00.000Z"
      }
    },
    "article": {
      "available": true,
      "pricePerOutline": 0,
      "pricePerArticle": 0,
      "pricePerTask": 0,
      "freeRemaining": 0,
      "daily": {
        "used": 0,
        "limit": 0,
        "remaining": 0,
        "resetAt": "2026-09-01T00:00:00.000Z"
      }
    },
    "materials": {
      "available": true,
      "pricePerOutline": 0,
      "pricePerArticle": 0,
      "pricePerTask": 0,
      "freeRemaining": 0,
      "daily": {
        "used": 0,
        "limit": 0,
        "remaining": 0,
        "resetAt": "2026-09-01T00:00:00.000Z"
      }
    },
    "distribution": {
      "plan": "string",
      "limits": {
        "channels": 0,
        "channelsPeriod": "month",
        "tasksPerMonth": 0,
        "activeCampaigns": 0
      },
      "usage": {
        "activeCampaigns": 0,
        "tasksThisMonth": 0,
        "channels": 0
      }
    }
  }
}

Topics

GET/v1/topics

طلبات بحث لها مرات ظهور وليست لها صفحة مخصصة

مجاني، ولا تترتب عليه رسوم لدى أي خدمة خارجية (أما استخدام API نفسه فيتطلب خطة مدفوعة). يُحسب من جديد في كل استدعاء من بيانات Search Console الخاصة بك، دون أي قاعدة بيانات خارجية للكلمات المفتاحية؛ وهذا هو جوهر الفكرة: «لديك مرات ظهور بالفعل وليست لديك صفحة لها» أمر لا تستطيع أي أداة للكلمات المفتاحية أن تخبرك به.

تُرتَّب النتائج حسب حجم الفرصة، وتُستبعد المواضيع التي أخفاها المستخدم في الواجهة.

معاملات الاستعلام

الحقلالنوعالوصف
siteIdstringمن GET /v1/sites. إذا أُغفل، يُستخدم أول موقع رُبط بالحساب.

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataTopicList
└siteIdيقبل nullstring
└topicsarray<Topic>
└keystringمفتاح المجموعة: أعِده كما هو في key إلى كل نقاط النهاية الأخرى الخاصة بالمواضيع. وهو النص الموحَّد لطلب البحث الممثِّل للمجموعة، لذا قد يحتوي على مسافات وشرطات مائلة وأحرف غير لاتينية. أرسله دائمًا في سلسلة الاستعلام أو في نص الطلب، ولا تضعه أبدًا في مسار الرابط.
└titlestringطلب البحث صاحب أكبر عدد من مرات الظهور في المجموعة، كما هو حرفيًا. وهو ليس عنوانًا مولَّدًا؛ فالعنوان يأتي مع المخطط.
└shapeenumتعني comparison أن هذه المجموعة تطابقت مع قائمة منافسيك. يجب أن تقارن المقالة، لا أن تشرح المنافس؛ وإلا فأنت تكتب محتوى لصالحه.القيم: comparisonroundupguide
└intentstring
└membersarray<TopicMember>
└textstringطلب البحث كما كتبه المستخدم.
└impressionsinteger
└clicksinteger
└positionيقبل nullnumber
└landingUrlيقبل nullstringالصفحة التي يسجلها Search Console حاليًا لطلب البحث هذا، إن وُجدت.
└impressionsintegerقيمة فعلية، مصدرها Search Console.
└clicksintegerقيمة فعلية، مصدرها Search Console.
└positionيقبل nullnumberقيمة فعلية: متوسط موضع الظهور في المجموعة، مرجَّحًا بعدد مرات الظهور.
└competitorboolean
└scorenumber
└rankinteger
└upsideClicksintegerهذه قيمة تقديرية، وليست قياسًا فعليًا: النقرات الشهرية الإضافية المتوقعة لو وصلت صفحة مخصصة إلى الموضع 3. وقد فُصل هذا الحقل عمدًا عن clicks وعن impressions، ويجب أن يبقى منفصلًا بصريًا أينما عرضته. فتقديم التوقعات كأنها بيانات مقيسة هو الخطأ المعتاد في هذه الفئة من المنتجات.
└statusenumالقيم: newdismissedplannedpublished
└outlineAtيقبل nullstring
└articleAtيقبل nullstringلا تستنتجه من outlineAt. فوجود مخطط لا يعني وجود مسودة؛ وهما خطوتان مدفوعتان منفصلتان.
└totalQueriesintegerإجمالي عدد طلبات البحث المختلفة التي تغطيها هذه المواضيع.
الأخطاء المحتملة
401فشلت المصادقة
404site_not_found (قيمة siteId هذه لا تنتمي إلى هذا الحساب)

مثال

bash
curl "https://www.querywin.com/api/v1/topics" \
  -H "Authorization: Bearer $QUERYWIN_API_KEY"
json — الاستجابة
{
  "success": true,
  "data": {
    "siteId": "string",
    "topics": [
      {
        "key": "string",
        "title": "string",
        "shape": "comparison",
        "intent": "string",
        "members": [
          {
            "text": null,
            "impressions": null,
            "clicks": null,
            "position": null,
            "landingUrl": null
          }
        ],
        "impressions": 0,
        "clicks": 0,
        "position": 0,
        "competitor": true,
        "score": 0,
        "rank": 0,
        "upsideClicks": 0,
        "status": "new",
        "outlineAt": "2026-09-01T00:00:00.000Z",
        "articleAt": "2026-09-01T00:00:00.000Z"
      }
    ],
    "totalQueries": 0
  }
}
GET/v1/topics/article

قراءة مسودة سبق توليدها

لا يشغّل أي توليد، ولا تُخصم فيه أي نقاط. تكون قيمة article هي null إذا لم توجد مسودة بعد.

معاملات الاستعلام

الحقلالنوعالوصف
keyمطلوبstringمفتاح المجموعة من GET /v1/topics.
siteIdstringمن GET /v1/sites. إذا أُغفل، يُستخدم أول موقع رُبط بالحساب.

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataArticleResult
└articleيقبل nullArticle
└titlestring
└descriptionstringالوصف التعريفي للصفحة (meta description).
└markdownstringالنص الذي تنشره.
└jsonLdstringالبيانات المنظَّمة لهذه المقالة، مملوءة مسبقًا. وهي JSON صالح: ضعه داخل وسم script من النوع application/ld+json في الصفحة المنشورة.
└wordCountinteger
└warningsarray<ArticleWarning>عبارات تبدو كأنها من توليد الذكاء الاصطناعي. تظل المسودة صالحة للاستخدام، فهذه العبارات يُبلَّغ عنها بدلًا من إعادة كتابتها بصمت. سجّلها في السجلات. ففي المسار المؤتمت، هذه هي اللحظة الوحيدة التي يمكن أن يلاحظها فيها أحد.
└kindenumالقيم: banned_phrasebanned_wordem_dash_overuseno_short_sentence
└hitstringالنص موضع المشكلة.
└articleAtيقبل nullstring
└modelيقبل nullstring
الأخطاء المحتملة
400key_required
401فشلت المصادقة

مثال

bash
curl "https://www.querywin.com/api/v1/topics/article?key=..." \
  -H "Authorization: Bearer $QUERYWIN_API_KEY"
json — الاستجابة
{
  "success": true,
  "data": {
    "article": {
      "title": "string",
      "description": "string",
      "markdown": "string",
      "jsonLd": "string",
      "wordCount": 0,
      "warnings": [
        {
          "kind": "banned_phrase",
          "hit": "string"
        }
      ]
    },
    "articleAt": "2026-09-01T00:00:00.000Z",
    "model": "string"
  }
}
POST/v1/topics/article

تحويل المخطط إلى مسودة جاهزة للنشر (تُخصم نقاط)

أعلى الاستدعاءات تكلفة في المنتج. استدعاء متزامن، وقد يستغرق من دقيقة إلى دقيقتين.

يجب أن يوجد مخطط أولًا، وإلا تحصل على failure: "no_outline". فالمخطط هو ما يحمل الشواهد (طلبات البحث الفعلية وراء المجموعة، والصفحات التي يستشهد بها الذكاء الاصطناعي اليوم، واستبعاد التكرار مع صفحاتك الحالية). وتخطّيه يحوّل هذا الاستدعاء إلى مجرد أداة كتابة بالذكاء الاصطناعي لا يستند ما تكتبه إلى شيء.

article.markdown هو النص الذي تنشره. أما article.jsonLd فبيانات منظَّمة مملوءة مسبقًا بمحتوى هذه المقالة. وبالنسبة إلى article.warnings، سجّلها في السجلات ولا تتجاهلها: يشير كل تحذير إلى عبارة محددة تبدو كأنها من توليد الذكاء الاصطناعي، وفي المسار المؤتمت لا يعيد أحد قراءة المسودة قبل نشرها.

المسودات التي لا تجتاز التحقق من البنية (أقسام ناقصة، أو أسئلة مطلوبة بلا إجابة، أو روابط مختلقة، أو JSON-LD معطوب) تُستبعد، ولا تُخصم مقابلها أي نقاط.

متن الطلب

الحقلالنوعالوصف
keyمطلوبstringمفتاح المجموعة من GET /v1/topics.
siteIdstringإذا أُغفل، يُستخدم أول موقع رُبط بالحساب.
confirmSpendمطلوبintegerسقف تفويض بالنقاط، وليس مبلغًا دقيقًا. أرسل قيمة أكبر من السعر الحالي في GET /v1/usage أو مساوية له؛ ولا تُخصم إلا النقاط التي تكلّفها العملية فعلًا، وكثيرًا ما تكون صفرًا عند استخدام نتيجة مخزّنة مؤقتًا. وإذا تجاوز السعر سقفك يومًا، يُرفض الاستدعاء بدلًا من أن تُخصم نقاط إضافية بصمت. وهو مطلوب حتى إن بقيت لديك حصة مجانية؛ فالحصة ستنفد، ولا ينبغي أن تكون تلك هي اللحظة التي يكتشف فيها نصك البرمجي لأول مرة أن نقطة النهاية هذه مدفوعة. (min 0)

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataArticleOutcome
└okboolean
└failureenumيرد فقط عندما تكون قيمة ok هي false. وتظل حالة HTTP هي 200.القيم: topic_not_foundno_outlineengine_unavailableengine_failedno_valid_article
└articleيقبل nullArticle
└titlestring
└descriptionstringالوصف التعريفي للصفحة (meta description).
└markdownstringالنص الذي تنشره.
└jsonLdstringالبيانات المنظَّمة لهذه المقالة، مملوءة مسبقًا. وهي JSON صالح: ضعه داخل وسم script من النوع application/ld+json في الصفحة المنشورة.
└wordCountinteger
└warningsarray<ArticleWarning>عبارات تبدو كأنها من توليد الذكاء الاصطناعي. تظل المسودة صالحة للاستخدام، فهذه العبارات يُبلَّغ عنها بدلًا من إعادة كتابتها بصمت. سجّلها في السجلات. ففي المسار المؤتمت، هذه هي اللحظة الوحيدة التي يمكن أن يلاحظها فيها أحد.
└kindenumالقيم: banned_phrasebanned_wordem_dash_overuseno_short_sentence
└hitstringالنص موضع المشكلة.
└generatedbooleanتكون false عند إرجاع نتيجة مخزّنة مؤقتًا، ولا تُخصم أي نقاط.
└creditsSpentinteger
└freeUsedboolean
└rejectedarray<string>أوجه الخلل البنيوي التي أدت إلى استبعاد المسودة (ولا تُخصم مقابلها أي نقاط): missing_sections، missing_faq، invented_link، invalid_json_ld، comparison_without_contrast، body_too_short.
الأخطاء المحتملة
400key_required أو confirm_spend_required أو confirm_spend_too_low (يتضمن نص الاستجابة قيمة price الحالية)
401فشلت المصادقة
402insufficient_credits (يتضمن نص الاستجابة requiredCredits، currentBalance، shortfall)
403missing_scope_spend (لم يُمنح هذا المفتاح نطاق spend)
429rate_limited أو daily_limit_reached (يتضمن نص الاستجابة resetAt)

مثال

bash
curl -X POST https://www.querywin.com/api/v1/topics/article \
  -H "Authorization: Bearer $QUERYWIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "siteId": "clx1site000",
    "key": "standard wardrobe depth",
    "confirmSpend": 80
  }'
json — الاستجابة
{
  "success": true,
  "data": {
    "ok": true,
    "failure": "topic_not_found",
    "article": {
      "title": "string",
      "description": "string",
      "markdown": "string",
      "jsonLd": "string",
      "wordCount": 0,
      "warnings": [
        {
          "kind": "banned_phrase",
          "hit": "string"
        }
      ]
    },
    "generated": true,
    "creditsSpent": 0,
    "freeUsed": true,
    "rejected": [
      "string"
    ]
  }
}
GET/v1/topics/outline

قراءة مخطط سبق توليده

لا يشغّل أي توليد، ولا تُخصم فيه أي نقاط. تكون قيمة outline هي null إذا لم يوجد مخطط بعد.

معاملات الاستعلام

الحقلالنوعالوصف
keyمطلوبstringمفتاح المجموعة من GET /v1/topics.
siteIdstringمن GET /v1/sites. إذا أُغفل، يُستخدم أول موقع رُبط بالحساب.

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataOutlineResult
└outlineيقبل nullOutline
└titlestring
└slugstring
└anglestringالفكرة التي يجب أن تدافع عنها هذه الصفحة.
└sectionsarray<object>
└headingstring
└pointsarray<string>
└faqarray<object>الأسئلة التي يجب أن تجيب عنها الصفحة. وهي المواضع التي تقتبسها إجابات الذكاء الاصطناعي.
└questionstring
└answerstring
└schemaTypestringنوع JSON-LD المناسب لهذه الصفحة.
└internalLinksarray<string>صفحات في موقعك تستحق الربط إليها. مختارة من روابط حقيقية، ولا تُختلق أبدًا.
└outlineAtيقبل nullstring
└modelيقبل nullstring
الأخطاء المحتملة
400key_required
401فشلت المصادقة

مثال

bash
curl "https://www.querywin.com/api/v1/topics/outline?key=..." \
  -H "Authorization: Bearer $QUERYWIN_API_KEY"
json — الاستجابة
{
  "success": true,
  "data": {
    "outline": {
      "title": "string",
      "slug": "string",
      "angle": "string",
      "sections": [
        {
          "heading": "string",
          "points": []
        }
      ],
      "faq": [
        {
          "question": "string",
          "answer": "string"
        }
      ],
      "schemaType": "string",
      "internalLinks": [
        "string"
      ]
    },
    "outlineAt": "2026-09-01T00:00:00.000Z",
    "model": "string"
  }
}
POST/v1/topics/outline

توليد مخطط (تُخصم نقاط)

استدعاء متزامن؛ يستغرق عادةً من 10 إلى 20 ثانية.

عند تطابق المدخلات يُرجع المخطط المخزّن مؤقتًا، ولا تُخصم أي نقاط مرة أخرى؛ فالبصمة تشمل مجموعة الموضوع وتصنيفها بالنسبة إلى منافسيك، لذا يمكنك إعادة طلب HTTP الفاشل بأمان.

في نتائج المعالجة (المحرك غير متاح، أو المخرجات لم تجتز التحقق) يُرجع HTTP 200 مع ok: false ورمز في failure. أما نقص الرصيد فيُرجع خطأ 402 حقيقيًا.

متن الطلب

الحقلالنوعالوصف
keyمطلوبstringمفتاح المجموعة من GET /v1/topics.
siteIdstringإذا أُغفل، يُستخدم أول موقع رُبط بالحساب.
confirmSpendمطلوبintegerسقف تفويض بالنقاط، وليس مبلغًا دقيقًا. أرسل قيمة أكبر من السعر الحالي في GET /v1/usage أو مساوية له؛ ولا تُخصم إلا النقاط التي تكلّفها العملية فعلًا، وكثيرًا ما تكون صفرًا عند استخدام نتيجة مخزّنة مؤقتًا. وإذا تجاوز السعر سقفك يومًا، يُرفض الاستدعاء بدلًا من أن تُخصم نقاط إضافية بصمت. وهو مطلوب حتى إن بقيت لديك حصة مجانية؛ فالحصة ستنفد، ولا ينبغي أن تكون تلك هي اللحظة التي يكتشف فيها نصك البرمجي لأول مرة أن نقطة النهاية هذه مدفوعة. (min 0)

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataOutlineOutcome
└okboolean
└failureenumيرد فقط عندما تكون قيمة ok هي false. وتظل حالة HTTP هي 200؛ فهذه نتيجة معالجة وليست خطأ.القيم: topic_not_foundengine_unavailableengine_failedno_valid_outline
└outlineيقبل nullOutline
└titlestring
└slugstring
└anglestringالفكرة التي يجب أن تدافع عنها هذه الصفحة.
└sectionsarray<object>
└headingstring
└pointsarray<string>
└faqarray<object>الأسئلة التي يجب أن تجيب عنها الصفحة. وهي المواضع التي تقتبسها إجابات الذكاء الاصطناعي.
└questionstring
└answerstring
└schemaTypestringنوع JSON-LD المناسب لهذه الصفحة.
└internalLinksarray<string>صفحات في موقعك تستحق الربط إليها. مختارة من روابط حقيقية، ولا تُختلق أبدًا.
└generatedbooleanتكون false عند إرجاع نتيجة مخزّنة مؤقتًا، ولا تُخصم أي نقاط.
└creditsSpentinteger
└freeUsedboolean
└rejectedarray<string>قواعد التحقق التي أخفقت فيها مخرجات النموذج. ومن المفيد تسجيلها مؤشرًا على الجودة.
الأخطاء المحتملة
400key_required أو confirm_spend_required أو confirm_spend_too_low (يتضمن نص الاستجابة قيمة price الحالية)
401فشلت المصادقة
402insufficient_credits (يتضمن نص الاستجابة requiredCredits، currentBalance، shortfall)
403missing_scope_spend (لم يُمنح هذا المفتاح نطاق spend)
429rate_limited أو daily_limit_reached (يتضمن نص الاستجابة resetAt)

مثال

bash
curl -X POST https://www.querywin.com/api/v1/topics/outline \
  -H "Authorization: Bearer $QUERYWIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "siteId": "clx1site000",
    "key": "standard wardrobe depth",
    "confirmSpend": 80
  }'
json — الاستجابة
{
  "success": true,
  "data": {
    "ok": true,
    "failure": "topic_not_found",
    "outline": {
      "title": "string",
      "slug": "string",
      "angle": "string",
      "sections": [
        {
          "heading": "string",
          "points": []
        }
      ],
      "faq": [
        {
          "question": "string",
          "answer": "string"
        }
      ],
      "schemaType": "string",
      "internalLinks": [
        "string"
      ]
    },
    "generated": true,
    "creditsSpent": 0,
    "freeUsed": true,
    "rejected": [
      "string"
    ]
  }
}
POST/v1/topics/published

الإبلاغ عن مكان النشر

يُكمل هذا الاستدعاء الدورة: يضع على الموضوع علامة «منشور»، ويحفظ الرابط، ويُرسله إلى IndexNow نيابةً عنك.

يغطي IndexNow محركات Bing وYandex وSeznam وNaver، ولا يشمل Google. فليس لدى Google نقطة نهاية مماثلة للفهرسة الفورية، وهو يعثر على الصفحة عبر ملف sitemap الخاص بك.

لا يتسبب الإرسال إلى IndexNow أبدًا في فشل الطلب: فمقالتك منشورة بالفعل، وهذه هي الحقيقة التي يسجلها الاستدعاء. راجع حقل indexnow لمعرفة ما حدث فعلًا. ويتطلب الإرسال أن يكون ملف مفتاح IndexNow موثَّقًا للموقع (يُضبط مرة واحدة في لوحة التحكم).

وتسجيل الرابط هو أيضًا ما يمكّن QueryWin من إعادة قياس طلبات البحث التي تستهدفها هذه المقالة، بعد أن يمضي عليها وقت كافٍ لتؤتي أثرها.

متن الطلب

الحقلالنوعالوصف
keyمطلوبstring
siteIdstring
urlمطلوبstringالرابط الذي نشرت عليه المقالة. يُقبل http/https فقط، ولا تُجلب الصفحة في هذه المرحلة.

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataPublishedResult
└clusterKeystring
└statusenumالقيم: published
└publishedUrlstring
└publishedAtstring
└indexnowobjectيغطي Bing وYandex وSeznam وNaver، ولا يشمل Google.
└pushedboolean
└outcomestringتعني skipped غالبًا أن ملف المفتاح لم يُوثَّق بعد.
└enginesstring
الأخطاء المحتملة
400key_required أو url_required أو invalid_url (يُقبل http/https فقط)
401فشلت المصادقة
403missing_scope_publish (لم يُمنح هذا المفتاح نطاق publish)
404site_not_found

مثال

bash
curl -X POST https://www.querywin.com/api/v1/topics/published \
  -H "Authorization: Bearer $QUERYWIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "siteId": "clx1site000",
    "key": "standard wardrobe depth",
    "url": "https://example.com/blog/standard-wardrobe-depth"
  }'
json — الاستجابة
{
  "success": true,
  "data": {
    "clusterKey": "string",
    "status": "published",
    "publishedUrl": "string",
    "publishedAt": "2026-09-01T00:00:00.000Z",
    "indexnow": {
      "pushed": true,
      "outcome": "string",
      "engines": "string"
    }
  }
}

Distribution

GET/v1/campaigns

الحملات وحدود الإدراج في خطتك

الحملات (باستثناء المؤرشفة ما لم تمرّر includeArchived=true)، إلى جانب حدود الإدراج في الخطة والاستخدام الحالي. مجاني.

معاملات الاستعلام

الحقلالنوعالوصف
productIdstringحملات هذا المنتج فقط.
includeArchivedboolean

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataCampaignList
└campaignsarray<Campaign>
└campaignIdstring
└productIdstring
└namestring
└statusenumقيمة completed محسوبة: أي إن كل مهمة بلغت إحدى الحالات «منشورة» أو «تم التحقق» أو «فشلت» أو «تم التخطي».القيم: activecompletedarchived
└quotaintegerعدد القنوات التي أُنشئت بها الحملة.
└startsAtstring
└endsAtيقبل nullstring
└countsobject
└totalinteger
└submittedintegerمجموع submitted + published + verified.
└liveintegerمجموع published + verified.
└blockedinteger
└doneinteger
└byStatusobject
└createdAtstring
└quotaDistributionQuotaحدود الإدراج في الخطة والاستخدام الحالي. وإذا كانت قيمة الحد null فهو غير محدود.
└planstring
└limitsobject
└channelsيقبل nullintegerعدد القنوات المختلفة التي يمكن أن تكون لمنتج واحد مهام عليها، ويُعدّ خلال الفترة المحددة في channelsPeriod.
└channelsPeriodenummonth (الخطط المدفوعة): يُعدّ لكل شهر ميلادي (بتوقيت UTC)، فيتيح كل شهر دفعة جديدة من القنوات. total (الخطة المجانية): يُعدّ طوال عمر المنتج.القيم: monthtotal
└tasksPerMonthيقبل nullintegerعدد المهام التي يمكن إنشاؤها في كل شهر ميلادي (بتوقيت UTC)، لجميع المنتجات معًا.
└activeCampaignsيقبل nullintegerعدد الحملات التي يمكن أن تكون نشطة في الوقت نفسه.
└usageobject
└activeCampaignsinteger
└tasksThisMonthinteger
└channelsيقبل nullintegerيرد فقط إذا حدّد الطلب منتجًا.
الأخطاء المحتملة
401فشلت المصادقة

مثال

bash
curl "https://www.querywin.com/api/v1/campaigns" \
  -H "Authorization: Bearer $QUERYWIN_API_KEY"
json — الاستجابة
{
  "success": true,
  "data": {
    "campaigns": [
      {
        "campaignId": "string",
        "productId": "string",
        "name": "string",
        "status": "active",
        "quota": 0,
        "startsAt": "2026-09-01T00:00:00.000Z",
        "endsAt": "2026-09-01T00:00:00.000Z",
        "counts": {
          "total": 0,
          "submitted": 0,
          "live": 0,
          "blocked": 0,
          "done": 0,
          "byStatus": null
        },
        "createdAt": "2026-09-01T00:00:00.000Z"
      }
    ],
    "quota": {
      "plan": "string",
      "limits": {
        "channels": 0,
        "channelsPeriod": "month",
        "tasksPerMonth": 0,
        "activeCampaigns": 0
      },
      "usage": {
        "activeCampaigns": 0,
        "tasksThisMonth": 0,
        "channels": 0
      }
    }
  }
}
POST/v1/campaigns

إنشاء حملة من قائمة قنوات محددة صراحةً

مهمة واحدة لكل معرّف قناة، مع تجهيز مواد الإدراج الخاصة بها من ملف المنتج فورًا، ولا تُخصم أي نقاط. مرّر القنوات التي اخترتها فعلًا؛ فالحملة سجل للأماكن التي قررت الإرسال إليها، وليست عامل تصفية يوسّعه الخادم.

القنوات التي لدى المنتج عليها مهمة مفتوحة أو مُرسلة بالفعل تُتخطّى، وتُدرج في skipped مع السبب (already_open، already_submitted، not_found، broken، inactive، other_product، locked). وإذا لم يتبقَّ شيء، يُرجع الاستدعاء HTTP 200 مع ok: false وfailure: "no_valid_targets". أما تجاوز حدود الإدراج في الخطة فيُرفض بخطأ 409 (quota_exceeded، مع dimension، limit، used، requested)؛ ولا يُنشأ أي شيء، ولا حتى الجزء الذي كان يتسع له الحد.

متن الطلب

الحقلالنوعالوصف
productIdمطلوبstring
nameمطلوبstring
targetIdsمطلوبarray<string>معرّفات القنوات من GET /v1/channels. القنوات التي اخترتها فقط.
endsAtstringموعد نهائي اختياري يظهر في لوحة التحكم. ولا يُغلق أي شيء تلقائيًا.

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataCreateCampaignOutcome
└okboolean
└failureenumيرد عندما تكون قيمة ok هي false.القيم: no_valid_targets
└campaignCampaign
└campaignIdstring
└productIdstring
└namestring
└statusenumقيمة completed محسوبة: أي إن كل مهمة بلغت إحدى الحالات «منشورة» أو «تم التحقق» أو «فشلت» أو «تم التخطي».القيم: activecompletedarchived
└quotaintegerعدد القنوات التي أُنشئت بها الحملة.
└startsAtstring
└endsAtيقبل nullstring
└countsobject
└totalinteger
└submittedintegerمجموع submitted + published + verified.
└liveintegerمجموع published + verified.
└blockedinteger
└doneinteger
└byStatusobject
└createdAtstring
└tasksarray<Task>
└taskIdstring
└campaignIdstring
└productIdstring
└statusenumتمثّل published ما أبلغت عنه أنت، وتمثّل verified ما رآه QueryWin في صفحة الإدراج (رابطًا في الأدلة وقوائم أدوات الذكاء الاصطناعي، وإشارةً في غيرها). افصل بينهما عند إعداد التقارير.القيم: plannedpreparedin_progressblockedsubmittedpublishedverifiedfailedskipped
└blockedReasonيقبل nullenumالقيم: logincaptchapaymentmissing_materialothernull
└missingarray<string>مواد إدراج مطلوبة يفتقر إليها ملف المنتج. أكمل الملف في لوحة التحكم، وستُجهَّز المهمة من جديد تلقائيًا.
└listingUrlيقبل nullstring
└markedByenumالجهة التي أجرت آخر تغيير للحالة: شخص (أو هذه الواجهة البرمجية)، أو إضافة المتصفح، أو QueryWin نفسه.القيم: userdevicesystem
└hasGeneratedbooleanتوجد نسخة معاد كتابتها خصيصًا لهذه القناة.
└reviewDueAtيقبل nullstringموعد العودة للتحقق بعد الإرسال (submittedAt مضافًا إليه أيام المراجعة الخاصة بالقناة).
└submittedAtيقبل nullstring
└publishedAtيقبل nullstring
└verifiedAtيقبل nullstring
└nextarray<string>الحالات التي يمكنك ضبطها انطلاقًا من الحالة الحالية عبر POST /v1/tasks/{id}/status.
└targetobject
└targetIdstring
└namestring
└urlstring
└submitUrlstring
└kindstring
└sourceenumالقيم: seeduserrivals
└languagestring
└requiresBacklinkboolean
└checkيقبل nullobjectإعادة التحقق التي يجريها QueryWin على صفحة الإدراج بعد النشر. وتكون null حتى تُنشر المهمة.
└kindenumما يُبحث عنه: رابط إلى المنتج (في الأدلة وقوائم أدوات الذكاء الاصطناعي) أو إشارة إلى العلامة التجارية (في سائر القنوات).القيم: link_livemention_seen
└stateيقبل nullenumconfirmed: عُثر عليه. unconfirmed: لم يُعثر عليه في جولة تحقق واحدة (لم تتغير الحالة؛ تحقّق من الرابط). lost: كان موجودًا ثم اختفى (فشلت المهمة).القيم: confirmedunconfirmedlostnull
└checkedAtيقبل nullstring
└dueAtيقبل nullstring
└updatedAtstring
└skippedarray<object>
└targetIdstring
└reasonenumother_product: موقع يستشهد به الذكاء الاصطناعي لكنه تابع لمنتج آخر؛ inactive: قناة معطّلة أو مُتجاهَلة؛ locked: خارج ما تعرضه الخطة المجانية من مكتبة القنوات (أعلى القنوات ملاءمةً بعدد window، كما يُرجعها GET /v1/channels؛ ولا يسري هذا الحد على القنوات التي أضفتها بنفسك، ولا على المفضلة، ولا على المواقع التي يستشهد بها الذكاء الاصطناعي).القيم: not_foundbrokeninactiveother_productalready_openalready_submittedlocked
الأخطاء المحتملة
400product_id_required، أو name_required / name_too_long (80 حرفًا)، أو target_ids_required / too_many_targets (100 قناة)، أو invalid_date
401فشلت المصادقة
403missing_scope_publish (لم يُمنح هذا المفتاح نطاق publish)
404product_not_found (قيمة productId هذه لا تنتمي إلى هذا الحساب)
409quota_exceeded (يتضمن نص الاستجابة dimension بإحدى القيم active_campaigns / tasks_per_month / channels، إلى جانب limit، used، requested؛ وفي حالة channels يتضمن أيضًا period بالقيمة month أو total، كما في DistributionQuota.limits.channelsPeriod)

مثال

bash
curl -X POST https://www.querywin.com/api/v1/campaigns \
  -H "Authorization: Bearer $QUERYWIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "productId": "clx1prod000",
    "name": "Directories, September",
    "targetIds": [
      "clx1tgt001",
      "clx1tgt002"
    ]
  }'
json — الاستجابة
{
  "success": true,
  "data": {
    "ok": true,
    "failure": "no_valid_targets",
    "campaign": {
      "campaignId": "string",
      "productId": "string",
      "name": "string",
      "status": "active",
      "quota": 0,
      "startsAt": "2026-09-01T00:00:00.000Z",
      "endsAt": "2026-09-01T00:00:00.000Z",
      "counts": {
        "total": 0,
        "submitted": 0,
        "live": 0,
        "blocked": 0,
        "done": 0,
        "byStatus": null
      },
      "createdAt": "2026-09-01T00:00:00.000Z"
    },
    "tasks": [
      {
        "taskId": "string",
        "campaignId": "string",
        "productId": "string",
        "status": "planned",
        "blockedReason": "login",
        "missing": [
          "string"
        ],
        "listingUrl": "string",
        "markedBy": "user",
        "hasGenerated": true,
        "reviewDueAt": "2026-09-01T00:00:00.000Z",
        "submittedAt": "2026-09-01T00:00:00.000Z",
        "publishedAt": "2026-09-01T00:00:00.000Z",
        "verifiedAt": "2026-09-01T00:00:00.000Z",
        "next": [
          "string"
        ],
        "target": {
          "targetId": "string",
          "name": "string",
          "url": "string",
          "submitUrl": "string",
          "kind": "string",
          "source": "seed",
          "language": "string",
          "requiresBacklink": true
        },
        "check": {
          "kind": "link_live",
          "state": "confirmed",
          "checkedAt": "2026-09-01T00:00:00.000Z",
          "dueAt": "2026-09-01T00:00:00.000Z"
        },
        "updatedAt": "2026-09-01T00:00:00.000Z"
      }
    ],
    "skipped": [
      {
        "targetId": "string",
        "reason": "not_found"
      }
    ]
  }
}
GET/v1/campaigns/{id}

حملة واحدة مع مهامها

الحملة وجميع المهام فيها. مجاني.

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataCampaignDetail
└campaignCampaign
└campaignIdstring
└productIdstring
└namestring
└statusenumقيمة completed محسوبة: أي إن كل مهمة بلغت إحدى الحالات «منشورة» أو «تم التحقق» أو «فشلت» أو «تم التخطي».القيم: activecompletedarchived
└quotaintegerعدد القنوات التي أُنشئت بها الحملة.
└startsAtstring
└endsAtيقبل nullstring
└countsobject
└totalinteger
└submittedintegerمجموع submitted + published + verified.
└liveintegerمجموع published + verified.
└blockedinteger
└doneinteger
└byStatusobject
└createdAtstring
└tasksarray<Task>
└taskIdstring
└campaignIdstring
└productIdstring
└statusenumتمثّل published ما أبلغت عنه أنت، وتمثّل verified ما رآه QueryWin في صفحة الإدراج (رابطًا في الأدلة وقوائم أدوات الذكاء الاصطناعي، وإشارةً في غيرها). افصل بينهما عند إعداد التقارير.القيم: plannedpreparedin_progressblockedsubmittedpublishedverifiedfailedskipped
└blockedReasonيقبل nullenumالقيم: logincaptchapaymentmissing_materialothernull
└missingarray<string>مواد إدراج مطلوبة يفتقر إليها ملف المنتج. أكمل الملف في لوحة التحكم، وستُجهَّز المهمة من جديد تلقائيًا.
└listingUrlيقبل nullstring
└markedByenumالجهة التي أجرت آخر تغيير للحالة: شخص (أو هذه الواجهة البرمجية)، أو إضافة المتصفح، أو QueryWin نفسه.القيم: userdevicesystem
└hasGeneratedbooleanتوجد نسخة معاد كتابتها خصيصًا لهذه القناة.
└reviewDueAtيقبل nullstringموعد العودة للتحقق بعد الإرسال (submittedAt مضافًا إليه أيام المراجعة الخاصة بالقناة).
└submittedAtيقبل nullstring
└publishedAtيقبل nullstring
└verifiedAtيقبل nullstring
└nextarray<string>الحالات التي يمكنك ضبطها انطلاقًا من الحالة الحالية عبر POST /v1/tasks/{id}/status.
└targetobject
└targetIdstring
└namestring
└urlstring
└submitUrlstring
└kindstring
└sourceenumالقيم: seeduserrivals
└languagestring
└requiresBacklinkboolean
└checkيقبل nullobjectإعادة التحقق التي يجريها QueryWin على صفحة الإدراج بعد النشر. وتكون null حتى تُنشر المهمة.
└kindenumما يُبحث عنه: رابط إلى المنتج (في الأدلة وقوائم أدوات الذكاء الاصطناعي) أو إشارة إلى العلامة التجارية (في سائر القنوات).القيم: link_livemention_seen
└stateيقبل nullenumconfirmed: عُثر عليه. unconfirmed: لم يُعثر عليه في جولة تحقق واحدة (لم تتغير الحالة؛ تحقّق من الرابط). lost: كان موجودًا ثم اختفى (فشلت المهمة).القيم: confirmedunconfirmedlostnull
└checkedAtيقبل nullstring
└dueAtيقبل nullstring
└updatedAtstring
الأخطاء المحتملة
401فشلت المصادقة
404campaign_not_found

مثال

bash
curl "https://www.querywin.com/api/v1/campaigns/{id}" \
  -H "Authorization: Bearer $QUERYWIN_API_KEY"
json — الاستجابة
{
  "success": true,
  "data": {
    "campaign": {
      "campaignId": "string",
      "productId": "string",
      "name": "string",
      "status": "active",
      "quota": 0,
      "startsAt": "2026-09-01T00:00:00.000Z",
      "endsAt": "2026-09-01T00:00:00.000Z",
      "counts": {
        "total": 0,
        "submitted": 0,
        "live": 0,
        "blocked": 0,
        "done": 0,
        "byStatus": null
      },
      "createdAt": "2026-09-01T00:00:00.000Z"
    },
    "tasks": [
      {
        "taskId": "string",
        "campaignId": "string",
        "productId": "string",
        "status": "planned",
        "blockedReason": "login",
        "missing": [
          "string"
        ],
        "listingUrl": "string",
        "markedBy": "user",
        "hasGenerated": true,
        "reviewDueAt": "2026-09-01T00:00:00.000Z",
        "submittedAt": "2026-09-01T00:00:00.000Z",
        "publishedAt": "2026-09-01T00:00:00.000Z",
        "verifiedAt": "2026-09-01T00:00:00.000Z",
        "next": [
          "string"
        ],
        "target": {
          "targetId": "string",
          "name": "string",
          "url": "string",
          "submitUrl": "string",
          "kind": "string",
          "source": "seed",
          "language": "string",
          "requiresBacklink": true
        },
        "check": {
          "kind": "link_live",
          "state": "confirmed",
          "checkedAt": "2026-09-01T00:00:00.000Z",
          "dueAt": "2026-09-01T00:00:00.000Z"
        },
        "updatedAt": "2026-09-01T00:00:00.000Z"
      }
    ]
  }
}
GET/v1/channels

أين يمكن إرسال المنتج، مرتبةً حسب الملاءمة

مكتبة القنوات (الأدلة، ومنصات الإطلاق، وقوائم أدوات الذكاء الاصطناعي، والمجتمعات، ومنصات النشر)، والقنوات التي أضفتها بنفسك، وكذلك، عند تمرير productId، المواقع التي تستشهد بها إجابات الذكاء الاصطناعي بالفعل في طلبات البحث الخاصة بذلك المنتج (source: "rivals"). ومع productId تُرتَّب القائمة حسب الصلة، وتحمل كل قناة الحقل taskStatus (وتكون قيمته غير null إذا كانت للمنتج مهمة على تلك القناة بالفعل). مجاني.

يعني الحقل citedByAi أن إجابات الذكاء الاصطناعي استشهدت بذلك الموقع في طلبات البحث الخاصة بك، ولا يعني أن ذلك الموقع سيُدرج منتجك؛ فالتواصل مع الموقع وطلب الإدراج منه هو الغرض من المهمة.

معاملات الاستعلام

الحقلالنوعالوصف
productIdstringيرتّب النتائج حسب ملاءمتها لهذا المنتج، ويضيف taskStatus، ويضمّ أيضًا المواقع التي يستشهد بها الذكاء الاصطناعي في طلبات البحث الخاصة به.
kindstringنوع القناة.القيم: directorylaunchai_directorycommunitycontentother
sourcestringseed: مكتبة القنوات؛ user: قنوات أضفتها بنفسك؛ rivals: مواقع يستشهد بها الذكاء الاصطناعي لهذا المنتج.القيم: seeduserrivals
pricingstringتكلفة الإرسال.القيم: freeconditionalpaidunknown
submitMethodstringطريقة الإرسال: ملء نموذج، أو النشر في مجتمع، أو إرسال رسالة تعريفية بالبريد الإلكتروني.القيم: formpostemail
qstringالبحث في الاسم واسم النطاق والمواضيع.
hideSubmittedbooleanاستبعاد القنوات التي لدى هذا المنتج عليها مهمة مفتوحة أو مُرسلة. يتطلب productId.
pageintegerالقيمة الافتراضية 1.
pageSizeintegerالقيمة الافتراضية 30.

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataChannelList
└productIdيقبل nullstring
└itemsarray<Channel>
└targetIdstringمرّر هذه القيم في targetIds إلى POST /v1/campaigns.
└namestring
└urlstring
└submitUrlstringنموذج الإرسال أو صفحة النشر؛ وفي المواقع التي يستشهد بها الذكاء الاصطناعي، الصفحة الأكثر استشهادًا بها في إجاباته.
└kindenumالقيم: directorylaunchai_directorycommunitycontentother
└submitMethodenumform: ملء نموذج الإرسال الخاص بالقناة؛ post: النشر في المجتمع بنفسك؛ email: إرسال رسالة تعريفية إلى المحررين بالبريد الإلكتروني (يُقرأ العنوان من الصفحة عند فتحها، ولا يُخزَّن).القيم: formpostemail
└sourceenumseed: مكتبة القنوات؛ user: قناة أضفتها بنفسك؛ rivals: موقع تستشهد به إجابات الذكاء الاصطناعي في طلبات البحث الخاصة بهذا المنتج.القيم: seeduserrivals
└pricingTypeenumالقيم: freeconditionalpaidunknown
└priceNoteيقبل nullstring
└languagestringen أو zh أو multi، أو، في المواقع التي يستشهد بها الذكاء الاصطناعي، رمز لغة مستنتج من طلبات البحث.
└topicsarray<string>
└requiresAccountboolean
└requiresBacklinkboolean
└reviewDaysيقبل nullintegerمدة المراجعة المعتادة. وتذكّرك المهمة بالعودة للتحقق بعد انقضائها.
└siteRankيقبل nullintegerالترتيب العالمي في قائمة Tranco العامة (كلما قلّ الرقم زادت الزيارات). null: خارج أول مليون موقع. وهذا ليس مقياس Domain Rating.
└hasFormSpecbooleanحقول نموذج هذه القناة مسجّلة لدينا، لذا تُقتطع مواد الإدراج وفق حدودها بدقة.
└relevanceيقبل nullintegerدرجة الملاءمة للمنتج المحدد في الطلب. تُستخدم للترتيب فقط.
└taskStatusيقبل nullstringمهمة المنتج المفتوحة أو المكتملة على هذه القناة، إن وُجدت. null: لا توجد مهمة بعد.
└citedByAiيقبل nullobjectيرد فقط مع source: "rivals". استشهدت إجابات الذكاء الاصطناعي بهذا الموقع في طلبات البحث المذكورة، وهذا ليس وعدًا بأن الموقع سيُدرج منتجك؛ فطلب الإدراج هو الغرض من المهمة.
└queriesintegerعدد طلبات البحث المختلفة التي استُشهد به فيها.
└samplesintegerعدد عيّنات إجابات الذكاء الاصطناعي التي استشهدت به.
└searchesarray<string>
└pagesarray<string>الصفحات التي استُشهد بها، الأكثر استشهادًا أولًا. وتكون فارغة في العيّنات الأقدم التي لم تسجّل إلا اسم النطاق.
└totalinteger
└pageinteger
└pageSizeinteger
└limitedbooleanفي الخطة المجانية لا تُرجَع إلا القنوات الأولى بعدد window وفق الترتيب الافتراضي (الأكثر ملاءمة للمنتج المحدد في productId)، وتُرفض معاملات التصفية والبحث والترتيب بالخطأ 403 library_locked. وتظل total معبّرة عن الحجم الكامل لمكتبة القنوات.
└windowيقبل nullintegerعدد القنوات المعروضة في الخطة المجانية: 20 في الأساس، ويُضاف 20 عن كل صديق أنشأ حسابًا عبر رابط الدعوة الخاص بك (ويُضاف 20 أيضًا إذا أنشأت حسابك أنت عبر رابط دعوة). تكون القيمة null عندما لا تكون القائمة محدودة.
الأخطاء المحتملة
401فشلت المصادقة

مثال

bash
curl "https://www.querywin.com/api/v1/channels" \
  -H "Authorization: Bearer $QUERYWIN_API_KEY"
json — الاستجابة
{
  "success": true,
  "data": {
    "productId": "string",
    "items": [
      {
        "targetId": "string",
        "name": "string",
        "url": "string",
        "submitUrl": "string",
        "kind": "directory",
        "submitMethod": "form",
        "source": "seed",
        "pricingType": "free",
        "priceNote": "string",
        "language": "string",
        "topics": [
          "string"
        ],
        "requiresAccount": true,
        "requiresBacklink": true,
        "reviewDays": 0,
        "siteRank": 0,
        "hasFormSpec": true,
        "relevance": 0,
        "taskStatus": "string",
        "citedByAi": {
          "queries": 0,
          "samples": 0,
          "searches": [],
          "pages": []
        }
      }
    ],
    "total": 0,
    "page": 0,
    "pageSize": 0,
    "limited": true,
    "window": 0
  }
}
GET/v1/products

منتجاتك ومدى اكتمال ملف كل منتج

ابدأ من هنا في مسار الإدراج؛ فكل نقاط نهاية الإدراج الأخرى تأخذ productId. تأتي قيمة completeness وقيمة missing من ملف المنتج المحفوظ: الحقل الفارغ فيه يبقى فارغًا في كل طلب إدراج، والنواقص المطلوبة توقف المهمة بالحالة blocked / missing_material إلى أن يكتمل الملف. اقرأه باستخدام GET /v1/products/{id} واملأه باستخدام PATCH /v1/products/{id}. مجاني.

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataProductList
└productsarray<Product>
└productIdstring
└namestring
└urlstring
└domainstring
└primaryLanguageenumالقيم: enzhjakodefresptitrunlpltrarthviid
└topicsarray<string>
└completenessintegerنسبة اكتمال ملف المنتج، من 0 إلى 100. املأ الحقول الناقصة في لوحة التحكم أو باستخدام PATCH /v1/products/{id}.
└missingarray<string>حقول ملف المنتج الفارغة. وكل حقل منها يبقى فارغًا في كل طلب إدراج.
└sitesarray<object>
└siteIdstring
└domainstring
└syncedThroughيقبل nullstring
الأخطاء المحتملة
401فشلت المصادقة

مثال

bash
curl "https://www.querywin.com/api/v1/products" \
  -H "Authorization: Bearer $QUERYWIN_API_KEY"
json — الاستجابة
{
  "success": true,
  "data": {
    "products": [
      {
        "productId": "string",
        "name": "string",
        "url": "string",
        "domain": "string",
        "primaryLanguage": "en",
        "topics": [
          "string"
        ],
        "completeness": 0,
        "missing": [
          "string"
        ],
        "sites": [
          {
            "siteId": null,
            "domain": null,
            "syncedThrough": null
          }
        ]
      }
    ]
  }
}
POST/v1/products

إنشاء منتج

يتطلب نطاق publish وخطة مدفوعة. يُنشئ منتجًا من رابط عام لصفحته الرئيسية واسم اختياري، ويشغل مكانًا ضمن الحد الأقصى لعدد المنتجات في خطتك، ولا تُخصم أي نقاط. يُرجع ملف المنتج المحفوظ كاملًا، ثم املأه باستخدام PATCH /v1/products/{id}. لا يزحف إلى الموقع ولا يشغّل الذكاء الاصطناعي. إذا كان اسم النطاق مسجّلًا من قبل، يُرجع 409 product_exists مع قيمة productId للمنتج الموجود؛ فأعد استخدامها إذا فُقدت الاستجابة. القيم الافتراضية للمنتج قيم قابلة للتعديل، وليست حقائق موثّقة عن الموقع.

متن الطلب

الحقلالنوعالوصف
urlمطلوبstring
namestring

الاستجابة201

الحقلالنوعالوصف
successboolean
dataProductDetail
└namestring
└urlstring
└primaryLanguageenumالقيم: enzhjakodefresptitrunlpltrarthviid
└businessTypeenumالقيم: saastoolecommercecontentserviceother
└launchStatusenumالقيم: livebeta
└pricingModelenumالقيم: freefreemiumpaidtrial
└taglineيقبل nullobject
└shortDescيقبل nullobject
└longDescيقبل nullobject
└firstCommentيقبل nullobject
└topicsarray<string>
└promoCodeيقبل nullstring
└videoUrlيقبل nullstring
└demoUrlيقبل nullstring
└linksيقبل nullobject
└webAppstring
└appStorestring
└playStorestring
└chromeExtensionstring
└macosstring
└windowsstring
└socialsيقبل nullobject
└xstring
└linkedinstring
└githubstring
└instagramstring
└youtubestring
└facebookstring
└contactNameيقبل nullstring
└contactEmailيقبل nullstring
└galleryarray<string>
└productIdstring
└domainstring
└thumbnailUrlيقبل nullstring
└completenessinteger (0–100)
└missingarray<string>
└createdAtstring
└updatedAtstring
└sitesarray<object>
└siteIdstring
└domainstring
└syncedThroughيقبل nullstring
الأخطاء المحتملة
400invalid_product_input أو invalid_url أو url_not_public
401فشلت المصادقة
403plan_required، أو missing_scope_publish في عمليات الكتابة
409product_exists (مع productId للمنتج الموجود) أو product_limit_reached
429rate_limited (بحد 120 طلبًا في الدقيقة لكل مفتاح)

مثال

bash
curl -X POST https://www.querywin.com/api/v1/products \
  -H "Authorization: Bearer $QUERYWIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "name": "Example"
  }'
json — الاستجابة
{
  "success": true,
  "data": {
    "name": "string",
    "url": "string",
    "primaryLanguage": "en",
    "businessType": "saas",
    "launchStatus": "live",
    "pricingModel": "free",
    "tagline": null,
    "shortDesc": null,
    "longDesc": null,
    "firstComment": null,
    "topics": [
      "string"
    ],
    "promoCode": "string",
    "videoUrl": "string",
    "demoUrl": "string",
    "links": {
      "webApp": "string",
      "appStore": "string",
      "playStore": "string",
      "chromeExtension": "string",
      "macos": "string",
      "windows": "string"
    },
    "socials": {
      "x": "string",
      "linkedin": "string",
      "github": "string",
      "instagram": "string",
      "youtube": "string",
      "facebook": "string"
    },
    "contactName": "string",
    "contactEmail": "string",
    "gallery": [
      "string"
    ],
    "productId": "string",
    "domain": "string",
    "thumbnailUrl": "string",
    "completeness": 0,
    "missing": [
      "string"
    ],
    "createdAt": "2026-09-01T00:00:00.000Z",
    "updatedAt": "2026-09-01T00:00:00.000Z",
    "sites": [
      {
        "siteId": "string",
        "domain": "string",
        "syncedThrough": "string"
      }
    ]
  }
}
PATCH/v1/products/{id}

ملء ملف المنتج أو تحديثه

يتطلب نطاق publish. يحفظ الحقول المُرسلة وحدها فورًا؛ وتستبدل الكائنات (ومنها النصوص بكل لغة) والمصفوفات الحقل بأكمله، لذا اقرأ ملف المنتج أولًا للحفاظ على اللغات الأخرى. لا تُخصم أي نقاط، ولا يُولَّد أي محتوى بالذكاء الاصطناعي. تُحدَّث مواد الإدراج الخاصة بالمهام التي لم تُرسل بعد بشكل غير متزامن. استخدم الحقائق المعروفة فقط، ولا تختلق تفاصيل المنتج الناقصة.

متن الطلب

الحقلالنوعالوصف
namestring
urlstring
primaryLanguageenumالقيم: enzhjakodefresptitrunlpltrarthviid
businessTypeenumالقيم: saastoolecommercecontentserviceother
launchStatusenumالقيم: livebeta
pricingModelenumالقيم: freefreemiumpaidtrial
taglineobject
shortDescobject
longDescobject
firstCommentobject
topicsarray<string>
promoCodestring
videoUrlstring
demoUrlstring
linksobject
└webAppstring
└appStorestring
└playStorestring
└chromeExtensionstring
└macosstring
└windowsstring
socialsobject
└xstring
└linkedinstring
└githubstring
└instagramstring
└youtubestring
└facebookstring
contactNamestring
contactEmailstring
galleryarray<string>

الاستجابة200

الحقلالنوعالوصف
successboolean
dataProductDetail
└namestring
└urlstring
└primaryLanguageenumالقيم: enzhjakodefresptitrunlpltrarthviid
└businessTypeenumالقيم: saastoolecommercecontentserviceother
└launchStatusenumالقيم: livebeta
└pricingModelenumالقيم: freefreemiumpaidtrial
└taglineيقبل nullobject
└shortDescيقبل nullobject
└longDescيقبل nullobject
└firstCommentيقبل nullobject
└topicsarray<string>
└promoCodeيقبل nullstring
└videoUrlيقبل nullstring
└demoUrlيقبل nullstring
└linksيقبل nullobject
└webAppstring
└appStorestring
└playStorestring
└chromeExtensionstring
└macosstring
└windowsstring
└socialsيقبل nullobject
└xstring
└linkedinstring
└githubstring
└instagramstring
└youtubestring
└facebookstring
└contactNameيقبل nullstring
└contactEmailيقبل nullstring
└galleryarray<string>
└productIdstring
└domainstring
└thumbnailUrlيقبل nullstring
└completenessinteger (0–100)
└missingarray<string>
└createdAtstring
└updatedAtstring
└sitesarray<object>
└siteIdstring
└domainstring
└syncedThroughيقبل nullstring
الأخطاء المحتملة
400invalid_product_input أو invalid_url أو url_not_public أو invalid_email أو invalid_gallery
401فشلت المصادقة
403plan_required، أو missing_scope_publish في عمليات الكتابة
404product_not_found
409product_exists (مع productId للمنتج الموجود)
429rate_limited (بحد 120 طلبًا في الدقيقة لكل مفتاح)

مثال

bash
curl -X PATCH https://www.querywin.com/api/v1/products/{id} \
  -H "Authorization: Bearer $QUERYWIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tagline": {
      "en": "Your product tagline",
      "zh": "你的产品标语"
    },
    "shortDesc": {
      "en": "A factual description of the product."
    },
    "topics": [
      "productivity",
      "developer-tools"
    ],
    "contactEmail": "hello@example.com"
  }'
json — الاستجابة
{
  "success": true,
  "data": {
    "name": "string",
    "url": "string",
    "primaryLanguage": "en",
    "businessType": "saas",
    "launchStatus": "live",
    "pricingModel": "free",
    "tagline": null,
    "shortDesc": null,
    "longDesc": null,
    "firstComment": null,
    "topics": [
      "string"
    ],
    "promoCode": "string",
    "videoUrl": "string",
    "demoUrl": "string",
    "links": {
      "webApp": "string",
      "appStore": "string",
      "playStore": "string",
      "chromeExtension": "string",
      "macos": "string",
      "windows": "string"
    },
    "socials": {
      "x": "string",
      "linkedin": "string",
      "github": "string",
      "instagram": "string",
      "youtube": "string",
      "facebook": "string"
    },
    "contactName": "string",
    "contactEmail": "string",
    "gallery": [
      "string"
    ],
    "productId": "string",
    "domain": "string",
    "thumbnailUrl": "string",
    "completeness": 0,
    "missing": [
      "string"
    ],
    "createdAt": "2026-09-01T00:00:00.000Z",
    "updatedAt": "2026-09-01T00:00:00.000Z",
    "sites": [
      {
        "siteId": "string",
        "domain": "string",
        "syncedThrough": "string"
      }
    ]
  }
}
GET/v1/products/{id}

قراءة ملف المنتج كاملًا

يُرجع النصوص المحفوظة بكل لغة، والروابط، وبيانات التواصل، والصور، ونسبة الاكتمال، والحقول الناقصة. يكفيه نطاق read، ولا تُخصم أي نقاط. ويُرجع أيضًا product_not_found إذا كان المنتج لا ينتمي إلى مساحة العمل هذه.

الاستجابة200

الحقلالنوعالوصف
successboolean
dataProductDetail
└namestring
└urlstring
└primaryLanguageenumالقيم: enzhjakodefresptitrunlpltrarthviid
└businessTypeenumالقيم: saastoolecommercecontentserviceother
└launchStatusenumالقيم: livebeta
└pricingModelenumالقيم: freefreemiumpaidtrial
└taglineيقبل nullobject
└shortDescيقبل nullobject
└longDescيقبل nullobject
└firstCommentيقبل nullobject
└topicsarray<string>
└promoCodeيقبل nullstring
└videoUrlيقبل nullstring
└demoUrlيقبل nullstring
└linksيقبل nullobject
└webAppstring
└appStorestring
└playStorestring
└chromeExtensionstring
└macosstring
└windowsstring
└socialsيقبل nullobject
└xstring
└linkedinstring
└githubstring
└instagramstring
└youtubestring
└facebookstring
└contactNameيقبل nullstring
└contactEmailيقبل nullstring
└galleryarray<string>
└productIdstring
└domainstring
└thumbnailUrlيقبل nullstring
└completenessinteger (0–100)
└missingarray<string>
└createdAtstring
└updatedAtstring
└sitesarray<object>
└siteIdstring
└domainstring
└syncedThroughيقبل nullstring
الأخطاء المحتملة
401فشلت المصادقة
403plan_required، أو missing_scope_publish في عمليات الكتابة
404product_not_found
429rate_limited (بحد 120 طلبًا في الدقيقة لكل مفتاح)

مثال

bash
curl "https://www.querywin.com/api/v1/products/{id}" \
  -H "Authorization: Bearer $QUERYWIN_API_KEY"
json — الاستجابة
{
  "success": true,
  "data": {
    "name": "string",
    "url": "string",
    "primaryLanguage": "en",
    "businessType": "saas",
    "launchStatus": "live",
    "pricingModel": "free",
    "tagline": null,
    "shortDesc": null,
    "longDesc": null,
    "firstComment": null,
    "topics": [
      "string"
    ],
    "promoCode": "string",
    "videoUrl": "string",
    "demoUrl": "string",
    "links": {
      "webApp": "string",
      "appStore": "string",
      "playStore": "string",
      "chromeExtension": "string",
      "macos": "string",
      "windows": "string"
    },
    "socials": {
      "x": "string",
      "linkedin": "string",
      "github": "string",
      "instagram": "string",
      "youtube": "string",
      "facebook": "string"
    },
    "contactName": "string",
    "contactEmail": "string",
    "gallery": [
      "string"
    ],
    "productId": "string",
    "domain": "string",
    "thumbnailUrl": "string",
    "completeness": 0,
    "missing": [
      "string"
    ],
    "createdAt": "2026-09-01T00:00:00.000Z",
    "updatedAt": "2026-09-01T00:00:00.000Z",
    "sites": [
      {
        "siteId": "string",
        "domain": "string",
        "syncedThrough": "string"
      }
    ]
  }
}
POST/v1/products/{id}/images/from-url

استيراد صورة للمنتج من رابط

يتطلب نطاق publish. يجلب صورة عامة عبر HTTP(S) ويحفظ نسخة منها صورةً مصغّرة (تحلّ محل الحالية) أو في معرض الصور (تُضاف في آخره، بحد أقصى 6 صور). الصيغ المقبولة JPEG وPNG وWebP وSVG، بحجم أقصاه 4 ميغابايت؛ وتُحوَّل صور SVG إلى PNG. تحظر أداة جلب الصور الحالية الوصول إلى الشبكات الخاصة وعمليات إعادة التوجيه غير الآمنة. لا تُخصم أي نقاط. قد يؤدي تكرار الاستيراد إلى المعرض إلى صور مكررة؛ فإذا فُقدت الاستجابة، اقرأ المنتج باستخدام GET قبل إعادة المحاولة.

متن الطلب

الحقلالنوعالوصف
urlمطلوبstring
kindenumالقيم: thumbnailgalleryالقيمة الافتراضية gallery

الاستجابة200

الحقلالنوعالوصف
successboolean
dataProductDetail
└namestring
└urlstring
└primaryLanguageenumالقيم: enzhjakodefresptitrunlpltrarthviid
└businessTypeenumالقيم: saastoolecommercecontentserviceother
└launchStatusenumالقيم: livebeta
└pricingModelenumالقيم: freefreemiumpaidtrial
└taglineيقبل nullobject
└shortDescيقبل nullobject
└longDescيقبل nullobject
└firstCommentيقبل nullobject
└topicsarray<string>
└promoCodeيقبل nullstring
└videoUrlيقبل nullstring
└demoUrlيقبل nullstring
└linksيقبل nullobject
└webAppstring
└appStorestring
└playStorestring
└chromeExtensionstring
└macosstring
└windowsstring
└socialsيقبل nullobject
└xstring
└linkedinstring
└githubstring
└instagramstring
└youtubestring
└facebookstring
└contactNameيقبل nullstring
└contactEmailيقبل nullstring
└galleryarray<string>
└productIdstring
└domainstring
└thumbnailUrlيقبل nullstring
└completenessinteger (0–100)
└missingarray<string>
└createdAtstring
└updatedAtstring
└sitesarray<object>
└siteIdstring
└domainstring
└syncedThroughيقبل nullstring
الأخطاء المحتملة
400invalid_product_input أو invalid_url
401فشلت المصادقة
403plan_required، أو missing_scope_publish في عمليات الكتابة
404product_not_found
409gallery_full
413image_too_large
415image_type
429rate_limited (بحد 120 طلبًا في الدقيقة لكل مفتاح)
502image_unreachable
503storage_unavailable

مثال

bash
curl -X POST https://www.querywin.com/api/v1/products/{id}/images/from-url \
  -H "Authorization: Bearer $QUERYWIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/logo.png",
    "kind": "thumbnail"
  }'
json — الاستجابة
{
  "success": true,
  "data": {
    "name": "string",
    "url": "string",
    "primaryLanguage": "en",
    "businessType": "saas",
    "launchStatus": "live",
    "pricingModel": "free",
    "tagline": null,
    "shortDesc": null,
    "longDesc": null,
    "firstComment": null,
    "topics": [
      "string"
    ],
    "promoCode": "string",
    "videoUrl": "string",
    "demoUrl": "string",
    "links": {
      "webApp": "string",
      "appStore": "string",
      "playStore": "string",
      "chromeExtension": "string",
      "macos": "string",
      "windows": "string"
    },
    "socials": {
      "x": "string",
      "linkedin": "string",
      "github": "string",
      "instagram": "string",
      "youtube": "string",
      "facebook": "string"
    },
    "contactName": "string",
    "contactEmail": "string",
    "gallery": [
      "string"
    ],
    "productId": "string",
    "domain": "string",
    "thumbnailUrl": "string",
    "completeness": 0,
    "missing": [
      "string"
    ],
    "createdAt": "2026-09-01T00:00:00.000Z",
    "updatedAt": "2026-09-01T00:00:00.000Z",
    "sites": [
      {
        "siteId": "string",
        "domain": "string",
        "syncedThrough": "string"
      }
    ]
  }
}
GET/v1/tasks

المهام في جميع الحملات

سجل الإرسال، مرتبًا من الأحدث نشاطًا. يمكنك التصفية حسب المنتج أو الحملة أو قائمة حالات مفصولة بفواصل. ويعدّ byStatus كل المهام المطابقة قبل تطبيق تصفية الحالة. مجاني.

معاملات الاستعلام

الحقلالنوعالوصف
productIdstringمهام هذا المنتج فقط.
campaignIdstring
statusstringمفصولة بفواصل، مثل prepared,in_progress.
pageintegerالقيمة الافتراضية 1.
pageSizeintegerالقيمة الافتراضية 30.

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataTaskList
└itemsarray<Task>
└taskIdstring
└campaignIdstring
└productIdstring
└statusenumتمثّل published ما أبلغت عنه أنت، وتمثّل verified ما رآه QueryWin في صفحة الإدراج (رابطًا في الأدلة وقوائم أدوات الذكاء الاصطناعي، وإشارةً في غيرها). افصل بينهما عند إعداد التقارير.القيم: plannedpreparedin_progressblockedsubmittedpublishedverifiedfailedskipped
└blockedReasonيقبل nullenumالقيم: logincaptchapaymentmissing_materialothernull
└missingarray<string>مواد إدراج مطلوبة يفتقر إليها ملف المنتج. أكمل الملف في لوحة التحكم، وستُجهَّز المهمة من جديد تلقائيًا.
└listingUrlيقبل nullstring
└markedByenumالجهة التي أجرت آخر تغيير للحالة: شخص (أو هذه الواجهة البرمجية)، أو إضافة المتصفح، أو QueryWin نفسه.القيم: userdevicesystem
└hasGeneratedbooleanتوجد نسخة معاد كتابتها خصيصًا لهذه القناة.
└reviewDueAtيقبل nullstringموعد العودة للتحقق بعد الإرسال (submittedAt مضافًا إليه أيام المراجعة الخاصة بالقناة).
└submittedAtيقبل nullstring
└publishedAtيقبل nullstring
└verifiedAtيقبل nullstring
└nextarray<string>الحالات التي يمكنك ضبطها انطلاقًا من الحالة الحالية عبر POST /v1/tasks/{id}/status.
└targetobject
└targetIdstring
└namestring
└urlstring
└submitUrlstring
└kindstring
└sourceenumالقيم: seeduserrivals
└languagestring
└requiresBacklinkboolean
└checkيقبل nullobjectإعادة التحقق التي يجريها QueryWin على صفحة الإدراج بعد النشر. وتكون null حتى تُنشر المهمة.
└kindenumما يُبحث عنه: رابط إلى المنتج (في الأدلة وقوائم أدوات الذكاء الاصطناعي) أو إشارة إلى العلامة التجارية (في سائر القنوات).القيم: link_livemention_seen
└stateيقبل nullenumconfirmed: عُثر عليه. unconfirmed: لم يُعثر عليه في جولة تحقق واحدة (لم تتغير الحالة؛ تحقّق من الرابط). lost: كان موجودًا ثم اختفى (فشلت المهمة).القيم: confirmedunconfirmedlostnull
└checkedAtيقبل nullstring
└dueAtيقبل nullstring
└updatedAtstring
└totalinteger
└pageinteger
└pageSizeinteger
└byStatusobject
الأخطاء المحتملة
401فشلت المصادقة

مثال

bash
curl "https://www.querywin.com/api/v1/tasks" \
  -H "Authorization: Bearer $QUERYWIN_API_KEY"
json — الاستجابة
{
  "success": true,
  "data": {
    "items": [
      {
        "taskId": "string",
        "campaignId": "string",
        "productId": "string",
        "status": "planned",
        "blockedReason": "login",
        "missing": [
          "string"
        ],
        "listingUrl": "string",
        "markedBy": "user",
        "hasGenerated": true,
        "reviewDueAt": "2026-09-01T00:00:00.000Z",
        "submittedAt": "2026-09-01T00:00:00.000Z",
        "publishedAt": "2026-09-01T00:00:00.000Z",
        "verifiedAt": "2026-09-01T00:00:00.000Z",
        "next": [
          "string"
        ],
        "target": {
          "targetId": "string",
          "name": "string",
          "url": "string",
          "submitUrl": "string",
          "kind": "string",
          "source": "seed",
          "language": "string",
          "requiresBacklink": true
        },
        "check": {
          "kind": "link_live",
          "state": "confirmed",
          "checkedAt": "2026-09-01T00:00:00.000Z",
          "dueAt": "2026-09-01T00:00:00.000Z"
        },
        "updatedAt": "2026-09-01T00:00:00.000Z"
      }
    ],
    "total": 0,
    "page": 0,
    "pageSize": 0,
    "byStatus": null
  }
}
GET/v1/tasks/{id}

مهمة واحدة مع مواد الإدراج المطلوب إرسالها

كل حقل يطلبه نموذج القناة، مقتطعًا من ملف المنتج وفق حدود القناة (source: "profile")، إضافةً إلى النسخة المعاد كتابتها لهذه القناة إن وُجدت (source: "ai")، وأي تعديلات أُجريت في لوحة التحكم (source: "override"). وتعني source: "none" أن ملف المنتج لا يحتوي على شيء لهذا الحقل، فلا تختلقه. لا يشغّل أي إعادة كتابة، ولا تُخصم فيه أي نقاط.

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataTaskDetailResult
└taskTaskDetail
الأخطاء المحتملة
401فشلت المصادقة
404task_not_found

مثال

bash
curl "https://www.querywin.com/api/v1/tasks/{id}" \
  -H "Authorization: Bearer $QUERYWIN_API_KEY"
json — الاستجابة
{
  "success": true,
  "data": {
    "task": null
  }
}
POST/v1/tasks/{id}/materials

إعادة كتابة مواد الإدراج لهذه القناة (تُخصم نقاط)

معالجة واحدة بالذكاء الاصطناعي تكيّف ملف المنتج مع هذه القناة تحديدًا: وصف أكثر إيجازًا للدليل، أو التعليق الأول لصاحب المنتج، أو منشور في المجتمع، أو رسالة تعريفية إلى محرر، أو، في المواقع التي يستشهد بها الذكاء الاصطناعي، رسالة تعريفية مع فقرة يمكن لصاحب الصفحة إضافتها. استدعاء متزامن يستغرق بضع ثوانٍ. لا يستخدم إلا الحقائق الموجودة في ملف المنتج؛ وأي جزء يحتوي على رابط غير موجود في الملف يُستبعد، ولا تُخصم مقابله أي نقاط.

عند تطابق المدخلات تُرجَع النسخة السابقة ولا تُخصم أي نقاط (cached: true)؛ أما force: true فيعيد الكتابة على أي حال وتُخصم نقاط. وغالبًا ما تكفي مواد ملف المنتج التي يُرجعها GET /v1/tasks/{id} للأدلة؛ فأعد الكتابة حين تطلب القناة أسلوبًا مختلفًا.

يُرجع HTTP 200 مع ok: false وfailure: "engine_failed" إذا لم يجتز أي جزء التحقق. أما نقص الرصيد فيُرجع خطأ 402 حقيقيًا.

متن الطلب

الحقلالنوعالوصف
confirmSpendمطلوبintegerسقف التفويض بالنقاط، بالمعنى نفسه كما في المخططات والمسودات. اقرأ السعر من GET /v1/usage (materials.pricePerTask). وهو مطلوب حتى ما دامت لديك حصة مجانية متبقية. (min 0)
forcebooleanيعيد الكتابة حتى لو لم يتغير شيء منذ النسخة السابقة. وتُخصم نقاط.

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataWriteMaterialsOutcome
└okboolean
└failureenumيرد عندما تكون قيمة ok هي false. ولا تُخصم أي نقاط.القيم: engine_failedengine_unavailable
└cachedbooleanلم تتغير المدخلات؛ فأُرجعت النسخة السابقة، ولا تُخصم أي نقاط.
└freeUsedboolean
└creditsSpentinteger
└taskTaskDetail
الأخطاء المحتملة
400confirm_spend_required أو confirm_spend_too_low (يتضمن نص الاستجابة قيمة price الحالية)
401فشلت المصادقة
402insufficient_credits (يتضمن نص الاستجابة requiredCredits، currentBalance، shortfall)
403missing_scope_spend (لم يُمنح هذا المفتاح نطاق spend)
404task_not_found
429rate_limited أو daily_limit_reached (يتضمن نص الاستجابة resetAt)

مثال

bash
curl -X POST https://www.querywin.com/api/v1/tasks/{id}/materials \
  -H "Authorization: Bearer $QUERYWIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "confirmSpend": 10
  }'
json — الاستجابة
{
  "success": true,
  "data": {
    "ok": true,
    "failure": "engine_failed",
    "cached": true,
    "freeUsed": true,
    "creditsSpent": 0,
    "task": null
  }
}
POST/v1/tasks/{id}/status

الإبلاغ عن نتيجة الإرسال

سجّل نتيجة طلب إدراج أرسلته بحساباتك الخاصة. لا يرسل QueryWin أي شيء إلى أي مكان بنفسه. اضبط الحالة على submitted بعد إرسال النموذج، ثم على published مع رابط صفحة الإدراج (الإدخال أو المنشور نفسه، لا الصفحة الرئيسية للموقع) بعد نشرها؛ ويعيد QueryWin التحقق من تلك الصفحة بعد نحو 72 ساعة بحثًا عن رابط إلى منتجك (في الأدلة وقوائم أدوات الذكاء الاصطناعي) أو إشارة إليه (في سائر القنوات)، ثم يضبط الحالة verified بنفسه، ولا يمكنك أنت ضبط هذه الحالة.

تعني blocked أن المهمة «تحتاج إلى تدخل شخص»: مرّر reason (login، captcha، payment، missing_material، other). وتُغلق failed / skipped المهمة، وتُعيدها prepared إلى الانتظار. والانتقالات التي لا تسمح بها آلة الحالات تُرجع خطأ 409 (transition_not_allowed)؛ ويسرد الحقل next في المهمة الحالات المسموح بها انطلاقًا من حالتها الحالية.

متن الطلب

الحقلالنوعالوصف
statusمطلوبenumلا يمكن ضبط الحالة verified؛ إذ يضبطها QueryWin بنفسه بعد إعادة التحقق من صفحة الإدراج.القيم: preparedin_progressblockedsubmittedpublishedfailedskipped
listingUrlstringمطلوب مع published: رابط الإدخال أو المنشور بعد نشره، لا الصفحة الرئيسية للموقع. يُقبل http/https فقط. واختياري مع submitted إن كنت تعرفه بالفعل.
notestring
reasonenumمطلوب مع blocked.القيم: logincaptchapaymentmissing_materialother

الاستجابة200

الحقلالنوعالوصف
successenumالقيم: true
dataTaskDetailResult
└taskTaskDetail
الأخطاء المحتملة
400invalid_status، أو listing_url_required (تتطلب الحالة published الحقل listingUrl)، أو invalid_listing_url، أو reason_required (تتطلب الحالة blocked الحقل reason)
401فشلت المصادقة
403missing_scope_publish (لم يُمنح هذا المفتاح نطاق publish)
404task_not_found
409transition_not_allowed (اقرأ المهمة؛ فالحقل next يسرد الحالات المسموح بها)

مثال

bash
curl -X POST https://www.querywin.com/api/v1/tasks/{id}/status \
  -H "Authorization: Bearer $QUERYWIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "published",
    "listingUrl": "https://example-directory.com/tools/your-product"
  }'
json — الاستجابة
{
  "success": true,
  "data": {
    "task": null
  }
}
QueryWin API — مسارا المحتوى والإدراج للنصوص البرمجية ووكلاء الذكاء الاصطناعي