OROVA.VN — BIZ AI AGENT

/ Dasturchilar uchun qoʻllanma

API orqali nashr qilish istalgan veb-saytda.

WordPress da ishlamaydigan saytga Orova tayyor maqolalarni nashr qilishi uchun oʻz endpointingizni qanday yaratish kerak.

Orova tayyor maqolalarni WordPress ga darhol nashr qiladi. Agar saytingiz WordPress emas boʻlsa — maxsus CMS, headless tizim, statik sayt yoki oʻz backendingiz — kichik API orqali maqolalarni qabul qilib, Orova ga avtomatik nashr qilishga baribir ruxsat bera olasiz. Siz bitta HTTP endpoint yozasiz; Orova har bir maqolani tugatganda uni chaqiradi. Bu qoʻllanma dasturchi uchun va soʻrovning toʻliq shartnomasini tavsiflaydi.

/ Umumiy koʻrinish

Qanday ishlaydi

Orova kalit soʻz uchun maqolani yozib boʻlgach, siz roʻyxatdan oʻtkazgan endpoint URL ga bitta HTTP POST soʻrovini yuboradi. Soʻrov tanasi JSON boʻlib, butun maqolani oʻz ichiga oladi. Endpointingiz oʻz tomoningizda post yaratadi va maqolaning yakuniy ommaviy URL i bilan javob beradi. Orova bu URL ni WordPress posti kabi nashr havolasi sifatida saqlaydi. WordPress boʻlmagan saytda qoʻl tegizmasdan nashr qilmoqchi boʻlsangiz yoki postlar qanday saqlanishini toʻliq nazorat qilishni istasangiz, shundan foydalaning.

/ Sozlash

Sozlash — olti qadam

  • 1

    Loyihangizda “Connect via API” ni yoqing. Loyihangizni oching (Loyihalar → loyihangiz → Ulanishlar). WordPress kartasi yonida Connect via API kartasi bor. U yerga endpointingiz URL ini kiriting. Maxfiy kalit maydoni ixtiyoriy: boʻsh qoldirsangiz Orova uni yaratadi yoki saytingiz ishlatayotgan kalitni joylang. Saqlangach, kalit kartada Nusxalash tugmasi bilan koʻrinadi. Loyiha faqat bitta manzilga nashr qiladi — API orqali ulanish WordPress tugmasini qulflaydi va aksincha.

  • 2

    POST qabul qiladigan endpoint yarating. Oʻz saytingiz yoki serveringizda JSON tanali HTTP POST ni tinglaydigan route yarating. Aynan shu URL ni loyihaning Ulanishlar ekraniga joylaysiz. Orova har bir tayyor maqola uchun uni bir marta chaqiradi.

  • 3

    Har bir soʻrovda Bearer tokenni tekshiring. Orova dan kelgan har bir soʻrovda “Bearer <secret>” koʻrinishidagi Authorization sarlavhasi boʻladi, unda loyihangizda koʻrsatilgan aynan oʻsha maxfiy kalit ishlatiladi. Uni saqlangan nusxangiz bilan solishtiring va mos kelmaganini rad eting — aynan shu boshqalarning saytingizga post joylashiga yoʻl qoʻymaydi.

  • 4

    Payload dan maqola yarating. JSON tanasini oʻqing va CMS yoki maʼlumotlar bazangizda post yarating: maqolaning oʻzi uchun title, slug va content_html, meta tavsif sifatida excerpt, muqova rasmi sifatida featured_image_url, metamaʼlumot sifatida keyword / lang / published_at dan foydalaning.

  • 5

    Maqolaning jonli URL ini qaytaring. HTTP 200 yoki 201 va { "url": "https://yoursite.com/the-new-article" } JSON tanasi bilan javob bering. Orova bu URL ni maqolaning nashr havolasi sifatida saqlaydi. 2xx boʻlmagan status qaytarsangiz yoki url maydonini qoldirib ketsangiz, Orova nashrni muvaffaqiyatsiz deb hisoblaydi.

  • 6

    Optimize mexanizmidan kelgan yangilash soʻrovlarini qayta ishlang. Tanada action = "update" boʻlsa, mavjud postni target_url (yoki slug) boʻyicha toping va uning title, content_html va excerpt maydonlarini joyida qayta yozing — URL oʻzgarmasin. Oʻsha postga ishora qiluvchi { "url": ... } bilan 200 javob bering. Buni hali qoʻllab-quvvatlamaydigan endpointlarda Orova optimizatsiyani muvaffaqiyatsiz deb koʻrsatadi; yangi maqola nashr qilish avvalgidek ishlayveradi.

