OROVA.VN — BIZ AI AGENT

/ Vadovas programuotojams

Publikavimas per API bet kurioje svetainėje.

Kaip sukurti savo endpoint, kad Orova galėtų publikuoti straipsnius svetainėje, kuri neveikia su WordPress.

Orova iš karto publikuoja straipsnius į WordPress. Jei jūsų svetainė nėra WordPress – nuosava CMS, headless sistema, statinė svetainė ar jūsų backend – vis tiek galite leisti Orova publikuoti automatiškai, priimdami straipsnius per nedidelę API. Parašote vieną HTTP endpoint; kaskart užbaigusi straipsnį, Orova jį iškviečia. Šis vadovas skirtas programuotojams ir aprašo visą užklausos sutartį.

/ Apžvalga

Kaip tai veikia

Parašiusi straipsnį raktažodžiui, Orova siunčia vieną HTTP POST užklausą į jūsų nurodytą endpoint URL. Užklausos turinys yra JSON ir apima visą straipsnį. Jūsų endpoint sukuria įrašą jūsų pusėje ir grąžina galutinį viešą straipsnio URL. Orova išsaugo tą URL kaip paskelbto įrašo nuorodą, kaip ir WordPress įrašo atveju. Naudokite tai, kai norite automatinio publikavimo svetainėje, kuri nėra WordPress, arba norite patys valdyti, kaip saugomi įrašai.

/ Nustatymas

Nustatymas – šeši žingsniai

  • 1

    Įjunkite „Prijungti per API“ savo projekte. Atidarykite savo projektą (Projektai → jūsų projektas → Prijungimai). Šalia WordPress kortelės yra kortelė Prijungti per API. Įveskite ten savo endpoint URL. Slaptojo rakto laukas neprivalomas: palikite tuščią ir Orova sugeneruos raktą, arba įklijuokite raktą, kurį jūsų svetainė jau naudoja. Išsaugojus raktas rodomas kortelėje su mygtuku Kopijuoti. Projektas publikuoja tik į vieną vietą – prijungus per API užrakinamas WordPress mygtukas, ir atvirkščiai.

  • 2

    Sukurkite endpoint, priimantį POST. Savo svetainėje ar serveryje sukurkite maršrutą, kuris priima HTTP POST su JSON turiniu. Tai URL, kurį įklijuojate projekto Prijungimų ekrane. Orova jį iškviečia vieną kartą kiekvienam užbaigtam straipsniui.

  • 3

    Tikrinkite Bearer token kiekvienoje užklausoje. Kiekviena Orova užklausa turi Authorization antraštę formatu „Bearer <secret>“ su tiksliai tuo slaptuoju raktu, kuris rodomas jūsų projekte. Palyginkite jį su savo saugoma kopija ir atmeskite viską, kas nesutampa – tik tai neleidžia kitiems skelbti jūsų svetainėje.

  • 4

    Sukurkite straipsnį iš payload. Perskaitykite JSON turinį ir sukurkite įrašą savo CMS ar duomenų bazėje: title, slug ir content_html naudokite pačiam straipsniui, excerpt – kaip metaaprašą, featured_image_url – kaip viršelio vaizdą, o keyword / lang / published_at – kaip metaduomenis.

  • 5

    Grąžinkite tikrą straipsnio URL. Atsakykite HTTP 200 arba 201 su JSON turiniu { "url": "https://yoursite.com/the-new-article" }. Orova išsaugo tą URL kaip paskelbtą straipsnio nuorodą. Jei grąžinsite ne 2xx būseną arba praleisite url lauką, Orova laikys publikavimą nepavykusiu.

  • 6

    Apdorokite atnaujinimo užklausas iš Optimizavimo variklio. Kai turinyje yra action = "update", raskite esamą įrašą pagal target_url (arba slug) ir perrašykite jo title, content_html ir excerpt toje pačioje vietoje – URL nekeiskite. Atsakykite 200 su { "url": ... }, nukreipiančiu į tą patį įrašą. Jei endpoint to dar neapdoroja, Orova tiesiog praneš, kad optimizavimas nepavyko; naujų straipsnių publikavimas veiks kaip anksčiau.

/ Sutartis

Užklausa, kurią siunčia Orova

Kiekvienas užbaigtas straipsnis atkeliauja kaip viena tokia užklausa:

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.

/ Žinynas

Payload laukai

