Conectați-vă Începeți perioada de probă gratuită

Preluați-vă articolele.
Publicați-le în felul dumneavoastră.

Fiecare articol pe care îl scriem pentru dumneavoastră poate fi citit prin HTTP: titlul, metadatele, Markdown-ul, HTML-ul, imaginea principală și întrebările frecvente. Preluați-le în site-ul dumneavoastră Next.js, Astro sau personalizat când rulează build-ul, publicați-le și spuneți-ne adresa la care a ajuns fiecare.

Un token bearer. JSON la intrare, JSON la ieșire. Niciun SDK de instalat și nimic de configurat în afară de o cheie.

Webhook-ul trimite. API-ul vă permite să preluați.

Transmit același articol în aceeași formă, astfel încât un parser scris pentru una o citește și pe cealaltă fără modificări. Diferența este cine începe conversația.

Webhook-ul, când site-ul dumneavoastră poate accepta o postare la orice oră

Apelăm endpoint-ul dumneavoastră în momentul în care un articol este gata și din nou când se schimbă. Nimic de interogat periodic, nimic de programat. WordPress, Shopify, Ghost, un trigger Zapier sau o rută scrisă chiar de dumneavoastră.

API-ul, când site-ul dumneavoastră este construit și implementat ca o unitate

Un site static nu poate accepta o postare la șase și jumătate dimineața, mai întâi trebuie refăcut ceva. Așa că build-ul dumneavoastră întreabă ce așteaptă, îl preia și ne spune adresa după aceea. Dumneavoastră alegeți când.

Ambele, dacă le doriți

Sunt conexiuni separate și niciuna nu o exclude pe cealaltă. Un webhook care alimentează un newsletter și un API care alimentează site-ul web este o configurație normală.

O cheie, trimisă ca token bearer.

Creați o cheie în panoul de control, la Settings, apoi Connections. Este afișată o singură dată, când este creată, deoarece este stocat doar hash-ul ei: dacă o pierdeți, revocați-o și creați alta. O cheie citește fiecare site din cont și este revocată din același ecran.

Fiecare cerere

Authorization: Bearer sns_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept: application/json

Verificați că funcționează

curl https://seonis.ai/api/v1/me \
  -H "Authorization: Bearer $SEONIS_API_KEY"
{
  "organisation": { "id": 12, "name": "Peppervale", "country": "GB" },
  "key": {
    "name": "Production build",
    "prefix": "sns_live_ab",
    "created_at": "2026-09-06T09:12:44+00:00",
    "last_used_at": "2026-09-06T09:31:02+00:00"
  },
  "sites": 2
}

Limită de rată

120 cereri pe minut, numărate pentru cheie, nu pentru adresa de la care vin, deoarece runner-ele de build împart adresele. Peste această limită primiți 429 cu antetele standard Retry-After și X-RateLimit. Preluarea articolelor pentru un build înseamnă doar câteva cereri, deci nu este o limită pe care ar trebui să o atingeți din greșeală.

Nu păstrați cheia în repository-ul dumneavoastră

Citește tot ce am scris pentru contul dumneavoastră, inclusiv articolele care nu sunt încă publicate. Puneți-o în mediul dumneavoastră de build, nu în sursă. Revocați-o aici în momentul în care ajunge undeva unde nu ar trebui să fie, iar orice o folosește primește imediat 401.

Sunt cinci, iar patru doar citesc.

Totul se află sub /api/v1/. Versiunea este în cale din prima zi, astfel încât într-o zi să poată exista un v2 fără să strice ce scrieți astăzi.

GET /api/v1/me

Contul căruia îi aparține cheia și numele și prefixul cheii. Util mai ales pentru un singur lucru: să vă spună că cheia din acest mediu este cheia care credeți că este.

Exemplu

curl https://seonis.ai/api/v1/me \
  -H "Authorization: Bearer $SEONIS_API_KEY"
GET /api/v1/sites

Fiecare site din cont. id este ceea ce folosește lista de articole pentru filtrare, iar domeniul este acolo pentru ca un script de build să poată potrivi după ceva ce știe deja, în loc să poarte un id.

Exemplu

