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
POSTpara criar novos conteúdos. - Permitir atualizar artigos / categorias: permite pedidos
PUTpara 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.
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.
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:
| Campo | Tipo | Descrição |
|---|---|---|
languages | objeto | Conteúdo por idioma, indexado pelo ID de idioma do PrestaShop. Obrigatório na criação |
languages.{id}.title | texto | Título do artigo. Obrigatório para cada idioma |
languages.{id}.introduction | HTML | Texto curto apresentado nas listas e no topo do artigo |
languages.{id}.content | HTML | Corpo do artigo |
languages.{id}.meta_title | texto | Tag title SEO (máx. 500 caracteres) |
languages.{id}.meta_description | texto | Meta description (máx. 500 caracteres) |
languages.{id}.meta_keywords | texto | Palavras-chave SEO |
languages.{id}.link_rewrite | texto | Slug de URL. Gerado automaticamente a partir do título se estiver em falta |
categories | lista de IDs | Categorias PrestaBlog a associar |
products | lista de IDs | Produtos PrestaShop associados |
related_articles | lista de IDs | Artigos relacionados |
active | booleano | Publicação imediata. Se ausente, usa o parâmetro “Ativar automaticamente” |
date | data/hora | Data de publicação em YYYY-MM-DD HH:MM:SS. Uma data futura agenda a publicação |
enable_toc | booleano | Ativa o sumário gerado a partir das tags h2/h3 do conteúdo |
author_id | inteiro | ID do autor PrestaBlog |
image.url | URL | Imagem principal para descarregar a partir de um URL remoto |
id_shop | inteiro | ID 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:
| Campo | Tipo | Descrição |
|---|---|---|
languages | objeto | Conteúdo por idioma. Obrigatório na criação |
languages.{id}.title | texto | Título da categoria. Obrigatório para cada idioma |
languages.{id}.description | HTML | Descrição da categoria |
languages.{id}.meta_title | texto | Tag title SEO (máx. 500 caracteres) |
languages.{id}.meta_description | texto | Meta description (máx. 500 caracteres) |
languages.{id}.meta_keywords | texto | Palavras-chave SEO |
languages.{id}.link_rewrite | texto | Slug de URL. Gerado automaticamente a partir do título se estiver em falta |
parent | inteiro | ID da categoria pai. 0 = raiz |
position | inteiro | Ordem de apresentação |
active | booleano | Categoria visível no front |
image.url | URL | Imagem 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.
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 autoresGET /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ódigo | HTTP | Significado |
|---|---|---|
unauthorized | 401 | Chave de API em falta ou inválida |
api_disabled | 503 | API desativada na configuração |
https_required | 426 | O pedido deve ser feito via HTTPS |
rate_limited | 429 | Limite de pedidos excedido, ou IP bloqueado após autenticação falhada |
invalid_json | 400 | Corpo JSON inválido ou em falta |
validation_error | 422 | Valor de campo inválido (detalhes em error.details) |
conflict | 409 | Conflito de slug: já existe um artigo ou categoria com este link |
not_found | 404 | Recurso não encontrado |
method_not_allowed | 405 | Método HTTP não suportado para este endpoint |
payload_too_large | 413 | Corpo do pedido demasiado grande (limite: 10 MB) |
internal_error | 500 | Erro 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())