مواد پر جائیں
دستاویزات

ڈیلیوری ویب ہُک: اپنی سائٹ پر مضامین وصول کرنا

دستخط شدہ ویب ہُک جو AutoPSEO کے مضامین آپ کی سائٹ تک پہنچاتا ہے: ہیڈرز، ہر ایونٹ اور اس کا پے لوڈ، جو جوابات دینے ہیں، ری ٹرائی، انتظار میں پڑی کمانڈز اور IndexNow۔

پراپرٹی ← کنٹینٹ ← مضامین کہاں شائع ہوتے ہیں23 منٹ کا مطالعہ

AutoPSEO جو مضمون بھی شائع کرتا ہے، اپ ڈیٹ کرتا ہے یا ہٹاتا ہے، اسے دستخط شدہ HTTPS POST کی صورت میں آپ کی اپنی سائٹ پر بھیجتا ہے۔ آپ کی سائٹ مضمون کو محفوظ کرتی ہے اور اپنے ٹیمپلیٹس سے دکھاتی ہے، یوں مواد آپ کے اپنے سسٹم میں رہتا ہے اور اگر آپ کبھی AutoPSEO چھوڑ دیں تب بھی کام کرتا رہتا ہے۔ یہ صفحہ اس ڈیولپر کے لیے حوالہ ہے جو ریسیور بنا رہا ہو: دستخط، ہر ایونٹ اپنے پے لوڈ کے ساتھ، وہ جوابات جنہیں AutoPSEO پڑھتا ہے، ری ٹرائی، انتظار میں پڑی کمانڈز اور IndexNow۔

ویب ہُک سیٹ اپ کریں

  1. پراپرٹی کا Content صفحہ کھولیں اور Where articles are published پر جائیں۔
  2. Webhook address on your site بھریں۔ یہ کسی عوامی ہوسٹ نام پر https:// URL ہونا چاہیے: IP ایڈریس اور localhost قبول نہیں کیے جاتے۔ AutoPSEO ری ڈائریکٹ کو فالو نہیں کرتا، اس لیے حتمی ایڈریس دیں۔
  3. Your site's address بھریں، مثلاً https://example.com۔ ہر کنٹینٹ ٹائپ کا پاتھ اسی کے نیچے آتا ہے، لہٰذا /answers پر موجود ٹائپ کا مضمون https://example.com/answers/<slug> پر ہوگا۔
  4. Save and send a test منتخب کریں۔ AutoPSEO ایک سائننگ سیکرٹ بناتا ہے (whsec_ کے بعد 48 ہیکس حروف) اور آپ کے ایڈریس کو پنگ کرتا ہے۔ جو ریسیور دستخط چیک کرتا ہے وہ یہ پہلا پنگ ناکام کر دیتا ہے، کیونکہ اس کے پاس ابھی سیکرٹ نہیں ہوتا۔
  5. Show یا Copy سے Signing secret سامنے لائیں، اسے اپنی سائٹ پر سیکرٹ کے طور پر محفوظ کریں، پھر Send a test منتخب کریں۔
  6. What your site handles پڑھیں: ہر کمانڈ کے آگے Connected، Not connected، Declared, not tested یا Not tested دکھائی دیتا ہے۔

نئی پراپرٹیز پر ابتدا میں مضامین AutoPSEO کے اپنے ایڈریس پر ہوسٹ ہوتے ہیں (دیکھیں Hosting)، اور ہوسٹنگ اور ویب ہُک ساتھ ساتھ چل سکتے ہیں۔ جب آپ کی سائٹ مضامین دکھانے لگے تو Stop hosting on AutoPSEO منتخب کریں: ہر لائیو مضمون آپ کی سائٹ کے ایڈریس پر منتقل ہو جاتا ہے اور آپ کے ویب ہُک کو article.published کے طور پر بھیجا جاتا ہے۔ اس بٹن کے لیے ضروری ہے کہ ویب ہُک نے اپنے آخری ٹیسٹ کا جواب دیا ہو اور آپ کی سائٹ کا ایڈریس موجود ہو۔ جب تک ہوسٹنگ بند ہے، ویب ہُک کو ہٹایا نہیں جا سکتا۔

New secret سائننگ سیکرٹ کو فوراً بدل دیتا ہے اور پرانا سیکرٹ اسی لمحے تصدیق کرنا چھوڑ دیتا ہے۔ نیا سیکرٹ بناتے ہی اسے اپنی سائٹ پر لگا دیں۔

AutoPSEO صرف اسی ویب ہُک کے لیے ڈیلیوریز قطار میں لگاتا ہے جس کے آخری پنگ کا جواب 2xx آیا ہو۔ ناکام پنگ (محفوظ کرتے وقت، Send a test پر، یا سائٹ اسکین کے آغاز پر) ویب ہُک کو خرابی کی حالت میں ڈال دیتا ہے، اور خرابی کے دوران شائع ہونے والے مضامین اس کے لیے قطار میں نہیں لگتے۔ ping کا جواب دیتے رہیں، اور کسی بندش کے ٹھیک ہونے کے بعد Send a test منتخب کریں۔

ہیڈرز اور دستخط

ہر درخواست JSON باڈی اور درج ذیل ہیڈرز کے ساتھ ایک POST ہوتی ہے:

ہیڈرقدر
Content-Typeapplication/json
User-AgentAutoPSEO-Webhook/1
X-AutoPSEO-Eventایونٹ کا نام، جو باڈی میں بھی event کے طور پر ہوتا ہے
X-AutoPSEO-Deliveryڈیلیوری کی آئی ڈی، جو باڈی میں بھی id کے طور پر ہوتی ہے۔ ایک ڈیلیوری کی ہر ری ٹرائی پر یہی رہتی ہے
X-AutoPSEO-Timestampاس کوشش پر دستخط کے وقت کا یونکس ٹائم، سیکنڈز میں
X-AutoPSEO-Signaturesha256= کے بعد <timestamp>.<raw body> کا ہیکس HMAC-SHA256

درخواست کی تصدیق کے لیے:

  1. ٹائم اسٹیمپ ہیڈر، ایک فل اسٹاپ، اور درخواست کی خام باڈی لیں، بالکل ویسی جیسی پہنچی ہو، JSON پارس کرنے سے پہلے۔
  2. اس اسٹرنگ پر HMAC-SHA256 نکالیں۔ کلید پورا سائننگ سیکرٹ ہے جیسا ایپ دکھاتی ہے، whsec_ سابقے سمیت، UTF-8 بائٹس کی صورت میں۔
  3. نتیجے کو ہیکس میں انکوڈ کریں اور X-AutoPSEO-Signature میں sha256= کے بعد والے حصے سے constant time میں موازنہ کریں۔ اگر دونوں مختلف ہوں تو درخواست مسترد کر دیں۔

ہر کوشش پر اپنے ٹائم اسٹیمپ کے ساتھ نئے سرے سے دستخط ہوتے ہیں، اس لیے آپ ایسی درخواستیں رد کر سکتے ہیں جن کا ٹائم اسٹیمپ آپ کی گھڑی سے بہت دور ہو (پانچ منٹ عام حد ہے) اور ری ٹرائی متاثر نہیں ہوتی۔ HMAC کی تعریف خود RFC 2104 میں موجود ہے۔

ہر باڈی میں id، event، occurredAt (ISO 8601، UTC) اور site: { propertyId, domain } شامل ہوتے ہیں۔

ایونٹس

ایونٹقسمAutoPSEO اسے کب بھیجتا ہے
pingجانچویب ہُک محفوظ کرتے وقت، Send a test پر، اور ہر سائٹ اسکین کے آغاز پر
testجانچکامیاب پنگ کے فوراً بعد، ہر کمانڈ کے لیے ایک
article.publishedڈیلیوریکوئی مضمون پہلی بار لائیو ہوتا ہے؛ ہوسٹنگ بند کرنے پر ہر لائیو مضمون
article.updatedڈیلیورینیا ریویژن لائیو ہوتا ہے (ریفریش، آپٹیمائزیشن، رول بیک، ہٹائے جانے کے بعد دوبارہ شائع کرنا، زبانوں کا اضافہ) یا کور شامل کیا گیا
article.unpublishedڈیلیوریکوئی مضمون ہٹایا جاتا ہے، یا کسی دوسرے صفحے میں ضم کر دیا جاتا ہے
path.addڈیلیوریٹائپڈ کنٹینٹ ٹائپ کی کوئی نئی ویلیو منظور ہوئی
path.removeڈیلیوریکسی نے ویلیو کا پاتھ ہٹانے کی درخواست کی
path.checkکالاس سے پہلے کہ AutoPSEO کسی ایسے ایڈریس پر صفحہ منصوبہ بنائے جہاں آپ کی سائٹ پر صفحہ نہیں، یا کوئی نئی ویلیو تجویز کرے
site.exportکالسائٹ اسکین کے دوران، روزانہ ٹاپک سنک میں، اور کسی لائیو مضمون میں تبدیلی سے پہلے
articles.adoptedکالاس اسکین کے بعد جس نے آپ کی سائٹ کے ایکسپورٹ کیے ہوئے مضامین امپورٹ کیے
site.handoverکالجب کوئی کنٹینٹ ٹائپس کی تحریر AutoPSEO کے سپرد کرے، یا واپس لے

ڈیلیوریز ایک آؤٹ باکس کے ذریعے جاتی ہیں: وہ تبدیلی کے ساتھ اسی ڈیٹابیس بیچ میں ریکارڈ ہوتی ہیں، فوراً بھیجی جاتی ہیں، دوبارہ آزمائی جاتی ہیں، اور آپ کی سائٹ کے انتظار میں رک بھی سکتی ہیں۔ کالز سادہ درخواست اور جواب ہوتی ہیں: AutoPSEO جواب اسی لمحے پڑھ لیتا ہے۔ پاتھ کمانڈز کب بھیجی جاتی ہیں، یہ Typed pages and new paths میں بیان ہے۔

مضمون کا پے لوڈ

article.published اور article.updated پورا مضمون لے کر آتے ہیں، تمام زبانوں سمیت:

{
  "id": "0f6d2c1e-7a51-4c1b-9d0e-5b8f3a2e9c41",
  "event": "article.published",
  "occurredAt": "2026-10-12T08:30:00.000Z",
  "site": { "propertyId": "prop_123", "domain": "example.com" },
  "article": {
    "id": "a4c09e2b-6f1d-4e57-8b3a-1d2e3f4a5b6c",
    "slug": "plan-a-content-calendar",
    "path": "/answers/plan-a-content-calendar",
    "type": { "key": "answers", "name": "Answers", "path": "/answers" },
    "lang": "en",
    "langs": ["en", "de"],
    "rev": 1,
    "url": "https://example.com/answers/plan-a-content-calendar",
    "datePublished": "2026-10-12",
    "dateModified": "2026-10-12",
    "contentHash": "9f2c4e1a7b3d5f6081a2c3d4",
    "writer": "platform",
    "category": "Planning",
    "copy": {
      "title": "How to plan a content calendar",
      "metaDescription": "A content calendar in five steps, with a template.",
      "h1": "How to plan a content calendar",
      "directAnswer": "List your topics, give each a date and an owner, then review the plan weekly.",
      "keyTakeaways": ["Plan a quarter at a time.", "Give every piece one owner."],
      "sections": [{ "heading": "Start from your topics", "bodyHtml": "<p>Begin with the searches you want to win.</p>" }],
      "faq": [{ "q": "How far ahead should I plan?", "a": "One quarter is enough for most teams." }],
      "sources": [{ "title": "Creating helpful content", "url": "https://developers.google.com/search/docs/fundamentals/creating-helpful-content" }]
    },
    "translations": { "de": { "title": "Einen Redaktionsplan erstellen", "h1": "Einen Redaktionsplan erstellen" } },
    "cover": {
      "url": "https://app.autopseo.com/media/covers/prop_123/<sha256>.jpg",
      "sha256": "<sha256>",
      "contentType": "image/jpeg",
      "width": 1536,
      "height": 1024
    }
  }
}

جرمن اندراج یہاں مختصر کیا گیا ہے؛ ہر ترجمے کی ساخت copy جیسی ہوتی ہے۔

فیلڈمطلب
idمضمون کے لیے AutoPSEO کی آئی ڈی۔ یہ کبھی نہیں بدلتی، اس لیے اسے بطور کلید استعمال کرنا محفوظ ہے
slugایڈریس کا آخری حصہ۔ ٹائپڈ صفحات پر اس میں / سے جڑے سیگمنٹس ہوتے ہیں، جیسے google/software-engineer
pathآپ کی سائٹ کے لحاظ سے ایڈریس: ٹائپ کا پاتھ اور اس کے ساتھ slug۔ صفحہ بننے کے بعد طے رہتا ہے
type{ key, name, path }۔ key مستقل رہتی ہے؛ path وہ جگہ ہے جہاں اس ٹائپ کے مضامین ہوتے ہیں (سائٹ کی جڑ کے لیے خالی)
lang, langsبنیادی زبان اور اس ریویژن کی تمام زبانیں
revریویژن نمبر
urlمکمل ایڈریس جیسا AutoPSEO اسے جانتا ہے: ہوسٹنگ بند ہونے کے بعد آپ کی سائٹ کا، یا وہ url جو آپ کے ریسیور نے آخری بار جواب میں دیا
datePublished, dateModifiedYYYY-MM-DD۔ اشاعت کی تاریخ بعد کے ریویژنز میں بھی وہی رہتی ہے
contentHashریویژن کی شناختی فنگر پرنٹ
writerریویژن کس نے لکھا: platform (AutoPSEO)، mcp (آپ کا اپنا AI)، user، import (آپ کی سائٹ کی اپنی تحریر) یا aggregate (فہرست والا صفحہ)
copyبنیادی زبان میں مضمون
translationsباقی زبانیں، زبان کے کوڈ کی کلید کے ساتھ
categoryاس کے لیے آپ کی سائٹ کی کیٹیگری، جب آپ کا فارمیٹ کیٹیگریز رکھتا ہو
topic{ externalId, keyword } جب مضمون کسی ایسے ٹاپک کے لیے لکھا گیا ہو جو آپ کی سائٹ نے سپرد کیا تھا، تاکہ آپ وہ ٹاپک بند کر سکیں
partsٹائپڈ صفحات پر، ہر حصے کی ویلیو: { "company": "google", "role": "software-engineer" }
kindفہرست والے صفحے پر "list"۔ اس کی copy { title, h1, items: [{ from, text }] } ہوتی ہے، جہاں from اس صفحے کا پاتھ ہے جس سے ہر آئٹم آیا، اور parts اس ویلیو کا نام بتاتا ہے جسے یہ جمع کرتا ہے
coverAutoPSEO کا بنایا ہوا کور۔ اسے ایک بار حاصل کریں اور اپنی کاپی رکھیں؛ ایڈریس کبھی نہیں بدلتا کیونکہ فائل کا نام تصویر کا SHA-256 ہے
basedOnarticle.updated پر: آپ کے صفحے کا وہ ورژن جس سے یہ ریویژن لکھا گیا (نیچے تنازعات دیکھیں)
redirectToانضمام کے بعد article.unpublished پر: پرانا ایڈریس اب کہاں لے جاتا ہے۔ اس کا جواب 301 سے دیں اور وہاں کچھ نیا نہ رکھیں

article.unpublished میں وہی article فیلڈز ہوتی ہیں سوائے copy، translations، category اور cover کے۔

copy کے اندر

فیلڈمطلب
title, metaDescription, h1صفحے کا عنوان، میٹا تفصیل اور سرخی
directAnswerمختصر جواب جو سب سے پہلے دکھایا جاتا ہے
keyTakeawaysاسٹرنگز کی فہرست
sections[{ heading, bodyHtml }]
faq[{ q, a }]
sources[{ title, url, lastVerified? }]
questionاختیاری: تلاش کرنے والے کا سوال اسی کے الفاظ میں، جب آپ کا فارمیٹ اسے مانگے
categoryاختیاری: آپ کی سائٹ کی کیٹیگریز میں سے ایک
listsاختیاری: کلید کے حساب سے سادہ متن کی فہرستیں، ان کنٹینٹ ٹائپس کے لیے جو انہیں مانگتی ہیں (انٹرویو گائیڈ کے نمونہ سوالات)