Publikavimo (naujo straipsnio) užklausos laukai. Šalinimo ir atnaujinimo užklausos naudoja tą patį endpoint su mažesniu turiniu, parodytu jų skyriuose žemiau.

LaukasTipasAprašas
titlestringStraipsnio antraštė.
slugstringURL-friendly identifier suggested for the post.
content_htmlstringVisas straipsnio tekstas kaip paruoštas publikuoti HTML.
excerptstringTrumpa santrauka, skirta metaaprašui.
featured_image_urlstring | nullViršelio vaizdo URL arba null, kai jo nėra.
keywordstringTikslinis SEO raktažodis, kuriam straipsnis parašytas.
langstringLanguage as an ISO code, e.g. "en" or "vi".
published_atstringMomentas, kai Orova išsiuntė straipsnį, ISO 8601 formatu UTC laiku, be laiko juostos priesagos.
statusstring | undefinedNeprivaloma. "draft" palieka straipsnį nepaskelbtą; "publish" arba jokios reikšmės – paskelbia jį.
actionstring | undefinedNaujiems straipsniams nėra. "delete" prašo pašalinti įrašą; "update" (siunčia Optimizavimo variklis) prašo perrašyti esamą įrašą toje pačioje vietoje.
target_urlstringTik su action = "update": tikras perrašomo įrašo URL. URL nekeiskite.
idnumber | undefinedOnly sent when Orova knows your post id (from `list` or `get`): match on it before `target_url`.

Neprivalomi laukai visiškai praleidžiami, kai nėra ką siųsti – Orova niekada nesiunčia null, todėl skaitykite juos atsargiai. status taip pat neprivalomas: "draft" sukuria straipsnį kaip juodraštį, o "publish" arba be status jį iškart paskelbia.

/ Sutartis

Atsakymas, kurį turite grąžinti

Sukūrę įrašą, atsakykite HTTP 200 arba 201 būsena ir šiuo JSON turiniu:

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

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

Orova išsaugo tą url kaip paskelbtą straipsnio nuorodą. Jei jūsų endpoint grąžina bet kokią ne 2xx būseną arba turinį, kuris nėra JSON objektas su url lauku, Orova laiko publikavimą nepavykusiu ir atitinkamai pažymi straipsnį, kad galėtumėte bandyti dar kartą. Atsakykite per 60 sekundžių – po to Orova nutraukia užklausą (taikoma publikavimui, atnaujinimui ir šalinimui).

/ Pavyzdys

Kodo pavyzdys

Minimalus priimantis endpoint Node.js su Express. Tie patys žingsniai – patikrinti token, išsišakoti pagal action (update / delete), sukurti ar pakeisti įrašą, grąžinti URL – taikomi bet kuria kalba ar karkasu.

// 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);

/ Sutartis – atnaujinimas

Straipsnių atnaujinimas (Optimizavimas)

Orova Optimizavimo variklis perrašo jau paskelbtus straipsnius – atnaujina faktus, gerina pavadinimus, sujungia turinį – ir tada perrašo esamą įrašą toje pačioje vietoje, nekeisdamas URL. Užklausa siunčiama į tą patį endpoint URL, kaip POST su tuo pačiu Bearer token:

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.

Raskite įrašą pagal target_url (atsarginis variantas – slug), pakeiskite jo pavadinimą, tekstą ir metaaprašą, palikite URL kaip yra, tada atsakykite 200 su { "url": "<same post URL>" }. Bet kokia ne 2xx būsena arba turinys be url priverčia Orova pažymėti optimizavimą kaip nepavykusį (ji niekada nesukuria įrašo dublikato). Endpoint, kurie to dar neįgyvendino, ir toliau publikuoja naujus straipsnius – atnaujinimą įgyvendinti reikia tik tada, kai naudojate Optimizavimo ekraną.

Nuo rugpjūčio 29 d. atnaujinimo turinyje taip pat gali būti id (tikrinkite pagal jį prieš target_url), featured_image_url naujam viršelio vaizdui ir status su "publish" arba "draft". Visi trys neprivalomi; kai tušti, jie praleidžiami ir niekada nesiunčiami kaip null.

/ Sutartis – Visual Editor

Straipsnių skaitymas (privaloma)

