/ Ceļvedis izstrādātājiem
Publicēšana caur API jebkurā vietnē.
Kā izveidot savu galapunktu, lai Orova varētu publicēt gatavus rakstus vietnē, kas nedarbojas ar WordPress.
Orova jau no paša sākuma publicē gatavus rakstus WordPress. Ja jūsu vietne nav WordPress — pielāgota CMS, headless risinājums, statiska vietne vai jūsu pašu backend — jūs joprojām varat ļaut Orova publicēt automātiski, pieņemot rakstus caur nelielu API. Jūs uzrakstāt vienu HTTP galapunktu; Orova to izsauc katru reizi, kad pabeidz rakstu. Šis ceļvedis ir paredzēts izstrādātājam un apraksta pilnu pieprasījuma līgumu.
/ Pārskats
Kā tas darbojas
Kad Orova pabeidz rakstu atslēgvārdam, tā nosūta vienu HTTP POST pieprasījumu uz jūsu reģistrēto galapunkta URL. Pieprasījuma ķermenis ir JSON un satur visu rakstu. Jūsu galapunkts izveido ierakstu jūsu pusē un atbild ar raksta galīgo, publisko URL. Orova saglabā šo URL kā publicēto saiti, tāpat kā WordPress ierakstam. Izmantojiet to, ja vēlaties automātisku publicēšanu vietnē, kas nav WordPress, vai vēlaties pilnībā kontrolēt, kā ieraksti tiek glabāti.
/ Iestatīšana
Iestatīšana — seši soļi
- 1
Ieslēdziet “Savienot, izmantojot API” savā projektā. Atveriet savu projektu (Projekti → jūsu projekts → Savienojumi). Blakus WordPress kartītei ir kartīte Savienot, izmantojot API. Ievadiet tajā sava galapunkta URL. Slepenās atslēgas lauks nav obligāts: atstājiet to tukšu, un Orova to ģenerēs, vai ielīmējiet atslēgu, ko jūsu vietne jau izmanto. Pēc saglabāšanas atslēga tiek rādīta kartītē ar pogu Kopēt. Projekts publicē tikai vienā mērķī — savienojums caur API bloķē WordPress pogu un otrādi.
- 2
Izveidojiet galapunktu, kas pieņem POST. Savā vietnē vai serverī izveidojiet maršrutu, kas klausās HTTP POST ar JSON ķermeni. Šo URL jūs ielīmējat atpakaļ projekta Savienojumu ekrānā. Orova to izsauc vienreiz par katru pabeigto rakstu.
- 3
Pārbaudiet Bearer token katrā pieprasījumā. Katrs Orova pieprasījums satur Authorization galveni formā “Bearer <secret>”, izmantojot tieši to slepeno atslēgu, kas redzama jūsu projektā. Salīdziniet to ar savu saglabāto kopiju un noraidiet visu, kas nesakrīt — tas ir tas, kas neļauj nevienam citam publicēt jūsu vietnē.
- 4
Izveidojiet rakstu no payload. Nolasiet JSON ķermeni un izveidojiet ierakstu savā CMS vai datubāzē: izmantojiet title, slug un content_html pašam rakstam, excerpt kā meta aprakstu, featured_image_url kā vāka attēlu, bet keyword / lang / published_at kā metadatus.
- 5
Atgrieziet raksta publisko URL. Atbildiet ar HTTP 200 vai 201 un JSON ķermeni { "url": "https://yoursite.com/the-new-article" }. Orova saglabā šo URL kā raksta publicēto saiti. Ja atgriežat statusu ārpus 2xx vai izlaižat lauku url, Orova uzskata publicēšanu par neveiksmīgu.
- 6
Apstrādājiet atjaunināšanas pieprasījumus no Optimizācijas dzinēja. Kad ķermenī ir action = "update", atrodiet esošo ierakstu pēc target_url (vai slug) un pārrakstiet tā title, content_html un excerpt vietā — URL paliek nemainīgs. Atbildiet 200 ar { "url": ... }, kas norāda uz to pašu ierakstu. Galapunkti, kas to vēl neapstrādā, vienkārši liks Orova ziņot par neveiksmīgu optimizāciju; jaunu rakstu publicēšana turpina darboties kā iepriekš.
/ Līgums
Pieprasījums, ko sūta Orova
Katrs pabeigtais raksts pienāk kā viens šāda veida pieprasījums:
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./ Uzziņas
Payload lauki
Publicēšanas (jauna raksta) pieprasījuma lauki. Dzēšanas un atjaunināšanas pieprasījumi izmanto to pašu galapunktu ar mazākiem ķermeņiem, kas parādīti to sadaļās zemāk.
| Lauks | Tips | Apraksts |
|---|---|---|
| title | string | Raksta virsraksts. |
| slug | string | URL-friendly identifier suggested for the post. |
| content_html | string | Pilns raksta saturs kā publicēšanai gatavs HTML. |
| excerpt | string | Īss kopsavilkums, paredzēts meta aprakstam. |
| featured_image_url | string | null | Vāka attēla URL vai null, ja tā nav. |
| keyword | string | Mērķa SEO atslēgvārds, kuram raksts tika uzrakstīts. |
| lang | string | Language as an ISO code, e.g. "en" or "vi". |
| published_at | string | Brīdis, kad Orova nosūtīja rakstu, ISO 8601 formātā UTC laikā, bez laika joslas sufiksa. |
| status | string | undefined | Nav obligāts. "draft" atstāj rakstu nepublicētu; "publish" vai nekāda vērtība to publicē. |
| action | string | undefined | Nav jauniem rakstiem. "delete" prasa noņemt ierakstu; "update" (sūta Optimizācijas dzinējs) prasa pārrakstīt esošu ierakstu vietā. |
| target_url | string | Tikai ar action = "update": pārrakstāmā ieraksta publiskais URL. Atstājiet URL nemainīgu. |
| id | number | undefined | Only sent when Orova knows your post id (from `list` or `get`): match on it before `target_url`. |
Neobligātie lauki tiek pilnībā izlaisti no ķermeņa, ja nav ko sūtīt — Orova nekad nesūta null, tāpēc lasiet tos piesardzīgi. Arī status nav obligāts: "draft" izveido rakstu kā melnrakstu, bet "publish" vai status neesamība to publicē uzreiz.
/ Līgums
Atbilde, kas jums jāatgriež
Kad esat izveidojis ierakstu, atbildiet ar HTTP 200 vai 201 statusu un šo JSON ķermeni:
HTTP 200 (or 201)
Content-Type: application/json
{
"url": "https://yoursite.com/published-article"
}Orova saglabā šo url kā raksta publicēto saiti. Ja jūsu galapunkts atgriež jebkuru statusu ārpus 2xx vai ķermeni, kas nav JSON objekts ar lauku url, Orova uzskata publicēšanu par neveiksmīgu un attiecīgi atzīmē rakstu, lai varētu mēģināt vēlreiz. Atbildiet 60 sekunžu laikā — pēc tam Orova pārtrauc pieprasījumu (tas attiecas uz publicēšanu, atjaunināšanu un dzēšanu).
/ Piemērs
Koda piemērs
Minimāls saņemšanas galapunkts Node.js ar Express. Tie paši soļi — pārbaudīt token, sazarot pēc action (update / delete), izveidot vai mainīt ierakstu, atgriezt URL — attiecas uz jebkuru valodu vai ietvaru.
// 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);/ Līgums — atjaunināšana
Rakstu atjaunināšana (Optimizācija)
Orova Optimizācijas dzinējs pārraksta jau publicētus rakstus — atsvaidzināti fakti, labāki virsraksti, apvienots saturs — un pēc tam pārraksta esošo ierakstu vietā, saglabājot URL nemainīgu. Pieprasījums tiek nosūtīts uz to pašu galapunkta URL kā POST ar to pašu 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.Atrodiet ierakstu pēc target_url (rezerves variants — slug), aizstājiet tā virsrakstu, saturu un meta aprakstu, atstājiet URL kā ir, pēc tam atbildiet 200 ar { "url": "<same post URL>" }. Jebkurš statuss ārpus 2xx vai ķermenis bez url liek Orova atzīmēt optimizāciju kā neveiksmīgu (tā nekad neizveido dublētu ierakstu). Galapunkti, kas to vēl nav ieviesuši, turpina publicēt jaunus rakstus bez izmaiņām — atjaunināšana jāievieš tikai tad, kad izmantojat Optimizācijas ekrānu.
Kopš 29. augusta atjaunināšanas ķermenī var būt arī id (salīdziniet pēc tā pirms target_url), featured_image_url jaunam vāka attēlam un status ar vērtību "publish" vai "draft". Visi trīs nav obligāti; ja tie ir tukši, tie tiek izlaisti no ķermeņa, nekad netiek sūtīti kā null.
/ Līgums — Vizuālais redaktors
Rakstu lasīšana (obligāti)
Orova jāspēj lasīt raksti, kas jau ir jūsu vietnē — lai izvairītos no dublētām tēmām, pievienotu iekšējās saites un optimizētu vecākus ierakstus. Pievienojiet vēl divas action tajā pašā galapunkta URL ar to pašu Bearer token: list atgriež jūsu rakstus, get atgriež vienu no tiem pilnībā.
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 ir ierobežots līdz 500, un jaunākais raksts ir pirmais. Ar get Orova sūta id, target_url un slug kopā — salīdziniet pēc tā, ko atpazīstat, šādā secībā. Ja nekas nesakrīt, atbildiet 404 ar { "ok": false, "err": "not_found" }. excerpt sarakstā list nav obligāts (maks. 300 rakstzīmes). Obligāti: Orova izsauc list, lai uzzinātu, kuri raksti jau pastāv (lai izvairītos no dublikātiem, pievienotu iekšējās saites un analizētu visu vietni), un izsauc get, lai lasītu rakstu, to optimizējot. Ja jūsu vietne neatbild uz šīm divām action, jaunie raksti nesaņem iekšējās saites un vecākus rakstus nevar optimizēt.
/ Līgums — Vizuālais redaktors
Attēlu augšupielāde (Vizuālais redaktors)
Kad ievelkat attēlu Vizuālajā redaktorā, Orova to nosūta uz to pašu galapunkta URL kā base64 JSON ķermenī — bez multipart, bez otra URL, kas jāaizsargā.
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
}Pieņemiet tikai image/* un noraidiet visu, kas pārsniedz 15 MB. Saglabājiet failu, pēc tam atbildiet ar attēla absolūto URL: relatīvs ceļš salauž rakstu, tiklīdz tas tiek attēlots citur. Šī darbība vajadzīga tikai Vizuālajam redaktoram.
/ Līgums — dzēšana
Rakstu dzēšana
Kad lietotājs noņem publicētu rakstu Orova iekšienē (ekrānā Rakstīt vai Pārskats), Orova lūdz jūsu vietni to arī izdzēst. Pieprasījums tiek nosūtīts uz to pašu galapunkta URL kā POST ar to pašu Bearer token — atšķiras tikai ķermenis:
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
}Atrodiet ierakstu pēc url (rezerves variants — slug), noņemiet vai atceliet tā publicēšanu, pēc tam atbildiet ar 200 un { "deleted": true } — der arī tukšs 204. Ja ieraksts vairs nepastāv, atbildiet 404, un Orova to uzskatīs par jau izdzēstu. Atgriežot { "deleted": false }, jūs paziņojat Orova, ka ieraksts netika noņemts. Parastie publicēšanas pieprasījumi nekad nesatur lauku action, tāpēc esošie galapunkti turpina darboties bez izmaiņām — dzēšanas ieviešana nav obligāta, bet ieteicama.
/ Drošība
Drošības piezīmes
- Vienmēr pārbaudiet Bearer token. Jūsu galapunkts ir publisks URL — to var izsaukt jebkurš. Authorization galvene ir vienīgais, kas pierāda, ka pieprasījums tiešām nāk no Orova, tāpēc noraidiet katru pieprasījumu, kura token precīzi nesakrīt ar jūsu saglabāto slepeno atslēgu.
- Izmantojiet galapunktam HTTPS. Slepenā atslēga tiek pārsūtīta galvenē. HTTPS neļauj to nolasīt pārsūtīšanas laikā.
- Neturiet slepeno atslēgu kodā. Glabājiet to vides mainīgajā vai noslēpumu pārvaldniekā, nekad neierakstiet to failā, ko iesniedzat (commit). Ja tā kādreiz tiek atklāta, ģenerējiet jaunu sadaļā Projekti → Savienojumi.
- Uztveriet content_html kā saturu, nevis kā uzticamu marķējumu. Glabājiet un attēlojiet to tikpat uzmanīgi kā jebkuru raksta saturu savā CMS.
/ Noslēgumā
Tas ir viss līgums
Kad galapunkts darbojas un ir reģistrēts jūsu projektā, Orova publicē jūsu vietnē automātiski — tieši tāpat kā WordPress lietotājiem. Katrs pabeigtais raksts nonāk jūsu serverī, kļūst par ierakstu, un tā publiskais URL atgriežas sadaļās Pārskats un Analīze, lai jūs varētu sekot tā rezultātiem.
/ Vajadzīga palīdzība?
Neizdodas pieslēgt galapunktu? Atveriet sadaļu Atbalsts savā darbvietā vai nosūtiet mums ziņu.