AutoPSEO کے لکھے مضامین میں bodyHtml صرف p، ul، li، strong، em، a اور code استعمال کرتا ہے، اور لنکس میں صرف ان کا href رہتا ہے۔ آپ کی اپنی سائٹ سے لیا گیا متن آپ کا HTML برقرار رکھتا ہے۔ اگر آپ کے ٹیمپلیٹس کو سینیٹائزر درکار ہو تو اسے اپنے سینیٹائزر سے بھی گزاریں۔

آپ کا ریسیور کیا جواب دے

کوئی بھی 2xx ڈیلیوری مکمل کر دیتا ہے۔ AutoPSEO جواب کی باڈی سے ایک اختیاری JSON آبجیکٹ بھی پڑھتا ہے؛ اسے 64 KB سے کم رکھیں، کیونکہ اس سے بڑا جواب ناکامی شمار ہوتا ہے۔

فیلڈاثر
urlوہ https:// ایڈریس جہاں مضمون اب موجود ہے۔ AutoPSEO اسے مضمون کے URL کے طور پر درج کرتا ہے
versionآپ کے صفحے کا ورژن، ایک مبہم اسٹرنگ جو زیادہ سے زیادہ 128 حروف کی ہو۔ یہ اگلی اپ ڈیٹ کے ساتھ basedOn بن کر واپس آتا ہے
urlsوہ https:// ایڈریس جو اس ڈیلیوری نے بدلے، IndexNow کے لیے (ہر زبان، یا وہ ایڈریس جن کی سروس آپ نے بند کی)۔ [] کا مطلب ہے کچھ نہیں بدلا
cover"wanted" جب آپ کے پاس مضمون کے لیے کور نہ ہو اور ڈیلیوری میں بھی کوئی کور نہ آیا ہو۔ AutoPSEO ایک کور بناتا ہے اور اسے article.updated میں بھیجتا ہے

خرابی کے جوابات کے مختلف معنی ہیں:

آپ کا جوابAutoPSEO اسے کیا سمجھتا ہےکیا ہوتا ہے
{ "error": "unknown_event" } کے ساتھ 4xx، یا 501آپ ابھی یہ کمانڈ ہینڈل نہیں کرتےڈیلیوری بغیر ری ٹرائی کے انتظار میں رہتی ہے
{ "error": "conflict" } کے ساتھ 409اپ ڈیٹ ایسے ورژن سے لکھی گئی تھی جو آپ کے صفحے کے پاس اب نہیں رہاڈیلیوری بغیر ری ٹرائی کے ناکام ہو جاتی ہے، اور مضمون کی اگلی تبدیلی سے پہلے اسے آپ کی سائٹ سے دوبارہ پڑھا جاتا ہے
path.add یا path.remove کو { "error": "<code>", "details": [] } کے ساتھ 408 یا 429 کے علاوہ کوئی 4xxآپ کی وجہ کے ساتھ انکاردرج کر لیا جاتا ہے؛ دیکھیں Typed pages and new paths
اس کے علاوہ کچھ بھی: 10 سیکنڈ میں جواب نہیں، نیٹ ورک کی خرابی، ری ڈائریکٹ، 408، 429، 5xx یا کوئی اور 4xxعارضی ناکامیبیک آف کے ساتھ دوبارہ آزمایا جاتا ہے

ری ٹرائی اور منسوخ شدہ ڈیلیوریز

ڈیلیوری تبدیلی محفوظ ہوتے ہی بھیج دی جاتی ہے، اور پانچ منٹ کا شیڈول جو کچھ بھی واجب الادا ہو اسے، سب سے پرانے سے شروع کرکے، بھیجتا ہے۔ عارضی ناکامی کے بعد AutoPSEO کوششوں کے درمیان 1 منٹ، پھر 5 منٹ، 15 منٹ، 1 گھنٹہ، 3 گھنٹے، 6 گھنٹے اور 12 گھنٹے انتظار کرتا ہے۔ آٹھویں ناکام کوشش ڈیلیوری کو ناکام قرار دے دیتی ہے، اور Content صفحہ اسے ویب ہُک کے ساتھ سرخ بیج میں گنتا ہے۔

جب اسی مضمون کی نئی ڈیلیوری موجود ہو تو پرانی، جو ابھی زیر التوا ہو، superseded نشان زد ہو جاتی ہے اور کبھی نہیں بھیجی جاتی۔ ہر ڈیلیوری پورا مضمون لاتی ہے، اس لیے آپ کی سائٹ کو صرف تازہ ترین ڈیلیوری درکار ہے۔ ایک ہی ویلیو کے بارے میں پاتھ کمانڈز بھی اسی طرح کام کرتی ہیں۔

آپ کا ریسیور ایک ہی ڈیلیوری دو بار دیکھ سکتا ہے، مثلاً جب اس نے مضمون محفوظ کر لیا مگر 10 سیکنڈ کی مہلت کے بعد جواب دیا۔ X-AutoPSEO-Delivery پر ڈپلیکیٹ ہٹائیں، یا article.id پر محفوظ کرکے ہر تحریر کو idempotent بنائیں۔ article.updated ایسے مضمون تک بھی پہنچ سکتا ہے جسے آپ نے article.unpublished کے بعد حذف کر دیا ہو، کیونکہ ہٹائے گئے مضمون کو دوبارہ شائع کرنے پر اپ ڈیٹ بھیجی جاتی ہے: اپ ڈیٹس کو "بناؤ یا بدل دو" سمجھیں۔

وہ کمانڈز جنہیں آپ کی سائٹ ابھی ہینڈل نہیں کرتی