/ Shartnoma

Orova yuboradigan soʻrov

Har bir tayyor maqola quyidagi koʻrinishdagi bitta soʻrov boʻlib keladi:

POST <your endpoint URL>

Headers:
  Content-Type: application/json
  Authorization: Bearer <secret>     # the secret key shown in Project -> Connections
  User-Agent: Orova-SEO

Body (JSON):
  {
    "title": "...",                  # article headline
    "slug": "...",                   # URL-friendly identifier
    "content_html": "...",           # full article HTML
    "excerpt": "...",                # meta description
    "featured_image_url": "..." | null,
    "keyword": "...",                # target keyword
    "lang": "en",                    # ISO language code
    "published_at": "2026-05-17T09:00:00.482913",  # ISO 8601, UTC, no offset suffix
    "status": "draft"                # optional: "draft" keeps it unpublished
  }
  # Optional fields are left out of the body when empty — never sent as null.

/ Maʼlumotnoma

Payload maydonlari

Nashr (yangi maqola) soʻrovining maydonlari. Oʻchirish va yangilash soʻrovlari oʻsha endpointdan quyidagi alohida boʻlimlarda koʻrsatilgan kichikroq tanalar bilan foydalanadi.

MaydonTuriTavsif
titlestringMaqola sarlavhasi.
slugstringURL-friendly identifier suggested for the post.
content_htmlstringNashrga tayyor HTML koʻrinishidagi maqolaning toʻliq matni.
excerptstringMeta tavsif uchun moʻljallangan qisqa xulosa.
featured_image_urlstring | nullMuqova rasmi URL i yoki rasm boʻlmasa null.
keywordstringMaqola yozilgan maqsadli SEO kalit soʻzi.
langstringLanguage as an ISO code, e.g. "en" or "vi".
published_atstringOrova maqolani yuborgan payt, UTC dagi ISO 8601, vaqt mintaqasi qoʻshimchasisiz.
statusstring | undefinedIxtiyoriy. "draft" maqolani nashr qilmasdan saqlaydi; "publish" yoki umuman qiymat boʻlmasa, nashr qilinadi.
actionstring | undefinedYangi maqolalarda boʻlmaydi. "delete" postni olib tashlashni soʻraydi; "update" (Optimize mexanizmi yuboradi) mavjud postni joyida qayta yozishni soʻraydi.
target_urlstringFaqat action = "update" bilan: qayta yoziladigan postning jonli URL i. URL oʻzgarmasin.
idnumber | undefinedOnly sent when Orova knows your post id (from `list` or `get`): match on it before `target_url`.

Yuboradigan narsa boʻlmasa, ixtiyoriy maydonlar tanadan butunlay chiqarib tashlanadi — Orova hech qachon null yubormaydi, shuning uchun ularni ehtiyotkorlik bilan oʻqing. status ham ixtiyoriy: "draft" maqolani qoralama sifatida yaratadi, "publish" yoki status umuman boʻlmasa, darhol nashr qiladi.

/ Shartnoma

Qaytarishingiz kerak boʻlgan javob

Postni yaratgach, HTTP 200 yoki 201 statusi va quyidagi JSON tanasi bilan javob bering:

HTTP 200 (or 201)
Content-Type: application/json

{
  "url": "https://yoursite.com/published-article"
}

Orova bu url ni maqolaning nashr havolasi sifatida saqlaydi. Endpointingiz 2xx boʻlmagan status yoki url maydoniga ega JSON obyekt boʻlmagan tana qaytarsa, Orova nashrni muvaffaqiyatsiz deb hisoblaydi va qayta urinishingiz uchun maqolani shunga mos belgilaydi. 60 soniya ichida javob bering — shundan soʻng Orova soʻrovni toʻxtatadi (bu nashr, yangilash va oʻchirishga birdek tegishli).

/ Namuna

Kod namunasi

