Kirjaudu sisään Aloita ilmainen kokeilu

Noutakaa artikkelinne.
Julkaiskaa ne omalla tavallanne.

Jokainen teille kirjoittamamme artikkeli voidaan lukea HTTP:n kautta: otsikko, metatiedot, Markdown, HTML, hero-kuva ja FAQ. Tuokaa ne Next.js-, Astro- tai mukautetulle sivustollenne buildin aikana, julkaiskaa ne ja kertokaa meille osoite, johon kukin päätyi.

Yksi bearer token. JSON sisään, JSON ulos. Ei asennettavaa SDK:ta eikä mitään määritettävää avaimen lisäksi.

Webhook lähettää. API antaa Teidän hakea.

Ne välittävät saman artikkelin samassa muodossa, joten toiselle kirjoitettu jäsennin lukee myös toisen muuttamattomana. Ero on siinä, kumpi aloittaa yhteyden.

Webhook, kun sivustonne voi vastaanottaa postauksen mihin aikaan tahansa

Kutsumme päätepistettänne heti, kun artikkeli on valmis, ja uudelleen, kun se muuttuu. Ei kyselyä, ei ajastettavaa. WordPress, Shopify, Ghost, Zapier-laukaisin tai itse kirjoittamanne reitti.

API, kun sivustonne rakennetaan ja otetaan käyttöön yhtenä kokonaisuutena

Staattinen sivusto ei voi vastaanottaa julkaisua puoli seitsemältä aamulla, vaan jotain on rakennettava ensin uudelleen. Siksi buildinne kysyy, mitä odottaa, hakee sen ja kertoo meille osoitteen jälkeenpäin. Te päätätte milloin.

Molemmat, jos haluatte

Ne ovat erillisiä yhteyksiä, eikä kumpikaan sulje toista pois. Webhook, joka syöttää uutiskirjettä, ja API, joka syöttää verkkosivustoa, on tavallinen järjestely.

Yksi avain, lähetetään bearer tokenina.

Luokaa avain hallintapaneelissa kohdassa Settings, sitten Connections. Se näytetään kerran, kun se luodaan, koska vain sen tiiviste tallennetaan: jos kadotatte sen, kumotkaa se ja tehkää uusi. Avain lukee tilin kaikki sivustot, ja se kumotaan samasta näkymästä.

Jokainen pyyntö

Authorization: Bearer sns_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept: application/json

Tarkistakaa, että se toimii

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
}

Nopeusraja

120 pyyntöä minuutissa, laskettuna avainta eikä lähdeosoitetta kohti, koska build runnerit jakavat osoitteita. Sen yli saatte 429-vastauksen tavallisilla Retry-After- ja X-RateLimit-otsakkeilla. Artikkelien noutaminen buildia varten on vain muutama pyyntö, joten tähän rajaan ei pitäisi osua vahingossa.

Pitäkää avain poissa repositoriostanne

Se lukee kaiken, mitä olemme kirjoittaneet tilillenne, myös artikkelit, joita ei ole vielä julkaistu. Laittakaa se build-ympäristöönne, ei lähdekoodiin. Kumotkaa se täällä heti, jos se päätyy paikkaan, jossa sen ei pitäisi olla, ja kaikki sitä käyttävä saa heti 401-vastauksen.

Niitä on viisi, ja neljä niistä vain lukee.

Kaikki on polun /api/v1/ alla. Versio on polussa alusta asti, joten v2 voi joskus olla olemassa rikkomatta sitä, mitä kirjoitatte tänään.

GET /api/v1/me

Tili, jolle avain kuuluu, sekä avaimen oma nimi ja etuliite. Tästä on hyötyä ennen kaikkea yhdessä asiassa: se kertoo Teille, että tämän ympäristön avain on se avain, joksi luulette sitä.

Esimerkki

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

Jokainen tilin sivusto. id:tä artikkeliluettelo suodattaa, ja domain on mukana, jotta build-skripti voi kohdistaa johonkin jo tuntemaansa eikä kuljettaa mukana id:tä.

Esimerkki

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

Sivu artikkeja, uusin muutos ensin, ilman sisältöä. Järjestetty sen mukaan, milloin kukin artikkeli on viimeksi muuttunut eikä milloin se kirjoitettiin, mikä tekee updated_since-parametrista hyödyllisen: jo julkaistua artikkelia voidaan muokata myöhemmin, kun siihen lisätään linkki tai siitä poistetaan linkki.

Kyselyparametrit