کوئی سائٹ پروٹوکول کو ایک وقت میں ایک کمانڈ کر کے نافذ کر سکتی ہے۔ AutoPSEO ہر کمانڈ کی حالت یاد رکھتا ہے اور اسے تین طریقوں سے جانتا ہے:

  • ٹیسٹ۔ ہر کامیاب پنگ کے بعد AutoPSEO ہر کمانڈ کے لیے ایک test بھیجتا ہے۔ باڈی { id, event: "test", occurredAt, site, test: { event: "<command>", ... } } ہوتی ہے، جہاں test میں حقیقی کمانڈ جیسی ساخت کا نمونہ ہوتا ہے جو <type path>/autopseo-connection-test کے بارے میں ہے، ایسا ایڈریس جو کسی سائٹ پر نہیں ہوتا۔ اسے ویسے ہی جانچیں جیسے حقیقی کمانڈ کو جانچتے، کچھ نہ بدلیں، اور 2xx سے جواب دیں: Connected کے لیے { "test": "<command>", "ok": true }، Not connected کے لیے { "test": "<command>", "ok": false, "error": "unknown_event" }۔ ok: false اور کسی اور ایرر کوڈ کے ساتھ جواب، جیسے ایسے ایڈریس کا ہٹایا جانا جو آپ کے پاس نہیں، پھر بھی connected شمار ہوتا ہے۔ نمونہ ہمیشہ test کے نیچے ہوتا ہے، اوپری سطح پر کبھی نہیں، تاکہ جو ریسیور ٹیسٹ کے بارے میں کچھ نہیں جانتا اسے اس میں کوئی مضمون نہ ملے۔
  • حقیقی ڈیلیوریز اور کالز۔ 2xx کمانڈ کو connected نشان زد کرتا ہے؛ unknown_event اسے not connected کرتا ہے۔
  • پنگ کا جواب۔ جو کمانڈز آپ کا جواب autopseo.events میں گنواتا ہے وہ Declared, not tested دکھائی دیتی ہیں جب تک کوئی ٹیسٹ یا ڈیلیوری مزید نہ بتائے۔

جو کمانڈ connected نہ ہو، اس کی ڈیلیوری انتظار کرتی ہے۔ Content صفحہ بتاتا ہے کہ کیا انتظار میں ہے، مثلاً "Your site does not take articles down yet"، اور جو کام آپ نے ہاتھ سے کر لیا ہو اس کے لیے Done on the site بٹن ہوتا ہے؛ پھر AutoPSEO وہ ڈیلیوری کبھی نہیں بھیجتا۔ جب بعد کا کوئی ٹیسٹ یا ڈیلیوری کمانڈ کو connected پائے تو اس پر انتظار کرتی ہر چیز بھیج دی جاتی ہے۔

پنگ کا جواب

ping کا جواب 2xx سے دیں۔ جو سائٹ صرف مضامین وصول کرتی ہے اسے اس سے زیادہ کچھ نہیں چاہیے۔ AutoPSEO کو یہ بتانے کے لیے کہ آپ کی سائٹ اور کیا کرتی ہے، ایک autopseo آبجیکٹ شامل کریں:

{
  "ok": true,
  "autopseo": {
    "version": 1,
    "events": ["article.published", "article.updated", "article.unpublished"],
    "covers": true,
    "indexNow": { "key": "3f1c9a7e5b2d4f60", "keyLocation": "https://example.com/3f1c9a7e5b2d4f60.txt" },
    "export": ["articles", "topics", "profile"],
    "adopt": true,
    "handover": true,
    "types": ["answers"],
    "writer": "site"
  }
}
فیلڈمطلب
version1۔ جب تک ورژن 1 یا اس سے زیادہ نہ ہو آبجیکٹ نظرانداز کر دیا جاتا ہے
eventsوہ کمانڈز جو آپ ہینڈل کرتے ہیں، جب تک ٹیسٹ نہ ہو declared دکھائی جاتی ہیں
coverstrue جب آپ کے صفحات ہر مضمون کے ساتھ کور دکھاتے ہوں۔ تب AutoPSEO کا رائٹر لکھتے وقت ہی کور بناتا ہے، اس لیے پہلی ڈیلیوری میں وہ شامل ہوتا ہے، اور آپ کے اپنے AI سے بھی کور فراہم کرنے کو کہا جاتا ہے۔ دیکھیں Covers
indexNow{ key, keyLocation? }: وہ IndexNow کلید جو آپ سرو کرتے ہیں (8 سے 128 حروف، ہندسے اور ڈیش) اور، جب کلید کی فائل /<key>.txt پر نہ ہو، اس کا https:// مقام
exportsite.export کیا فراہم کرتا ہے: articles، topics، profile
adoptآپ articles.adopted قبول کرتے ہیں، تاکہ مکمل اسکین آپ کے موجودہ مضامین اپنے ہاتھ میں لے سکے
handoverآپ site.handover قبول کرتے ہیں
typesوہ کنٹینٹ ٹائپ کیز جو آپ قبول کرتے ہیں (زیادہ سے زیادہ 50)
writerآج آپ کے نئے مضامین کون لکھتا ہے: site یا autopseo

آپ کے سرو کیے گئے ایڈریسز کے لیے IndexNow

