Log ind Start gratis prøveperiode

Hent Deres artikler.
Udgiv dem på Deres måde.

Hver artikel, vi skriver til Dem, kan læses over HTTP: titlen, metadataene, Markdown, HTML, hero-billedet og FAQ'en. Tag dem ind i Deres Next.js-, Astro- eller specialbyggede website, når Deres build kører, udgiv dem, og fortæl os den adresse, hver enkelt endte på.

Ét bearer-token. JSON ind, JSON ud. Intet SDK at installere og intet at konfigurere ud over en nøgle.

Webhooken sender. API'et lader Dem hente.

De bærer den samme artikel i samme form, så en parser skrevet til den ene læser den anden uændret. Forskellen er, hvem der starter samtalen.

Webhooken, når Deres website kan modtage et indlæg når som helst

Vi kalder Deres endpoint i det øjeblik, en artikel er klar, og igen når den ændrer sig. Intet at polle, intet at planlægge. WordPress, Shopify, Ghost, en Zapier-trigger eller en rute, De selv har skrevet.

API'et, når Deres website bygges og udrulles som en enhed

Et statisk website kan ikke modtage et indlæg klokken halv syv om morgenen, noget skal først genopbygges. Så Deres build spørger, hvad der venter, henter det og fortæller os adressen bagefter. De vælger selv hvornår.

Begge, hvis De vil have dem

De er separate forbindelser, og ingen af dem udelukker den anden. En webhook, der leverer til et nyhedsbrev, og et API, der leverer til websitet, er en normal opsætning.

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

Opret en nøgle i kontrolpanelet under Settings og derefter Connections. Den vises én gang, når den oprettes, fordi kun dens hash gemmes: hvis De mister den, skal De tilbagekalde den og oprette en ny. En nøgle læser alle websites på kontoen og tilbagekaldes fra samme skærm.

Hver anmodning

Authorization: Bearer sns_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept: application/json

Kontrollér, 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
}

Hastighedsgrænse

120 anmodninger i minuttet, talt på nøglen frem for den adresse, den kommer fra, fordi build-runners deler adresser. Over det får De 429 med standardoverskrifterne Retry-After og X-RateLimit. At hente artikler til et build er en håndfuld anmodninger, så det er ikke en grænse, De burde ramme ved et uheld.

Hold nøglen ude af Deres repository

Den læser alt, vi har skrevet til Deres konto, også artikler, der endnu ikke er udgivet. Læg den i Deres build-miljø, ikke i Deres kildekode. Tilbagekald den her, så snart den er et sted, den ikke burde være, og alt, der bruger den, får straks en 401.

Fem af dem, og fire læser kun.

Alt ligger under /api/v1/. Versionen er i stien fra første dag, så en v2 en dag kan findes uden at ødelægge det, De skriver i dag.

GET /api/v1/me

Den konto, nøglen tilhører, og nøglens eget navn og præfiks. Frem for alt nyttigt til at fortælle Dem, at nøglen i dette miljø er den nøgle, De tror, det er.

Eksempel

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

Alle websites på kontoen. id er det, artikellisten filtrerer på, og domænet er der, så et build-script kan matche på noget, det allerede kender, frem for at bære rundt på et 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 ændring først, uden selve teksten. Sorteret efter hvornår hver artikel sidst blev ændret frem for hvornår den blev skrevet, hvilket er det, der gør updated_since nyttig: en artikel, der allerede er udgivet, kan redigeres senere, når et link indsættes i den eller fjernes igen.

Forespørgselsparametre

Navn Hvad det gør
site_id Ét website fra /sites. Et id, der ikke er på Deres konto, svarer med 404.
status En af draft, qa, needs_repair, review, ready, published, failed. Alt andet giver 422 frem for en tom side. "ready" er det, et build vil have: skrevet, kontrolleret og endnu ikke nogen steder.
updated_since ISO 8601, såsom 2026-09-06T00:00:00Z. Husk tidsstemplet fra Deres sidste kørsel, og send det med tilbage ved den næste.
per_page Op til 100. Standardværdien er 25.
page Fra 1. meta.has_more angiver, om De skal bede 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 artikel med alt det, listen udelader: content_markdown, content_html, FAQ'en som schema.org JSON-LD klar til at indsætte på siden og eventuelle udvekslingslinks, artiklen indeholder.

Feltnavnene er med vilje dem, vores webhook sender. Hvis De allerede har en webhook-modtager, kan den samme parser læse 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 gør artiklen live, og her fortæller De os adressen. Det er det ene endpoint, der ændrer noget.

Det gør præcis det samme som en levering, vi selv har foretaget: artiklen markeres som udgivet, Deres månedlige kvote tæller den med, planpunktet lukkes, eventuelle udvekslingslinks i den får den adresse, verifikatoren har ventet på, og Deres Facebook Page får besked, hvis De har forbundet en. Uden dette kald forbliver artiklen klar for evigt, og intet af det sker.

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 Registreret. Artiklen kommer tilbage med sin nye status, published_at og published_url.
422 Url'en mangler eller er ikke en fuld http://- eller https://-adresse.
409 Artiklen er ikke klar til at blive udgivet eller er allerede registreret som udgivet. Artiklen returneres med afvisningen, så De kan se hvilken.

Forbind "REST API" som Deres publiceringsmotor.

Under Settings og derefter Publishing er der en motor kaldet "REST API: De henter og udgiver". Den beder ikke om noget, fordi der ikke er noget for os at sende. Det, den ændrer, er, hvad der sker hver morgen: En færdig artikel forbliver klar uden adresse, og udgivelsesskærmen siger, at den venter på, at De henter den, i stedet for at vise en levering, der mislykkedes.

De kan bruge API'et uden at forbinde det: endpoints virker for enhver konto med en nøgle. At forbinde det er sådan, resten af produktet ved, at det skal holde op med at forvente en egen adresse, og det er det, der forhindrer, at en artikel, De selv udgiver, bliver talt som en fejl.

Alle fejl er JSON med en besked.

Én form hele vejen igennem, uanset om afvisningen kom fra nøglekontrollen eller fra validatoren, så intet behøver at parse to.

{ "message": "That API key is not valid, or it has been revoked." }
Status Hvad det betyder
401 Ingen nøgle, en nøgle der ikke er vores, eller en nøgle der er blevet tilbagekaldt.
404 Ingen sådan artikel eller intet sådant website på denne konto. En anden kontos artikel svarer med 404 frem for 403: et API, der siger "det er ikke Deres", har bekræftet, at tingen findes.
409 Anmodningen var i orden, men artiklen er ikke i en tilstand til det.
422 En parameter mangler eller er forkert. Svaret indeholder et errors-objekt med feltnavnet samt beskeden.
429 Over hastighedsgrænsen. Retry-After angiver, hvor længe De skal vente.

Hvad et build-trin faktisk gø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

Opret en nøgle og prøv den.

Prøveperioden er nok til at bruge API'et: de artikler, der skrives i den, er rigtige artikler, og de kommer tilbage gennem disse endpoints som alle andre.

Start gratis prøveperiode