Orova turi perskaityti jūsų svetainėje jau esančius straipsnius – kad išvengtų pasikartojančių temų, pridėtų vidinių nuorodų ir optimizuotų senesnius įrašus. Pridėkite dar du action tame pačiame endpoint URL, su tuo pačiu Bearer token: list grąžina jūsų straipsnius, get – vieną iš jų visą.

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 ribojamas iki 500, naujausias straipsnis pateikiamas pirmas. Su get Orova kartu siunčia id, target_url ir slug – tikrinkite pagal tą, kurį atpažįstate, šia tvarka. Kai niekas nesutampa, atsakykite 404 su { "ok": false, "err": "not_found" }. excerpt sąraše list neprivalomas (daugiausia 300 simbolių). Privaloma: Orova kviečia list, kad sužinotų, kokie straipsniai jau yra (išvengti dublikatų, pridėti vidinių nuorodų ir analizuoti visą svetainę), ir kviečia get, kad perskaitytų straipsnį jį optimizuodama. Jei jūsų svetainė neatsako į šiuos du action, nauji straipsniai negauna vidinių nuorodų, o senesnių straipsnių optimizuoti neįmanoma.

/ Sutartis – Visual Editor

Vaizdų įkėlimas (Visual Editor)

Kai įmetate vaizdą į Visual Editor, Orova siunčia jį į tą patį endpoint URL kaip base64 JSON turinyje – jokio multipart, jokio antro URL, kurį reikėtų apsaugoti.

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
  }

Priimkite tik image/* ir atmeskite viską, kas viršija 15 MB. Išsaugokite failą ir atsakykite absoliučiu vaizdo URL: santykinis kelias sugadina straipsnį, kai tik jis rodomas kitur. Šis action reikalingas tik Visual Editor.

/ Sutartis – šalinimas

Straipsnių šalinimas

Kai naudotojas pašalina paskelbtą straipsnį Orova viduje (Rašymo arba Ataskaitų ekrane), Orova paprašo jūsų svetainės jį taip pat ištrinti. Užklausa siunčiama į tą patį endpoint URL, kaip POST su tuo pačiu Bearer token – skiriasi tik turinys:

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
  }

Raskite įrašą pagal url (atsarginis variantas – slug), pašalinkite arba atšaukite jo paskelbimą, tada atsakykite 200 su { "deleted": true } – tinka ir tuščias 204. Jei įrašo nebėra, atsakykite 404 ir Orova laikys jį jau ištrintu. Grąžinę { "deleted": false } pranešate Orova, kad įrašas nepašalintas. Įprastos publikavimo užklausos niekada neturi action lauko, todėl esami endpoint veikia nepakitę – šalinimą įgyvendinti neprivaloma, bet rekomenduojama.

/ Sauga

Saugos pastabos

  • Visada tikrinkite Bearer token. Jūsų endpoint yra viešas URL – jį gali iškviesti bet kas. Authorization antraštė yra vienintelis įrodymas, kad užklausa tikrai atėjo iš Orova, todėl atmeskite kiekvieną užklausą, kurios token tiksliai nesutampa su jūsų saugomu slaptuoju raktu.
  • Teikite endpoint per HTTPS. Slaptasis raktas keliauja antraštėje. HTTPS neleidžia jo perskaityti perdavimo metu.
  • Laikykite slaptąjį raktą ne kode. Laikykite jį aplinkos kintamajame arba slaptųjų duomenų saugykloje, niekada neįrašykite tiesiai į failą, kurį įkeliate į repozitoriją. Jei jis kada nors nutekėtų, sugeneruokite naują skiltyje Projektas → Ryšiai.
  • Laikykite content_html turiniu, o ne patikimu žymėjimu. Saugokite ir rodykite jį taip pat atsargiai, kaip ir bet kurį kitą straipsnio tekstą savo TVS.

/ Apibendrinimas

Tai ir visa sutartis

Kai galinis taškas veikia ir yra užregistruotas jūsų projekte, Orova automatiškai skelbia straipsnius jūsų svetainėje – lygiai taip pat, kaip WordPress naudotojams. Kiekvienas parengtas straipsnis pasiekia jūsų serverį, tampa įrašu, o jo viešas URL grįžta į Ataskaitas ir Analizę, kad galėtumėte stebėti jo rezultatus.

← Atgal į vadovų biblioteką

/ Reikia pagalbos?

Nepavyksta prijungti galinio taško? Atidarykite skiltį Pagalba savo darbo erdvėje arba parašykite mums.