جب آپ کا پنگ جواب indexNow ظاہر کرے تو AutoPSEO آپ کی قبول کردہ ڈیلیوریز کے بعد api.indexnow.org پر IndexNow کو پنگ کرتا ہے، اور آپ کی سائٹ خود کچھ پنگ نہیں کرتی۔

  • یہ آپ کے جواب کے درج کردہ urls بھیجتا ہے۔ urls کے بغیر یہ آپ کے جواب کا url بھیجتا ہے، ورنہ مضمون کا URL۔ urls: [] کچھ نہیں بھیجتا۔
  • صرف آپ کے اپنے ہوسٹ کے ایڈریس شامل ہوتے ہیں، جیسا کہ IndexNow protocol تقاضا کرتا ہے: keyLocation کا ہوسٹ، ورنہ آپ کی سائٹ کے ایڈریس کا ہوسٹ۔
  • ہر ڈیلیوری رن فی سائٹ ایک پنگ بھیجتا ہے، جس میں زیادہ سے زیادہ 10,000 ایڈریس ہوتے ہیں۔
  • 200 اور 202 قبول ہیں۔ 429، 5xx یا جواب نہ آنے پر ایڈریس محفوظ رہتے ہیں اور ایک گھنٹے بعد دوبارہ کوشش ہوتی ہے، ہر بار دگنا وقفہ، زیادہ سے زیادہ ایک دن تک (اگر Retry-After زیادہ مانگے تو اس سے بھی زیادہ)، اور بعد کی ڈیلیوریز نے جو ایڈریس شامل کیے وہ ساتھ جاتے ہیں۔ 403 (کلید درست نہیں) یا 422 (ایڈریس ہوسٹ پر نہیں) درج کرکے چھوڑ دیے جاتے ہیں۔
  • Content صفحہ آخری پنگ دکھاتا ہے: کب ہوا، کتنے ایڈریس تھے، HTTP اسٹیٹس اور اگلی کوشش۔
  • جب AutoPSEO بھی مضامین ہوسٹ کر رہا ہو تو ہوسٹ شدہ صفحات AutoPSEO کی اپنی کلید سے پنگ ہوتے ہیں، اور آپ کی کلید استعمال نہیں ہوتی۔

Indexing کے تحت IndexNow ٹول ایک الگ، دستی سبمٹر ہے؛ دیکھیں IndexNow۔

تنازعات: آپ کی سائٹ کا متن اصل ہے

آپ کے جواب کا version (یا آپ کے ایکسپورٹ میں کسی مضمون کا version) وہ ہے جس پر AutoPSEO سمجھتا ہے کہ آپ کا صفحہ ہے۔ ہر article.updated اسے basedOn کے طور پر لاتا ہے۔ اگر صفحہ آپ کی سائٹ پر اس کے بعد بدل چکا ہو، مثلاً کسی ایڈیٹر کی اصلاح سے، تو { "error": "conflict" } کے ساتھ 409 سے جواب دیں اور کچھ محفوظ نہ کریں۔ ڈیلیوری بغیر ری ٹرائی کے ناکام ہو جاتی ہے۔

کسی لائیو مضمون میں قطار شدہ تبدیلی لکھے جانے سے پہلے، اگر آپ کی سائٹ site.export ہینڈل کرتی ہے تو AutoPSEO اس مضمون کو site.export اور paths کے ذریعے آپ کی سائٹ سے دوبارہ پڑھتا ہے۔ اگر آپ کا ورژن آگے بڑھ چکا ہو تو آپ کا متن مضمون کا اگلا ریویژن بن جاتا ہے (writer import)، اور اس کے بعد آنے والی اپ ڈیٹ آپ کا موجودہ ورژن basedOn کے طور پر لاتی ہے۔

path.add اور path.remove

یہ دونوں ڈیلیوریز ٹائپڈ کنٹینٹ ٹائپ کی ایک ویلیو سے متعلق ہیں، مثلاً /interviews/{company}/{role} میں کوئی کمپنی۔ یہ article کی بجائے ایک path آبجیکٹ لاتی ہیں:

{
  "id": "7c1e9d2a-3b4f-4e8a-9c0d-1e2f3a4b5c6d",
  "event": "path.add",
  "occurredAt": "2026-10-12T08:30:00.000Z",
  "site": { "propertyId": "prop_123", "domain": "example.com" },
  "path": {
    "path": "/interviews/jane-street",
    "type": { "key": "interviews", "name": "Interviews", "path": "/interviews" },
    "part": "company",
    "value": {
      "value": "jane-street",
      "name": "Jane Street",
      "aliases": [],
      "url": "https://<its own site>/",
      "sameAs": ["https://<its careers page>/"],
      "description": "<what it is, in a few words>",
      "facts": [
        { "text": "<one sentence, as the source states it>", "source": "https://<the page that says it>", "lastVerified": "2026-10-01", "tier": "official" }
      ]
    },
    "takes": { "role": ["software-engineer"] }
  }
}
فیلڈمطلب
pathآپ کی سائٹ پر ویلیو کا اپنا ایڈریس
typeکنٹینٹ ٹائپ، { key, name, path } کی صورت میں
partایڈریس کا وہ حصہ جسے ویلیو پُر کرتی ہے
value{ value, name }، اور path.add پر اس کے علاوہ aliases، url، sameAs، description اور facts جو AutoPSEO کے رائٹر نے جمع کیے۔ ہر fact میں text، source، lastVerified اور official یا reported میں سے ایک tier ہوتا ہے
takespath.add پر: دوسرے حصوں کی وہ ویلیوز جن کے ساتھ لوگ اسے تلاش کرتے ہیں
redirectTopath.remove پر: ویلیو کے ایڈریس اب سے کہاں لے جائیں، 301 کے ساتھ

