Iniciar sessão Iniciar teste gratuito

Obtenha os seus artigos.
Publique-os à sua maneira.

Todos os artigos que escrevemos para si podem ser lidos por HTTP: o título, os metadados, o Markdown, o HTML, a imagem principal e as FAQ. Leve-os para o seu site Next.js, Astro ou personalizado quando a sua build correr, publique-os e diga-nos o endereço em que cada um ficou.

Um bearer token. JSON entra, JSON sai. Nenhum SDK para instalar e nada para configurar além de uma chave.

O webhook envia. A API permite-lhe ir buscar.

Transportam o mesmo artigo no mesmo formato, por isso um analisador escrito para um lê o outro sem alterações. A diferença está em quem inicia a conversa.

O webhook, quando o seu site pode aceitar uma publicação a qualquer hora

Chamamos o seu endpoint no momento em que um artigo fica pronto, e novamente quando muda. Nada para consultar, nada para agendar. WordPress, Shopify, Ghost, um acionador do Zapier, ou uma rota escrita por si.

A API, quando o seu site é construído e implementado como uma unidade

Um site estático não pode aceitar uma publicação às seis e meia da manhã; primeiro tem de haver uma nova build. Por isso, a sua build pergunta o que está à espera, obtém isso e depois diz-nos o endereço. Escolhe quando.

Ambos, se quiser

São ligações separadas e nenhuma exclui a outra. Um webhook que alimenta uma newsletter e uma API que alimenta o website é uma configuração normal.

Uma chave, enviada como bearer token.

Crie uma chave no painel em Definições, depois Ligações. É mostrada uma vez, quando é criada, porque só o hash é guardado: se a perder, revogue-a e crie outra. Uma chave lê todos os sites da conta e é revogada no mesmo ecrã.

Todos os pedidos

Authorization: Bearer sns_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept: application/json

Verifique se funciona

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
}

Limite de pedidos

120 pedidos por minuto, contados em relação à chave e não ao endereço de onde vêm, porque os executores de build partilham endereços. Acima disso recebe 429 com os cabeçalhos padrão Retry-After e X-RateLimit. Obter artigos para uma build são apenas alguns pedidos, por isso não é um limite que deva atingir por acidente.

Mantenha a chave fora do seu repositório

Lê tudo o que escrevemos para a sua conta, incluindo artigos que ainda não estão publicados. Coloque-a no seu ambiente de build, não no seu código-fonte. Revogue-a aqui no momento em que estiver onde não deve estar, e tudo o que a usar recebe um 401 imediatamente.

Cinco deles, e quatro são só de leitura.

Tudo fica em /api/v1/. A versão está no caminho desde o primeiro dia, para que um dia possa existir uma v2 sem quebrar o que escreve hoje.

GET /api/v1/me

A conta a que a chave pertence, e o nome e prefixo da própria chave. Útil sobretudo para uma coisa: dizer-lhe que a chave neste ambiente é a chave que pensa que é.

Exemplo

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

Todos os sites da conta. O id é o que a lista de artigos usa para filtrar, e o domínio está lá para que um script de build possa corresponder a algo que já conhece em vez de transportar um id.

Exemplo

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

Uma página de artigos, com a alteração mais recente primeiro, sem o texto. Ordenada pela última alteração de cada artigo e não pela data em que foi escrito, o que torna updated_since útil: um artigo que já está publicado pode ser editado mais tarde, quando uma ligação é inserida nele ou removida.

Parâmetros de consulta

Nome O que faz
site_id Um site, de /sites. Um id que não está na sua conta responde 404.
status Um de draft, qa, needs_repair, review, ready, published, failed. Qualquer outra coisa dá 422 em vez de uma página vazia. "ready" é o que uma build quer: escrito, verificado e ainda não publicado em lado nenhum.
updated_since ISO 8601, como 2026-09-06T00:00:00Z. Guarde o timestamp da sua última execução e volte a passá-lo na seguinte.
per_page Até 100. O valor predefinido é 25.
page A partir de 1. meta.has_more indica se deve pedir outra.

Exemplo

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}

Um artigo, com tudo o que a lista deixa de fora: content_markdown, content_html, as FAQ como schema.org JSON-LD prontas a inserir na página, e quaisquer ligações de troca que o artigo tenha.

Os nomes dos campos são os que o nosso webhook envia, de propósito. Se já tiver um recetor de webhook, o mesmo analisador lê isto.

Exemplo

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 o artigo; é aqui que nos indica o endereço. É o único endpoint que altera alguma coisa.

Faz exatamente o mesmo que uma entrega feita por nós: o artigo fica marcado como publicado, conta para o seu limite mensal, o item do plano é fechado, quaisquer ligações de troca nele recebem o endereço que o verificador estava à espera, e a sua Página do Facebook é informada se tiver ligado uma. Sem esta chamada o artigo fica pronto para sempre e nada disso acontece.

Exemplo

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

Respostas

200 Registado. O artigo volta com o novo estado, published_at e published_url.
422 Falta o url ou não é um endereço http:// ou https:// completo.
409 O artigo não está pronto para ser publicado, ou já está registado como publicado. O artigo volta com a recusa, para que possa ver qual é o caso.

Ligue a "REST API" como motor de publicação.

Em Settings, depois em Publishing, existe um motor chamado "REST API: you fetch and publish". Não pede nada, porque não há nada para enviarmos. O que muda é o que acontece todas as manhãs: um artigo concluído fica pronto sem endereço, e o ecrã de publicação diz que está à espera que o vá buscar, em vez de mostrar uma entrega falhada.

Pode usar a API sem a ligar: os endpoints funcionam para qualquer conta com uma chave. Ligá-la é a forma de o resto do produto saber que deve deixar de esperar um endereço próprio, e é isso que impede que um artigo publicado por si seja contado como falha.

Todas as falhas são JSON com uma mensagem.

Uma única forma em todo o lado, quer a recusa venha da verificação da chave quer do validador, para que nada tenha de interpretar duas.

{ "message": "That API key is not valid, or it has been revoked." }
Estado O que significa
401 Sem chave, uma chave que não é nossa, ou uma chave que foi revogada.
404 Não existe esse artigo ou site nesta conta. Um artigo de outra conta responde 404 em vez de 403: uma API que diz "isso não é seu" confirmou que a coisa existe.
409 O pedido estava correto, mas o artigo não está num estado que o permita.
422 Falta um parâmetro ou está incorreto. A resposta inclui um objeto errors com o nome do campo, bem como a mensagem.
429 Acima do limite de pedidos. Retry-After indica quanto tempo deve esperar.

O que um passo de build faz realmente.

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

Crie uma chave e experimente.

O período experimental é suficiente para ler a API: os artigos escritos durante esse período são artigos reais, e regressam através destes endpoints como quaisquer outros.

Iniciar teste gratuito