Logg inn Start kostnadsfri prøveperiode

Hent artiklene Deres.
Publiser dem på Deres måte.

Hver artikkel vi skriver for Dem kan leses over HTTP: tittelen, metadataene, Markdown, HTML, hovedbildet og FAQ-en. Ta dem inn i Deres Next.js-, Astro- eller tilpassede nettsted når builden kjører, publiser dem, og fortell oss hvilken adresse hver av dem endte opp på.

Ett bearer-token. JSON inn, JSON ut. Ingen SDK å installere og ingenting å konfigurere utover en nøkkel.

Webhooken sender. API-et lar Dem hente.

De bærer den samme artikkelen i samme form, så en parser skrevet for den ene leser den andre uendret. Forskjellen er hvem som starter samtalen.

Webhooken, når nettstedet Deres kan ta imot et innlegg når som helst

Vi kaller endepunktet Deres i det øyeblikket en artikkel er klar, og igjen når den endres. Ingenting å polle, ingenting å planlegge. WordPress, Shopify, Ghost, en Zapier-utløser eller en rute De har skrevet selv.

API-et, når nettstedet Deres bygges og distribueres som en enhet

Et statisk nettsted kan ikke ta imot et innlegg halv sju om morgenen, noe må bygges på nytt først. Derfor spør builden Deres hva som venter, henter det og forteller oss adressen etterpå. De velger når.

Begge, hvis De vil

De er separate tilkoblinger, og ingen av dem utelukker den andre. En webhook som mater et nyhetsbrev og et API som mater nettstedet, er et normalt oppsett.

Én nøkkel, sendt som et bearer-token.

Opprett en nøkkel i kontrollpanelet under Settings, deretter Connections. Den vises én gang, når den opprettes, fordi bare hashen lagres: hvis De mister den, tilbakekall den og opprett en ny. En nøkkel leser hvert nettsted på kontoen og tilbakekalles fra samme skjermbilde.

Hver forespørsel

Authorization: Bearer sns_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept: application/json

Kontroller at det virker

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
}

Fartsgrense

120 forespørsler i minuttet, telt mot nøkkelen i stedet for adressen den kommer fra, fordi build-runnere deler adresser. Over det får De 429 med standardhodene Retry-After og X-RateLimit. Å hente artikler til en build er bare en håndfull forespørsler, så dette er ikke en grense De bør treffe ved et uhell.

Hold nøkkelen utenfor repositoriet Deres

Den leser alt vi har skrevet for kontoen Deres, inkludert artikler som ennå ikke er publisert. Legg den i build-miljøet Deres, ikke i kildekoden. Tilbakekall den her med en gang den er et sted den ikke skal være, så får alt som bruker den 401 umiddelbart.

Fem av dem, og fire leser bare.

Alt ligger under /api/v1/. Versjonen er i stien fra første dag, så en v2 kan en dag finnes uten å bryte det De skriver i dag.

GET /api/v1/me

Kontoen nøkkelen tilhører, og nøkkelens eget navn og prefiks. Nyttig fremfor alt til én ting: å fortelle Dem at nøkkelen i dette miljøet er nøkkelen De tror det er.

Eksempel

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

Hvert nettsted på kontoen. id er det artikkellisten filtrerer på, og domenet er der slik at et build-skript kan matche mot noe det allerede kjenner til i stedet for å bære med seg en id.

Eksempel

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

En side med artikler, nyeste endring først, uten selve teksten. Sortert etter når hver artikkel sist ble endret i stedet for når den ble skrevet, og det er derfor updated_since er nyttig: en artikkel som allerede er publisert, kan redigeres senere, når en lenke settes inn i den eller tas ut igjen.

Spørringsparametere

Navn Hva det gjør
site_id Ett nettsted, fra /sites. En id som ikke er på kontoen Deres, svarer 404.
status En av draft, qa, needs_repair, review, ready, published, failed. Alt annet er 422 i stedet for en tom side. "ready" er det en build vil ha: skrevet, kontrollert og ennå ikke publisert noe sted.
updated_since ISO 8601, som 2026-09-06T00:00:00Z. Husk tidsstempelet for siste kjøring og send det tilbake ved neste.
per_page Opptil 100. Standardverdien er 25.
page Fra 1. meta.has_more sier om De skal be om en til.

Eksempel

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}

Én artikkel, med alt listen utelater: content_markdown, content_html, FAQ-en som schema.org JSON-LD klar til å settes inn på siden, og eventuelle utvekslingslenker artikkelen inneholder.

Feltnavnene er med vilje de samme som webhooken vår sender. Hvis De allerede har en webhook-mottaker, leser den samme parseren dette.

Eksempel

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

De publiserer artikkelen; her forteller De oss adressen. Det er det ene endepunktet som endrer noe.

Det gjør nøyaktig det samme som en levering vi gjorde selv: artikkelen markeres som publisert, den månedlige kvoten Deres teller den, planpunktet lukkes, eventuelle utvekslingslenker i den får adressen verifiseringen har ventet på, og Facebook-siden Deres får beskjed hvis De har koblet til en. Uten dette kallet forblir artikkelen klar for alltid, og ingenting av dette skjer.

Eksempel

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

Svar

200 Registrert. Artikkelen kommer tilbake med ny status, published_at og published_url.
422 URL-en mangler eller er ikke en fullstendig http://- eller https://-adresse.
409 Artikkelen er ikke klar til å publiseres, eller er allerede registrert som publisert. Artikkelen kommer tilbake med avslaget, slik at De kan se hva som gjelder.

Koble til "REST API" som publiseringsmotor.

Under Settings, deretter Publishing, finnes det en motor som heter "REST API: you fetch and publish". Den ber ikke om noe, fordi det ikke er noe for oss å sende. Det den endrer, er hva som skjer hver morgen: en ferdig artikkel forblir klar uten adresse, og publiseringsskjermen sier at den venter på at De skal hente den, i stedet for å vise en levering som mislyktes.

De kan bruke API-et uten å koble det til: endepunktene fungerer for enhver konto med en nøkkel. Å koble det til er hvordan resten av produktet vet at det skal slutte å forvente en egen adresse, og det er det som hindrer at en artikkel De publiserer selv blir regnet som en feil.

Alle feil er JSON med en melding.

Samme form hele veien, enten avvisningen kom fra nøkkelkontrollen eller fra validatoren, så ingenting trenger å tolke to.

{ "message": "That API key is not valid, or it has been revoked." }
Status Hva det betyr
401 Ingen nøkkel, en nøkkel som ikke er vår, eller en nøkkel som er tilbakekalt.
404 Ingen slik artikkel eller nettsted på denne kontoen. En annen kontos artikkel svarer 404 i stedet for 403: et API som sier "det er ikke Deres" har bekreftet at tingen finnes.
409 Forespørselen var i orden, men artikkelen er ikke i en tilstand for det.
422 En parameter mangler eller er feil. Svaret inneholder et errors-objekt som oppgir feltet, i tillegg til meldingen.
429 Over grensen for antall forespørsler. Retry-After sier hvor lenge De må vente.

Hva et byggesteg faktisk gjør.

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

Opprett en nøkkel og prøv den.

Prøveperioden er nok til å lese API-et: artiklene som skrives i løpet av den, er ekte artikler, og de kommer tilbake gjennom disse endepunktene som alle andre.

Start kostnadsfri prøveperiode