جب آپ نے کمانڈ لے لی ہو تو 2xx سے جواب دیں؛ path.add پر آپ وہ url شامل کر سکتے ہیں جہاں ویلیو اب موجود ہے، اور path.remove پر وہ urls جن کی سروس آپ نے بند کی، جو IndexNow کو جاتے ہیں۔ انکار کرنے کے لیے { "error": "<code>", "details": ["<why>"] } کے ساتھ 4xx دیں۔ path.add پر، invalid_value ویلیو کو آپ کی وجہ کے ساتھ رائٹر کو واپس بھیج دیتا ہے (تیسرا انکار حتمی ہوتا ہے) اور کوئی بھی دوسرا کوڈ اسے ہمیشہ کے لیے مسترد کر دیتا ہے۔ path.remove پر، not_found کو مکمل شمار کیا جاتا ہے، اور کوئی بھی دوسرا کوڈ، جیسے 409 in_use، سب کچھ جیسا تھا ویسا ہی چھوڑ دیتا ہے۔ انتظار میں پڑی پاتھ کمانڈ کو Done on the site نشان زد کرنا آپ کی سائٹ کی ہاں شمار ہوتا ہے۔

کالز: وہ درخواستیں جن کا جواب AutoPSEO پڑھتا ہے

کالز پر ڈیلیوریز کی طرح دستخط ہوتے ہیں۔ کال ڈیفالٹ طور پر 60 سیکنڈ تک انتظار کرتی ہے، اور دوبارہ پڑھنے اور پاتھ چیک کے لیے 30 سیکنڈ تک، اور 24 MB تک کے جواب پڑھتی ہے۔ 2xx کے علاوہ کوئی بھی جواب کال کو ناکام کر دیتا ہے۔

site.export

درخواست میں export: { what, cursor, limit } ہوتا ہے، اور ٹاپکس کے لیے since (ISO وقت) یا دوبارہ پڑھنے کے لیے paths بھی۔ { "items": [], "next": "<cursor>" } سے جواب دیں؛ AutoPSEO cursor کو آپ کے next پر رکھ کر دوبارہ پوچھتا ہے جب تک وہ خالی یا null نہ ہو جائے۔

  • what: "articles" مکمل سائٹ اسکینز میں چلتا ہے، فی صفحہ 10، جب آپ نے export کو articles اور adopt: true کے ساتھ ظاہر کیا ہو۔ 400 کا جواب "not supported" کے معنی رکھتا ہے۔ paths: ["/answers/x"] اور limit: 1 کے ساتھ یہ ایک مضمون دوبارہ پڑھتا ہے؛ صرف اسی مضمون سے جواب دیں۔
  • what: "topics" ہر اسکین میں اور روزانہ سنک میں چلتا ہے، فی صفحہ 50؛ روزانہ سنک since بھیجتا ہے، یعنی آخری پل کا وقت۔
  • what: "profile" ہر اسکین میں چلتا ہے۔ { "profile": { types, languages, rules, categories, format } } سے جواب دیں، ہر ایک اختیاری: types بطور [{ key, name, path }]، اور rules میں brandTerms، synonyms، noise، onTopic اور offTopic۔

ایکسپورٹ کیے گئے مضمون کے لیے externalId، ایک slug (کسی بھی رسم الخط کے حروف اور ہندسے اور ہائفن، زیادہ سے زیادہ 200 حروف، سیگمنٹس / سے جڑے)، اس slug پر ختم ہونے والا path، اور کم از کم title، h1 اور ایک سیکشن کے ساتھ copy ضروری ہیں۔ اختیاری فیلڈز: lang (ڈیفالٹ en)، type (کنٹینٹ ٹائپ کی کلید)، url، keyword، category، datePublished، dateModified، version، translations، owner (AutoPSEO کی مضمون آئی ڈی، ایک بار اپنانے کے بعد) اور maintenance: { kind: "refresh" or "optimize", reason }، جو وہ کام قطار میں لگا دیتا ہے۔ ہر ایکسپورٹ شدہ مضمون ایک منظم مضمون بن جاتا ہے جس کا پہلا ریویژن آپ کا متن ہوتا ہے، اور کچھ واپس نہیں بھیجا جاتا۔ دوبارہ ایکسپورٹ کرنا محفوظ ہے، اور جو مضمون AutoPSEO نے ہٹا دیا ہو وہ ایکسپورٹ کے ذریعے کبھی واپس نہیں آتا۔

ٹاپک آئٹم { keyword, status?, volume?, source?, externalId?, type?, reason? } ہوتا ہے، جہاں status queued، planned یا rejected میں سے ایک ہے۔

articles.adopted

امپورٹ کے بعد AutoPSEO آپ سے کہتا ہے کہ اسے نئے مضامین کا انتظام سنبھالنے دیں: { "articles": [{ "externalId", "articleId", "slug", "path" }] }۔ جواب دیں { "adopted": ["<externalId>"], "refused": [{ "externalId": "<id>", "reason": "<why>" }] }۔ جس مضمون کی آپ تصدیق نہ کریں وہ AutoPSEO سے دوبارہ ہٹا دیا جاتا ہے، سوائے اس کے کہ AutoPSEO اس کا کوئی ریویژن پہلے ہی لکھ چکا ہو۔

site.handover

{ "handover": { "types": ["answers"], "writer": "autopseo" } }، جو تب بھیجا جاتا ہے جب کوئی پراپرٹی کے Your site صفحے پر Let AutoPSEO write them یا Hand writing back to the site منتخب کرے۔ { "ok": true, "writer": "autopseo" } سے جواب دیں۔ AutoPSEO کو سپرد کیے جانے کے بعد، آپ کی سائٹ جن ٹاپکس کو جانچتی ہے انہیں خود لکھنے کی بجائے AutoPSEO کو دے دیتی ہے۔