Node.js va Express dagi minimal qabul qiluvchi endpoint. Xuddi shu qadamlar — tokenni tekshirish, action (update / delete) boʻyicha tarmoqlash, postni yaratish yoki oʻzgartirish, URL ni qaytarish — istalgan til yoki freymvorkda qoʻllaniladi.

// Node.js / Express — a minimal receiving endpoint
import express from "express";

const app = express();
app.use(express.json({ limit: "5mb" }));

// The secret Orova generated for this project.
const OROVA_SECRET = process.env.OROVA_SECRET;

app.post("/orova/publish", async (req, res) => {
  // 1. Verify the Bearer token.
  const auth = req.get("authorization") || "";
  if (auth !== "Bearer " + OROVA_SECRET) {
    return res.status(401).json({ error: "unauthorized" });
  }

  // 2. Required: list your articles (duplicate check, internal links). action = "list".
  if (req.body.action === "list") {
    const posts = await listPosts(req.body.limit || 500); // newest first, 500 max
    // each post: { id, title, slug, link, date, modified, status, author, excerpt? }
    return res.status(200).json({ ok: true, posts });
  }

  // 3. Required: read one article in full (used when optimizing it). action = "get".
  if (req.body.action === "get") {
    const post = await findPost(req.body.id, req.body.target_url, req.body.slug);
    if (!post) return res.status(404).json({ ok: false, err: "not_found" });
    return res.status(200).json({ ok: true, post });
  }

  // 4. Visual Editor: store an image, answer with its absolute URL.
  if (req.body.action === "upload_image") {
    const { filename, mime, data_base64 } = req.body;
    if (!String(mime || "").startsWith("image/")) {
      return res.status(422).json({ error: "image files only" });
    }
    const bytes = Buffer.from(data_base64, "base64");
    if (bytes.length > 15 * 1024 * 1024) {
      return res.status(413).json({ error: "image too large" });
    }
    return res.status(200).json({ ok: true, url: await saveImage(filename, bytes) });
  }

  // 5. Delete requests: body carries action = "delete".
  if (req.body.action === "delete") {
    const removed = await deletePostByUrl(req.body.url, req.body.slug);
    if (!removed) return res.status(404).json({ deleted: true }); // already gone
    return res.status(200).json({ deleted: true });
  }

  // 6. Update requests: action = "update". Optional fields may be absent.
  if (req.body.action === "update") {
    const updated = await updatePost(req.body.id, req.body.target_url, {
      title: req.body.title,
      html: req.body.content_html,
      metaDescription: req.body.excerpt,
      coverImage: req.body.featured_image_url,  // optional
      status: req.body.status,                  // optional: "publish" | "draft"
    });
    if (!updated) return res.status(404).json({ error: "post not found" });
    return res.status(200).json({ url: updated.url });
  }

  // 7. New article: read the payload Orova sent.
  const {
    title, slug, content_html, excerpt,
    featured_image_url, keyword, lang, published_at, status,
  } = req.body;

  // 8. Create the article in your own CMS or database.
  const post = await createPost({
    title,
    slug,
    html: content_html,
    metaDescription: excerpt,
    coverImage: featured_image_url,
    keyword,
    lang,
    publishedAt: published_at,
    draft: status === "draft",   // status is optional; absent means publish now
  });

  // 9. Return 200/201 with the live URL.
  return res.status(201).json({
    url: "https://yoursite.com/" + post.slug,
  });
});

app.listen(3000);

/ Shartnoma — yangilash

Maqolalarni yangilash (Optimize)

Orova ning Optimize mexanizmi allaqachon jonli maqolalarni qayta yozadi — yangilangan faktlar, yaxshiroq sarlavhalar, birlashtirilgan kontent — soʻng mavjud postni joyida, URL ni oʻzgartirmasdan qayta yozadi. Soʻrov oʻsha endpoint URL ga, xuddi shu Bearer token bilan POST sifatida yuboriladi:

POST <your endpoint URL>

Headers:
  Content-Type: application/json
  Authorization: Bearer <secret>
  User-Agent: Orova-SEO

Body (JSON):
  {
    "action": "update",          # always the literal string "update"
    "id": 123,                   # optional: post id, match on this first
    "target_url": "...",         # public URL of the post to overwrite (match next)
    "title": "...",              # new headline
    "slug": "...",               # slug fallback for matching, may be empty
    "content_html": "...",       # full new article body as HTML
    "excerpt": "...",            # new meta description
    "featured_image_url": "...", # optional: new cover image
    "status": "publish"          # optional: "publish" or "draft"
  }
  # Optional fields are left out of the body when empty — never sent as null.

