API

O PrestaBlog disponibiliza uma API REST que permite a ferramentas externas - scripts, software de terceiros, ou agentes de IA - criar e gerir artigos e categorias do blog sem utilizar o back-office. Esta funcionalidade, disponível a partir do PrestaShop 8, destina-se tanto a não programadores através de um agente de IA, como a programadores que pretendem uma integração direta.

Configuração da API

Antes de mais, a API deve ser ativada e configurada no back-office.

Aceder à configuração:
Módulos > PrestaBlog > Configuração > Ferramentas > API

Parâmetros disponíveis:

  • Ativar API: interruptor principal. A API não responde a qualquer pedido enquanto estiver desativada.
  • Chave da API: clique em “Gerar uma nova chave”. A chave é apresentada apenas uma vez - copie-a de imediato, pois não voltará a estar acessível. Apenas a sua impressão digital criptográfica (SHA-256) é guardada. Se perder a chave, gere uma nova.
  • Ativar automaticamente novos artigos: decide se os artigos criados via API são publicados imediatamente ou guardados como rascunhos quando o pedido não fornece explicitamente este parâmetro.
  • Limite de pedidos: número máximo de pedidos por minuto e por endereço IP (predefinição: 60).
  • Segurança de imagens: bloqueia downloads de imagens a partir de intervalos de IP privados/internos. Recomendado para instalações expostas à Internet.
  • Atrás de um proxy: ative se a sua loja estiver atrás de Cloudflare, de um reverse proxy ou de um CDN, para tratar corretamente o IP do cliente.
  • Nível de log: Nenhum desativa os logs. Segurança regista tentativas de autenticação falhadas e bloqueios. Debug regista todos os pedidos (usar temporariamente para diagnóstico).
  • Origens CORS permitidas: apenas se uma aplicação web alojada noutro domínio tiver de chamar a API a partir de um browser. Deixe vazio na maioria dos casos.

Permissões da API

A secção Permissões da API permite restringir com precisão o que a chave da API pode fazer. Cada operação pode ser ativada ou desativada de forma independente, tanto para artigos como para categorias.

  • Permitir criar artigos / categorias: permite pedidos POST para criar novos conteúdos.
  • Permitir atualizar artigos / categorias: permite pedidos PUT para atualizar conteúdos existentes.
  • Permitir eliminar artigos / categorias: permite pedidos DELETE. Desative se quiser evitar eliminações acidentais por um agente de IA ou um script de terceiros.
Boa prática Conceda apenas as permissões estritamente necessárias. Se usar a API apenas para publicar artigos, desative a atualização e a eliminação para reduzir o risco caso a chave seja comprometida.
Segurança

A API requer HTTPS. Em HTTP, todos os pedidos são rejeitados (exceto a partir de localhost para testes de desenvolvimento local). Nunca partilhe a sua chave de API.

Utilização via um agente de IA (recomendado)

Não é programador, ou não quer escrever código? O método mais simples é usar um agente de IA como o Claude através do protocolo MCP (Model Context Protocol). O agente sabe exatamente que chamadas fazer, trata da autenticação e compreende as suas instruções em linguagem natural.

Nota: Claude e Windsurf são exemplos de integrações MCP. Existem muitas outras ferramentas e ambientes compatíveis, mas não é possível analisá-los todos aqui.

1. Ativar a API e gerar a sua chave

No back-office do PrestaBlog: Ferramentas > API. Ative a API, clique em “Gerar uma nova chave” e copie a chave apresentada - não voltará a estar acessível.

2. Construir o seu URL de ligação MCP

O URL de ligação segue este formato:

https://prestablog-mcp.prestablog.workers.dev/mcp?key=YOUR_KEY&shop=https://your-shop.com

Substitua YOUR_KEY pela chave que gerou e https://your-shop.com pelo URL da sua loja.

Não confunda isto com o “URL da API”, que é um URL diferente usado para chamadas diretas.

Importante

O URL contém a sua chave de API. Trate-a como uma palavra-passe: não a partilhe nem a publique.

3. Configurar com o Claude

No Claude, clique em Customize no canto superior esquerdo e depois em Connectors,
no topo da coluna que aparece clique no botão + e depois em Add a custom connector.

Preencha:

  • Name: o que preferir (por exemplo, PrestaBlog API)
  • URL: o URL de ligação MCP que construiu no passo 2

Confirme. O Claude pode agora aceder ao seu blog e pode criar, editar e eliminar artigos e categorias diretamente.