curl https://seonis.ai/api/v1/sites \
  -H "Authorization: Bearer $SEONIS_API_KEY"
{
  "sites": [
    {
      "id": 5,
      "name": "Peppervale",
      "domain": "peppervale.co.uk",
      "url": "https://peppervale.co.uk",
      "language": "en",
      "country": "GB",
      "market": "en-GB",
      "status": "active",
      "articles_published": 34,
      "created_at": "2026-06-02T11:04:19+00:00"
    }
  ]
}
GET /api/v1/articles

O pagină de articole, cu cea mai nouă modificare prima, fără conținut. Ordonate după momentul ultimei modificări a fiecărui articol, nu după momentul în care a fost scris, ceea ce face ca updated_since să fie util: un articol deja publicat poate fi editat mai târziu, când un link este adăugat în el sau scos din nou.

Parametri de interogare

Nume Ce face
site_id Un site, din /sites. Un id care nu este în contul dumneavoastră răspunde cu 404.
status Una dintre draft, qa, needs_repair, review, ready, published, failed. Orice altceva este 422, nu o pagină goală. "ready" este ce vrea un build: scris, verificat și încă nicăieri.
updated_since ISO 8601, cum ar fi 2026-09-06T00:00:00Z. Rețineți timestamp-ul ultimei rulări și trimiteți-l înapoi la următoarea.
per_page Până la 100. Valoarea implicită este 25.
page De la 1. meta.has_more spune dacă să cereți încă una.

Exemplu

curl -G https://seonis.ai/api/v1/articles \
  -H "Authorization: Bearer $SEONIS_API_KEY" \
  -d site_id=5 \
  -d status=ready \
  -d updated_since=2026-09-01T00:00:00Z \
  -d per_page=50
{
  "articles": [
    {
      "id": 918,
      "site_id": 5,
      "language": "en",
      "status": "ready",
      "title": "How to choose a pepper grinder",
      "slug": "how-to-choose-a-pepper-grinder",
      "meta_title": "How to choose a pepper grinder | Peppervale",
      "meta_description": "Burr or blade, ceramic or steel: what matters in a grinder.",
      "meta_keywords": ["pepper grinder", "burr grinder"],
      "tags": ["Kitchen"],
      "excerpt": "A burr grinder gives an even grind; a blade one does not.",
      "key_takeaways": ["A burr grinder gives an even grind; a blade one does not."],
      "faq": [{ "question": "Ceramic or steel?", "answer": "Steel for pepper, ceramic for salt." }],
      "hero_image": { "url": "https://seonis.ai/storage/images/5/918.jpg", "alt": "A pepper grinder" },
      "infographic_url": null,
      "word_count": 1812,
      "published_url": null,
      "published_at": null,
      "updated_at": "2026-09-06T06:31:12+00:00",
      "created_at": "2026-09-05T02:14:55+00:00",
      "quality": { "seo_score": 88, "language_score": 96, "language_findings": [] }
    }
  ],
  "meta": { "page": 1, "per_page": 50, "total": 1, "last_page": 1, "has_more": false }
}
GET /api/v1/articles/{id}

Un articol, cu tot ce omite lista: content_markdown, content_html, întrebările frecvente ca schema.org JSON-LD gata de pus în pagină și orice linkuri de schimb pe care le conține articolul.

Numele câmpurilor sunt cele trimise de webhook-ul nostru, intenționat. Dacă aveți deja un receptor pentru webhook, același parser citește și asta.

Exemplu