Postni target_url boʻyicha toping (boʻlmasa slug), uning sarlavhasi, matni va meta tavsifini almashtiring, URL ni oʻz holicha qoldiring, soʻng { "url": "<same post URL>" } bilan 200 javob bering. 2xx boʻlmagan status yoki url siz tana Orova ga bu optimizatsiyani muvaffaqiyatsiz deb belgilatadi (u hech qachon takroriy post yaratmaydi). Buni hali joriy qilmagan endpointlar yangi maqolalarni avvalgidek nashr qilaveradi — yangilashni joriy qilish faqat Optimize ekranidan foydalanganingizda kerak.

29-avgustdan boshlab yangilash tanasida id (target_url dan oldin u boʻyicha moslang), yangi muqova uchun featured_image_url va "publish" yoki "draft" qiymatli status ham boʻlishi mumkin. Uchalasi ham ixtiyoriy; boʻsh boʻlsa tanadan chiqariladi, hech qachon null sifatida yuborilmaydi.

/ Shartnoma — Visual Editor

Maqolalarni oʻqish (majburiy)

Orova saytingizdagi mavjud maqolalarni oʻqishi kerak — takroriy mavzulardan qochish, ichki havolalar qoʻshish va eski postlarni optimallashtirish uchun. Oʻsha endpoint URL ga xuddi shu Bearer token bilan yana ikkita action qoʻshing: list maqolalaringizni qaytaradi, get ulardan birini toʻliq qaytaradi.

POST <your endpoint URL>     # same endpoint, same Bearer secret

Body (JSON):
  {
    "action": "list",            # always the literal string "list"
    "limit": 500                 # newest article first, 500 maximum
  }

Response — HTTP 200:
  {
    "ok": true,
    "posts": [
      {
        "id": 123,               # your own post id, reused by "get" and "update"
        "title": "...",
        "slug": "...",
        "link": "https://yoursite.com/the-article",
        "date": "2026-08-29",    # published date, YYYY-MM-DD
        "modified": "2026-08-29",
        "status": "publish",     # "publish" or "draft"
        "author": "...",
        "excerpt": "..."         # optional: short summary, 300 characters max
      }
    ]
  }
  # Required: Orova reads this list to avoid duplicate topics,
  # add internal links and analyze the whole site.
POST <your endpoint URL>

Body (JSON):
  {
    "action": "get",             # always the literal string "get"
    "id": 123,                   # match on this first
    "target_url": "...",         # then the public URL
    "slug": "..."                # then the slug
  }

Response — HTTP 200:
  {
    "ok": true,
    "post": {
      "id": 123,
      "title": "...",
      "slug": "...",
      "link": "https://yoursite.com/the-article",
      "content_html": "...",     # full article body as HTML
      "excerpt": "...",
      "featured_image_url": "...",
      "status": "publish"        # "publish" or "draft"
    }
  }

No such post — HTTP 404:
  { "ok": false, "err": "not_found" }

limit koʻpi bilan 500 va eng yangi maqola birinchi keladi. get uchun Orova id, target_url va slug ni birga yuboradi — shu tartibda qaysi birini taniyotgan boʻlsangiz, shu boʻyicha moslang. Hech narsa mos kelmasa, { "ok": false, "err": "not_found" } bilan 404 javob bering. list dagi excerpt ixtiyoriy (koʻpi bilan 300 belgi). Majburiy: Orova qaysi maqolalar mavjudligini bilish uchun (takrorlanishdan qochish, ichki havolalar qoʻshish va butun saytni tahlil qilish) list ni, maqolani optimallashtirishda uni oʻqish uchun get ni chaqiradi. Saytingiz bu ikki action ga javob bermasa, yangi maqolalarga ichki havolalar qoʻshilmaydi va eski maqolalarni optimallashtirib boʻlmaydi.

/ Shartnoma — Visual Editor

Rasm yuklash (Visual Editor)

Visual Editor ga rasm tashlaganingizda, Orova uni JSON tanasi ichida base64 koʻrinishida oʻsha endpoint URL ga yuboradi — multipart yoʻq, himoyalanishi kerak boʻlgan ikkinchi URL ham yoʻq.