Exemplos do que pode pedir ao Claude:

  • “Cria um artigo sobre sapatos de verão na categoria Moda”
  • “Lista os 10 artigos publicados mais recentes”
  • “Altera o título do artigo 42”
  • “Cria uma nova categoria chamada Notícias com esta descrição”
  • “Elimina a categoria 5”

Documentação integrada

A documentação completa está integrada no conector MCP. O Claude lê-a automaticamente; não há mais nada a configurar.

4. Configurar com o Windsurf

No Windsurf, abra o painel Cascade, clique em ... no canto superior direito do painel e depois clique no ícone MCPs (o último ícone no canto inferior direito do menu). Abre-se uma janela de edição. Adicione a seguinte configuração depois de gerar corretamente o URL (ver passo 2):

{
  "mcpServers": {
    "prestablog": {
      "serverUrl": "https://prestablog-mcp.prestablog.workers.dev/mcp?key=YOUR_KEY&shop=https://your-shop.com"
    }
  }
}

Guarde. O Cascade mostra 1 MCP na parte inferior do painel, confirmando que a ligação está ativa.

Exemplos do que pode pedir ao Cascade:

  • “Cria um artigo sobre sapatos de verão na categoria Moda”
  • “Lista os 10 artigos publicados mais recentes”
  • “Altera o título do artigo 42”
  • “Cria uma nova categoria chamada Notícias com esta descrição”
  • “Elimina a categoria 5”

Documentação integrada

A documentação completa está integrada no conector MCP. O Cascade lê-a automaticamente; não há mais nada a configurar.

Autenticação (REST)

Cada pedido deve incluir a chave de API num cabeçalho HTTP. São suportados dois formatos:

Authorization: Bearer YOUR_API_KEY

ou

X-Api-Key: YOUR_API_KEY

Boa prática

A chave nunca deve ser enviada como parâmetro de URL, para evitar que apareça nos logs do servidor.

Bloqueio automático: após 5 tentativas de autenticação falhadas a partir do mesmo IP, este é bloqueado durante 1 hora. Este atraso é configurável nos parâmetros da API.

Artigos

Listar artigos

GET /prestablog-api/articles

Devolve a lista paginada de artigos. Parâmetros disponíveis: lang (ID do idioma), page, per_page (máx. 100), active (1 = apenas publicados), category (ID da categoria), search (pesquisa no título), sort (date, title, id), order (asc, desc).

curl -X GET "https://your-shop.com/prestablog-api/articles?lang=1&page=1&per_page=10" \
  -H "Authorization: Bearer YOUR_KEY"

Detalhes do artigo

GET /prestablog-api/articles/{id}

Devolve todos os dados de um artigo: campos multilingues, categorias, produtos associados, artigos relacionados, sumário.

curl -X GET "https://your-shop.com/prestablog-api/articles/18" \
  -H "Authorization: Bearer YOUR_KEY"

Criar um artigo

POST /prestablog-api/articles

Exemplo mínimo:

curl -X POST "https://your-shop.com/prestablog-api/articles" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "languages": {
      "1": {
        "title": "O meu artigo",
        "content": "<h2>Introdução</h2><p>Conteúdo do artigo.</p>"
      }
    },
    "categories": [1],
    "active": true
  }'

Exemplo completo com imagem, multilingue e metadados:

{
  "languages": {
    "1": {
      "title": "O meu artigo",
      "introduction": "Texto curto apresentado nas listas",
      "content": "<h2>Secção</h2><p>Conteúdo HTML completo.</p>",
      "meta_title": "O meu artigo - Título SEO",
      "meta_description": "Descrição para motores de pesquisa",
      "meta_keywords": "palavra1, palavra2",
      "link_rewrite": "my-article"
    },
    "2": {
      "title": "O meu artigo",
      "introduction": "Texto curto apresentado nas listas",
      "content": "<h2>Secção</h2><p>Conteúdo HTML completo.</p>"
    }
  },
  "categories": [2, 5],
  "active": true,
  "date": "2026-06-15 09:00:00",
  "enable_toc": true,
  "author_id": 1,
  "image": {
    "url": "https://example.com/image.jpg"
  }
}

Campos disponíveis:

CampoTipoDescrição
languagesobjetoConteúdo por idioma, indexado pelo ID de idioma do PrestaShop. Obrigatório na criação
languages.{id}.titletextoTítulo do artigo. Obrigatório para cada idioma
languages.{id}.introductionHTMLTexto curto apresentado nas listas e no topo do artigo
languages.{id}.contentHTMLCorpo do artigo
languages.{id}.meta_titletextoTag title SEO (máx. 500 caracteres)
languages.{id}.meta_descriptiontextoMeta description (máx. 500 caracteres)
languages.{id}.meta_keywordstextoPalavras-chave SEO
languages.{id}.link_rewritetextoSlug de URL. Gerado automaticamente a partir do título se estiver em falta
categorieslista de IDsCategorias PrestaBlog a associar
productslista de IDsProdutos PrestaShop associados
related_articleslista de IDsArtigos relacionados
activebooleanoPublicação imediata. Se ausente, usa o parâmetro “Ativar automaticamente”
datedata/horaData de publicação em YYYY-MM-DD HH:MM:SS. Uma data futura agenda a publicação
enable_tocbooleanoAtiva o sumário gerado a partir das tags h2/h3 do conteúdo
author_idinteiroID do autor PrestaBlog
image.urlURLImagem principal para descarregar a partir de um URL remoto
id_shopinteiroID da loja (apenas multiloja). Predefinição: loja atual

Atualizar um artigo

PUT /prestablog-api/articles/{id}

Atualização parcial: apenas os campos presentes no pedido são atualizados. Campos não fornecidos mantêm o seu valor atual. Para idiomas, apenas os incluídos no payload são atualizados.

curl -X PUT "https://your-shop.com/prestablog-api/articles/18" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "active": false,
    "languages": {
      "1": {
        "title": "Novo título"
      }
    }
  }'

Eliminar um artigo

DELETE /prestablog-api/articles/{id}

Elimina o artigo e todos os dados associados: imagens (todas as variantes), categorias, produtos associados e artigos relacionados.

curl -X DELETE "https://your-shop.com/prestablog-api/articles/18" \
  -H "Authorization: Bearer YOUR_KEY"

Imagem do artigo

POST /prestablog-api/articles/{id}/image

Estão disponíveis três métodos consoante o seu contexto:

URL remoto (imagem alojada online):

curl -X POST "https://your-shop.com/prestablog-api/articles/18/image" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/image.jpg"}'

Ficheiro local (upload multipart):

curl -X POST "https://your-shop.com/prestablog-api/articles/18/image" \
  -H "Authorization: Bearer YOUR_KEY" \
  -F "file=@/path/to/image.jpg"

Base64 (alternativa):

Nota: base64 é muito volumoso e pode tornar-se difícil de gerir para imagens complexas. Quando possível, prefira o upload via URL remoto.

curl -X POST "https://your-shop.com/prestablog-api/articles/18/image" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"base64": "/9j/4AAQSkZJRg...", "filename": "photo.jpg"}'

Via MCP (Claude)

Apenas os métodos URL e base64 estão disponíveis via MCP. Para enviar um ficheiro local via Claude, codifique-o primeiro em base64.

Categorias

A API permite criar, consultar, atualizar e eliminar categorias, tal como para os artigos.

Listar categorias

GET /prestablog-api/categories

Devolve as categorias sob a forma de árvore por predefinição. Use flat=1 para uma lista plana, active=1 para apenas as ativas, lang para o idioma.

curl -X GET "https://your-shop.com/prestablog-api/categories?lang=1" \
  -H "Authorization: Bearer YOUR_KEY"

Detalhes da categoria

GET /prestablog-api/categories/{id}

Devolve todos os dados da categoria: campos multilingues, número de artigos e grupos de clientes associados.

Criar uma categoria

POST /prestablog-api/categories

Exemplo mínimo:

curl -X POST "https://your-shop.com/prestablog-api/categories" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "languages": {
      "1": {
        "title": "Notícias"
      }
    },
    "active": true
  }'

Exemplo completo:

{
  "languages": {
    "1": {
      "title": "Notícias",
      "description": "<p>Todas as notícias da nossa loja.</p>",
      "meta_title": "Notícias - Título SEO",
      "meta_description": "Descrição SEO da categoria",
      "meta_keywords": "notícias",
      "link_rewrite": "news"
    },
    "2": {
      "title": "Notícias",
      "description": "<p>Todas as notícias mais recentes da nossa loja.</p>",
      "link_rewrite": "news"
    }
  },
  "parent": 0,
  "position": 1,
  "active": true,
  "image": {
    "url": "https://example.com/category.jpg"
  }
}

Campos disponíveis:

CampoTipoDescrição
languagesobjetoConteúdo por idioma. Obrigatório na criação
languages.{id}.titletextoTítulo da categoria. Obrigatório para cada idioma
languages.{id}.descriptionHTMLDescrição da categoria
languages.{id}.meta_titletextoTag title SEO (máx. 500 caracteres)
languages.{id}.meta_descriptiontextoMeta description (máx. 500 caracteres)
languages.{id}.meta_keywordstextoPalavras-chave SEO
languages.{id}.link_rewritetextoSlug de URL. Gerado automaticamente a partir do título se estiver em falta
parentinteiroID da categoria pai. 0 = raiz
positioninteiroOrdem de apresentação
activebooleanoCategoria visível no front
image.urlURLImagem da categoria para descarregar a partir de um URL remoto

Atualizar uma categoria

PUT /prestablog-api/categories/{id}

Atualização parcial: apenas os campos presentes no pedido são atualizados.

curl -X PUT "https://your-shop.com/prestablog-api/categories/1" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "languages": {
      "1": {
        "title": "Novo nome da categoria",
        "description": "<p>Nova descrição.</p>"
      }
    }
  }'

Eliminar uma categoria

DELETE /prestablog-api/categories/{id}

Elimina a categoria e todos os dados associados: imagem, ligações com artigos e grupos de clientes.

Aviso

Os artigos associados a esta categoria não são eliminados, mas perdem a ligação a esta categoria.

curl -X DELETE "https://your-shop.com/prestablog-api/categories/1" \
  -H "Authorization: Bearer YOUR_KEY"

Imagem da categoria

POST /prestablog-api/categories/{id}/image

Os mesmos três métodos que para artigos: URL remoto, ficheiro local (multipart) ou base64.

Nota: base64 é muito volumoso e pode tornar-se difícil de gerir para imagens complexas. Quando possível, prefira o upload via URL remoto.

curl -X POST "https://your-shop.com/prestablog-api/categories/1/image" \
  -H "Authorization: Bearer YOUR_KEY" \
  -F "file=@/path/to/category.jpg"

Autores

Os autores são apenas leitura via API. Devem ser criados no back-office do PrestaBlog.

  • GET /prestablog-api/authors - listar todos os autores
  • GET /prestablog-api/authors/{id} - detalhes do autor com biografias multilingues
curl -X GET "https://your-shop.com/prestablog-api/authors?lang=1" \
  -H "Authorization: Bearer YOUR_KEY"

Códigos de erro

Todas as respostas de erro seguem este formato:

{
  "success": false,
  "error": {
    "code": "validation_error",
    "message": "Mensagem de erro legível",
    "details": { "campo": "languages.1.title" }
  }
}
CódigoHTTPSignificado
unauthorized401Chave de API em falta ou inválida
api_disabled503API desativada na configuração
https_required426O pedido deve ser feito via HTTPS
rate_limited429Limite de pedidos excedido, ou IP bloqueado após autenticação falhada
invalid_json400Corpo JSON inválido ou em falta
validation_error422Valor de campo inválido (detalhes em error.details)
conflict409Conflito de slug: já existe um artigo ou categoria com este link
not_found404Recurso não encontrado
method_not_allowed405Método HTTP não suportado para este endpoint
payload_too_large413Corpo do pedido demasiado grande (limite: 10 MB)
internal_error500Erro interno do servidor

Limite de pedidos: quando excedido, a resposta 429 inclui o cabeçalho Retry-After indicando quantos segundos deve esperar antes de tentar novamente. Cada resposta inclui também os cabeçalhos X-RateLimit-Limit e X-RateLimit-Remaining.

Integração com Python

Para programadores Python, a biblioteca requests torna simples interagir com a API em apenas algumas linhas.

pip install requests
import requests

BASE = "https://your-shop.com/prestablog-api"
KEY = "YOUR_KEY"
headers = {"Authorization": f"Bearer {KEY}"}

# Listar artigos
r = requests.get(f"{BASE}/articles", headers=headers, params={"lang": 1, "per_page": 10})
print(r.json())

# Criar um artigo
r = requests.post(f"{BASE}/articles", headers=headers, json={
    "languages": {"1": {"title": "O meu artigo", "content": "<p>Conteúdo</p>"}},
    "categories": [1],
    "active": True
})
print(r.json())

# Enviar uma imagem a partir de um ficheiro local
with open("image.jpg", "rb") as f:
    r = requests.post(f"{BASE}/articles/18/image", headers=headers, files={"file": f})
print(r.json())