path.check

{ "paths": [{ "path": "/interviews/google/data-engineer" }, { "path": "/interviews/jane-street", "new": { "part": "company", "value": "jane-street", "name": "Jane Street" } }] }۔ ہر پاتھ کے لیے ایک نتیجہ دیں: { "results": [{ "path": "/interviews/google/data-engineer", "ok": true }, { "path": "/interviews/jane-street", "ok": false, "error": "not_allowed", "details": ["We only list companies with a careers page."] }] }۔ انکار آپ کی وجہ کے ساتھ محفوظ رکھا جاتا ہے اور دوبارہ نہیں پوچھا جاتا؛ جو پاتھ آپ چھوڑ دیں وہ بعد میں دوبارہ پوچھا جاتا ہے۔

ایک کم سے کم ریسیور

ایک Cloudflare Worker جو Web Crypto API سے دستخط کی تصدیق کرتا ہے، تین مضمون کمانڈز ہینڈل کرتا ہے، اور باقی کو unknown_event کہہ کر مسترد کرتا ہے۔ یہ مضامین کو ARTICLES کے طور پر بائنڈ کیے گئے KV نیم اسپیس میں رکھتا ہے، اور سائننگ سیکرٹ AUTOPSEO_SECRET نامی Worker سیکرٹ میں۔

const HANDLED = ["article.published", "article.updated", "article.unpublished"];
const MAX_SKEW_SECONDS = 300;
const SITE = "https://example.com";

const json = (data, status = 200) =>
  new Response(JSON.stringify(data), { status, headers: { "content-type": "application/json" } });

function hexToBytes(hex) {
  if (!/^[0-9a-f]{64}$/.test(hex)) return null;
  const out = new Uint8Array(32);
  for (let i = 0; i < 32; i++) out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
  return out;
}

async function verified(request, body, secret) {
  const timestamp = request.headers.get("X-AutoPSEO-Timestamp") || "";
  const signature = (request.headers.get("X-AutoPSEO-Signature") || "").replace(/^sha256=/, "");
  if (!/^\d+$/.test(timestamp)) return false;
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > MAX_SKEW_SECONDS) return false;
  const bytes = hexToBytes(signature);
  if (!bytes) return false;
  const enc = new TextEncoder();
  const key = await crypto.subtle.importKey("raw", enc.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["verify"]);
  // verify() compares in constant time.
  return crypto.subtle.verify("HMAC", key, bytes, enc.encode(`${timestamp}.${body}`));
}

export default {
  async fetch(request, env) {
    if (request.method !== "POST") return new Response("Method not allowed", { status: 405 });
    const body = await request.text();
    if (!(await verified(request, body, env.AUTOPSEO_SECRET))) return json({ error: "bad_signature" }, 401);
    let msg;
    try {
      msg = JSON.parse(body);
    } catch {
      return json({ error: "bad_json" }, 400);
    }

    if (msg.event === "ping") return json({ ok: true, autopseo: { version: 1, events: HANDLED } });

    if (msg.event === "test") {
      const command = msg.test && msg.test.event;
      // Check the sample as you would the real command, and store nothing.
      return HANDLED.includes(command)
        ? json({ test: command, ok: true })
        : json({ test: command, ok: false, error: "unknown_event" });
    }

    if (msg.event === "article.published" || msg.event === "article.updated") {
      const a = msg.article;
      const stored = JSON.parse((await env.ARTICLES.get(a.id)) || "null");
      if (a.basedOn && stored && stored.version && stored.version !== a.basedOn) {
        return json({ error: "conflict", details: ["The page changed on the site."] }, 409);
      }
      // Any change to the page, here or in your own editor, gets a new version.
      const version = crypto.randomUUID();
      await env.ARTICLES.put(a.id, JSON.stringify({ ...a, version }));
      return json({ url: SITE + a.path, version });
    }

    if (msg.event === "article.unpublished") {
      const a = msg.article;
      if (a.redirectTo) await env.ARTICLES.put(a.id, JSON.stringify({ path: a.path, redirectTo: a.redirectTo }));
      else await env.ARTICLES.delete(a.id);
      return json({ ok: true });
    }

    return json({ error: "unknown_event" }, 400);
  },
};

Node.js پر اسی طرح createHmac اور timingSafeEqual سے تصدیق کریں، اس خام باڈی پر جو آپ کے فریم ورک کو ملی:

import { createHmac, timingSafeEqual } from "node:crypto";

export function verifyAutopseo(rawBody, headers, secret) {
  const timestamp = String(headers["x-autopseo-timestamp"] || "");
  const given = String(headers["x-autopseo-signature"] || "");
  if (!/^\d+$/.test(timestamp) || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
  const expected = "sha256=" + createHmac("sha256", secret).update(timestamp + ".").update(rawBody).digest("hex");
  return given.length === expected.length && timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}

آگے: ویب ہُک تک کیا پہنچے گا، اس کا فیصلہ تحریر اور ریویو اور دیکھ بھال کرتے ہیں؛ پورا بہاؤ کنٹینٹ انجن کے جائزے میں ہے۔

اپنے SEO مواد کو آٹو پائلٹ پر ڈالیں

Search Console اور اپنی سائٹ کو کنیکٹ کریں۔ AutoPSEO اسے اسکین کرتا ہے اور فوراً پہلے موضوعات کی منصوبہ بندی کر دیتا ہے۔ کریڈٹ کارڈ کی ضرورت نہیں۔