POST <your endpoint URL>

Body (JSON):
  {
    "action": "upload_image",    # always the literal string "upload_image"
    "filename": "cover.png",     # original file name, extension included
    "mime": "image/png",         # image/* only
    "data_base64": "iVBORw0KGgo..."   # file bytes, base64, 15 MB maximum
  }

Response — HTTP 200 (or 201):
  {
    "ok": true,
    "url": "https://yoursite.com/uploads/cover.png"   # absolute URL
  }

Faqat image/* ni qabul qiling va 15 MB dan kattasini rad eting. Faylni saqlang, soʻng rasmning mutlaq URL i bilan javob bering: nisbiy yoʻl maqola boshqa joyda koʻrsatilishi bilan uni buzadi. Bu action faqat Visual Editor uchun kerak.

/ Shartnoma — oʻchirish

Maqolalarni oʻchirish

Foydalanuvchi nashr qilingan maqolani Orova ichida (Yozish yoki Hisobotlar ekranidan) olib tashlaganda, Orova saytingizdan ham uni oʻchirishni soʻraydi. Soʻrov oʻsha endpoint URL ga xuddi shu Bearer token bilan POST sifatida yuboriladi — farqi faqat tanada:

POST <your endpoint URL>

Headers:
  Content-Type: application/json
  Authorization: Bearer <secret>
  User-Agent: Orova-SEO

Body (JSON):
  {
    "action": "delete",          # always the literal string "delete"
    "url": "...",                # public URL of the article to remove (match on this first)
    "slug": "...",               # slug fallback, may be empty
    "keyword": "..."             # the article's target keyword, for your logs
  }

Postni url boʻyicha toping (boʻlmasa slug), uni oʻchiring yoki nashrdan olib tashlang, soʻng 200 va { "deleted": true } bilan javob bering — oddiy 204 ham ishlaydi. Post endi mavjud boʻlmasa, 404 javob bering va Orova uni allaqachon oʻchirilgan deb hisoblaydi. { "deleted": false } qaytarish Orova ga post olib tashlanmaganini bildiradi. Oddiy nashr soʻrovlarida hech qachon action maydoni boʻlmaydi, shuning uchun mavjud endpointlar oʻzgarishsiz ishlayveradi — oʻchirishni joriy qilish ixtiyoriy, lekin tavsiya etiladi.

/ Xavfsizlik

Xavfsizlik eslatmalari

  • Bearer tokenni doim tekshiring. Endpointingiz ommaviy URL — uni istalgan kishi chaqira oladi. Authorization sarlavhasi soʻrov haqiqatan Orova dan kelganini isbotlaydigan yagona narsa, shuning uchun tokeni saqlangan maxfiy kalitingizga aynan mos kelmaydigan har bir soʻrovni rad eting.
  • Endpointni HTTPS orqali taqdim eting. Maxfiy kalit sarlavhada uzatiladi. HTTPS uni yoʻlda oʻqilishdan saqlaydi.
  • Maxfiy kalitni kodingizdan tashqarida saqlang. Kalitni muhit oʻzgaruvchisida yoki maxfiy maʼlumotlar omborida saqlang, uni faylga qattiq yozib commit qilmang. Agar u oshkor boʻlib qolsa, Loyiha → Ulanishlar boʻlimida yangisini yarating.
  • content_html ni ishonchli markup emas, kontent sifatida qabul qiling. Uni CMSingizdagi har qanday maqola matni kabi ehtiyotkorlik bilan saqlang va koʻrsating.

/ Yakun

Shartnoma shundan iborat

Endpoint ishlab turgan va loyihangizda roʻyxatdan oʻtkazilgan boʻlsa, Orova saytingizga maqolalarni avtomatik joylaydi — xuddi WordPress foydalanuvchilari uchun boʻlgani kabi. Tayyor boʻlgan har bir maqola serveringizga kelib tushadi, postga aylanadi va uning ommaviy URL manzili Hisobotlar hamda Tahlil boʻlimiga qaytib keladi, shunda siz uning samaradorligini kuzatib borasiz.

← Qoʻllanmalar kutubxonasiga qaytish

/ Yordam kerakmi?

Endpointni ulay olmayapsizmi? Ish maydoningizdagi Yordam boʻlimini oching yoki bizga xabar yuboring.