Nimi Mitä se tekee
site_id Yksi sivusto, osoitteesta /sites. id, jota ei ole tilillänne, vastaa 404.
status Yksi seuraavista: draft, qa, needs_repair, review, ready, published, failed. Mikä tahansa muu antaa 422-vastauksen tyhjän sivun sijaan. "ready" on se, mitä build haluaa: kirjoitettu, tarkistettu eikä vielä missään.
updated_since ISO 8601, kuten 2026-09-06T00:00:00Z. Muistakaa viimeisimmän ajon aikaleima ja välittäkää se takaisin seuraavalla kerralla.
per_page Enintään 100. Oletus on 25.
page Alkaen arvosta 1. meta.has_more kertoo, pitääkö pyytää seuraava.

Esimerkki

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}

Yksi artikkeli, mukana kaikki mitä luettelo ei sisällä: content_markdown, content_html, FAQ schema.org JSON-LD -muodossa valmiina lisättäväksi sivulle sekä kaikki artikkelin sisältämät vaihtolinkit.

Kenttien nimet ovat tarkoituksella samat, jotka webhookimme lähettää. Jos Teillä on jo webhook-vastaanotin, sama jäsennin lukee myös tämän.

Esimerkki

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

Te julkaiset artikkelin; tässä kerrotte meille osoitteen. Tämä on ainoa päätepiste, joka muuttaa mitään.

Se tekee täsmälleen saman kuin itse tekemämme toimitus: artikkeli merkitään julkaistuksi, se lasketaan kuukausikiintiöönne, suunnitelman kohta suljetaan, kaikki sen vaihtolinkit saavat osoitteen, jota tarkistin on odottanut, ja Facebook-sivullenne ilmoitetaan, jos olette yhdistäneet sellaisen. Ilman tätä kutsua artikkeli pysyy valmiina ikuisesti eikä mitään tästä tapahdu.

Esimerkki

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"}'

Vastaukset

200 Tallennettu. Artikkeli palautuu uuden tilansa sekä kenttien published_at ja published_url kanssa.
422 URL puuttuu tai ei ole täydellinen http://- tai https://-osoite.
409 Artikkeli ei ole valmis julkaistavaksi tai se on jo merkitty julkaistuksi. Artikkeli palautuu hylkäyksen mukana, jotta näette kummasta on kyse.

Yhdistäkää "REST API" julkaisumoottoriksi.

Kohdassa Asetukset, sitten Julkaiseminen, on moottori nimeltä "REST API: Te haette ja julkaisette". Se ei pyydä mitään, koska meillä ei ole mitään lähetettävää. Se muuttaa sitä, mitä tapahtuu joka aamu: valmis artikkeli pysyy valmiina ilman osoitetta, ja julkaisunäyttö kertoo odottavansa, että haette sen, sen sijaan että se näyttäisi epäonnistuneen toimituksen.

Voitte käyttää API:a yhdistämättä sitä: päätepisteet toimivat kaikilla tileillä, joilla on avain. Yhdistäminen kertoo muulle tuotteelle, että sen pitää lakata odottamasta omaa osoitetta, ja se estää itse julkaisemanne artikkelin laskemisen epäonnistumiseksi.

Jokainen virhe on JSON, jossa on viesti.

Sama muoto kaikkialla, tulipa hylkäys avaintarkistuksesta tai validaattorilta, joten mitään ei tarvitse jäsentää kahdesti.

{ "message": "That API key is not valid, or it has been revoked." }
Tila Mitä se tarkoittaa
401 Ei avainta, avain joka ei ole meidän, tai avain joka on kumottu.
404 Tällä tilillä ei ole sellaista artikkelia tai sivustoa. Toisen tilin artikkeli vastaa 404 eikä 403: API, joka sanoo "se ei ole teidän", on vahvistanut, että kohde on olemassa.
409 Pyyntö oli kunnossa, mutta artikkeli ei ole siihen sopivassa tilassa.
422 Parametri puuttuu tai on virheellinen. Vastauksessa on errors-objekti, jossa on kentän nimi sekä viesti.
429 Nopeusrajan yli. Retry-After kertoo, kuinka kauan pitää odottaa.

Mitä build-vaihe oikeasti tekee.

#!/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

Luokaa avain ja kokeilkaa sitä.

Kokeilujakso riittää API:n käyttöön: sen aikana kirjoitetut artikkelit ovat oikeita artikkeleita, ja ne palautuvat näiden päätepisteiden kautta kuten muutkin.

Aloita ilmainen kokeilu