curl https://seonis.ai/api/v1/articles/918 \
  -H "Authorization: Bearer $SEONIS_API_KEY"
{
  "article": {
    "id": 918,
    "site_id": 5,
    "language": "en",
    "status": "ready",
    "title": "How to choose a pepper grinder",
    "slug": "how-to-choose-a-pepper-grinder",
    "meta_description": "Burr or blade, ceramic or steel: what matters in a grinder.",
    "content_markdown": "Grinders differ.\n\n## Burr or blade\n\nA **burr** grinder ...",
    "content_html": "<p>Grinders differ.</p>\n<h2>Burr or blade</h2> ...",
    "faq_schema": { "@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [] },
    "hero_image": { "url": "https://seonis.ai/storage/images/5/918.jpg", "alt": "A pepper grinder" },
    "word_count": 1812,
    "published_url": null,
    "updated_at": "2026-09-06T06:31:12+00:00",
    "quality": { "seo_score": 88, "language_score": 96, "language_findings": [] },
    "exchange_links": []
  }
}
POST /api/v1/articles/{id}/published

Publicați articolul; aici ne spuneți adresa. Este singurul endpoint care schimbă ceva.

Face exact ce face o livrare făcută chiar de noi: articolul este marcat ca publicat, este numărat în alocarea dumneavoastră lunară, elementul din plan se închide, orice linkuri de schimb din el primesc adresa pe care o aștepta verificatorul, iar Pagina dumneavoastră de Facebook este notificată dacă ați conectat una. Fără acest apel, articolul rămâne pregătit pentru totdeauna și nimic din toate acestea nu se întâmplă.

Exemplu

curl -X POST https://seonis.ai/api/v1/articles/918/published \
  -H "Authorization: Bearer $SEONIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://peppervale.co.uk/blog/how-to-choose-a-pepper-grinder"}'

Răspunsuri

200 Înregistrat. Articolul revine cu noul său status, published_at și published_url.
422 Lipsește URL-ul sau nu este o adresă completă http:// sau https://.
409 Articolul nu este gata de publicare sau este deja înregistrat ca publicat. Articolul revine împreună cu refuzul, ca să puteți vedea care dintre situații se aplică.

Conectați "REST API" ca motor de publicare.

Sub Settings, apoi Publishing, există un motor numit "REST API: dumneavoastră preluați și publicați". Nu cere nimic, pentru că nu avem nimic de trimis. Ce schimbă este ce se întâmplă în fiecare dimineață: un articol finalizat rămâne pregătit fără adresă, iar ecranul de publicare spune că așteaptă să îl preluați, în loc să afișeze o livrare eșuată.

Puteți folosi API-ul fără să îl conectați: endpoint-urile funcționează pentru orice cont cu o cheie. Conectarea lui este modul în care restul produsului știe să nu mai aștepte o adresă proprie și este ceea ce împiedică un articol publicat de dumneavoastră să fie considerat un eșec.

Fiecare eroare este JSON cu un mesaj.

O singură formă peste tot, fie că refuzul vine din verificarea cheii sau de la validator, astfel încât nimic să nu trebuiască să interpreteze două.

{ "message": "That API key is not valid, or it has been revoked." }
Stare Ce înseamnă
401 Nicio cheie, o cheie care nu este a noastră sau o cheie care a fost revocată.
404 Nu există un astfel de articol sau site în acest cont. Articolul altui cont răspunde cu 404, nu cu 403: un API care spune "acela nu este al dumneavoastră" a confirmat că acel lucru există.
409 Cererea a fost în regulă, dar articolul nu este într-o stare potrivită pentru asta.
422 Lipsește un parametru sau este greșit. Răspunsul include un obiect errors care numește câmpul, precum și mesajul.
429 Peste limita de rată. Retry-After spune cât trebuie să așteptați.

Ce face de fapt un pas de build.

#!/usr/bin/env bash
set -euo pipefail

# 1. What is finished and not yet on the site?
ready=$(curl -sG https://seonis.ai/api/v1/articles \
  -H "Authorization: Bearer $SEONIS_API_KEY" \
  -d site_id=5 -d status=ready -d per_page=100)

for id in $(echo "$ready" | jq -r '.articles[].id'); do
  # 2. Take the article, body and all.
  curl -s https://seonis.ai/api/v1/articles/$id \
    -H "Authorization: Bearer $SEONIS_API_KEY" \
    | jq -r '.article.content_markdown' > "content/posts/$id.md"

  # 3. Your build puts it live, and you know where it landed.
  slug=$(echo "$ready" | jq -r ".articles[] | select(.id==$id) | .slug")

  curl -s -X POST https://seonis.ai/api/v1/articles/$id/published \
    -H "Authorization: Bearer $SEONIS_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"url\": \"https://peppervale.co.uk/blog/$slug\"}"
done

Creați o cheie și încercați-o.

Perioada de probă este suficientă pentru a citi API-ul: articolele scrise în această perioadă sunt articole reale și revin prin aceste endpoint-uri ca oricare altele.

Începeți perioada de probă gratuită