API

PrestaBlog oferă un API REST care permite unor instrumente externe - scripturi, software terț sau agenți IA - să creeze și să gestioneze articole și categorii de blog fără a trece prin back-office. Această funcționalitate, disponibilă începând cu PrestaShop 8, se adresează atât utilizatorilor non-dezvoltatori printr-un agent IA, cât și dezvoltatorilor care doresc o integrare directă.

Configurarea API-ului

Înainte de orice, API-ul trebuie activat și configurat în back-office.

Accesează configurarea:
Module > PrestaBlog > Configurare > Instrumente > API

Setări disponibile:

  • Activează API-ul: comutator principal. API-ul nu va răspunde la nicio cerere cât timp este dezactivat.
  • Cheie API: apasă „Generate a new key”. Cheia este afișată o singură dată - copiaz-o imediat, nu va mai fi accesibilă ulterior. Se stochează doar amprenta ei criptografică (SHA-256). Dacă pierzi cheia, generează una nouă.
  • Activează automat articolele noi: stabilește dacă articolele create prin API sunt publicate imediat sau salvate ca ciorne atunci când cererea nu precizează explicit acest parametru.
  • Limită de cereri: numărul maxim de cereri pe minut pentru fiecare adresă IP (implicit: 60).
  • Securitate imagini: blochează descărcarea imaginilor din intervale IP private/interne. Recomandat pentru instalările expuse pe Internet.
  • În spatele unui proxy: activează dacă magazinul tău este în spatele Cloudflare, a unui reverse proxy sau a unui CDN, pentru a gestiona corect IP-ul clientului.
  • Nivel de log: None dezactivează logurile. Security înregistrează încercările de autentificare eșuate și blocările. Debug înregistrează toate cererile (folosește temporar pentru diagnostic).
  • Origini CORS permise: doar dacă o aplicație web găzduită pe alt domeniu trebuie să apeleze API-ul din browser. Lasă gol în majoritatea cazurilor.

Permisiuni API

Secțiunea Permisiuni API îți permite să restricționezi cu precizie ce are voie să facă cheia API. Fiecare operațiune poate fi activată sau dezactivată independent, atât pentru articole, cât și pentru categorii.

  • Permite crearea de articole / categorii: permite cereri POST pentru a crea conținut nou.
  • Permite modificarea articolelor / categoriilor: permite cereri PUT pentru a actualiza conținut existent.
  • Permite ștergerea articolelor / categoriilor: permite cereri DELETE. Dezactivează dacă vrei să previi ștergerile accidentale din partea unui agent IA sau a unui script terț.
Bună practică Acordă doar permisiunile strict necesare. Dacă folosești API-ul doar pentru publicarea articolelor, dezactivează modificarea și ștergerea pentru a reduce riscul în caz de compromitere a cheii.
Securitate

API-ul necesită HTTPS. Prin HTTP, toate cererile sunt respinse (cu excepția celor din localhost pentru teste locale de dezvoltare). Nu partaja niciodată cheia ta API.

Utilizare printr-un agent IA (recomandat)

Nu ești dezvoltator sau nu vrei să scrii cod? Cea mai simplă metodă este să folosești un agent IA precum Claude prin protocolul MCP (Model Context Protocol). Agentul știe exact ce apeluri să facă, gestionează autentificarea și înțelege instrucțiunile tale în limbaj natural.

Notă: Claude și Windsurf sunt exemple de integrări MCP. Există multe alte instrumente și medii compatibile, însă nu este posibil să le trecem pe toate în revistă aici.

1. Activează API-ul și generează cheia

În back-office-ul PrestaBlog: Instrumente > API. Activează API-ul, apasă „Generate a new key” și copiază cheia afișată - nu va mai fi accesibilă ulterior.

2. Construiește URL-ul de conexiune MCP

URL-ul de conexiune urmează acest format:

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

Înlocuiește YOUR_KEY cu cheia generată și https://your-shop.com cu URL-ul magazinului tău.

Nu confunda acest URL cu „API URL”, care este un URL diferit folosit pentru apeluri directe.

Important

URL-ul conține cheia ta API. Trateaz-o ca pe o parolă: nu o partaja și nu o publica.

3. Configurează cu Claude

În Claude, apasă Customize în stânga sus, apoi Connectors,
iar în partea de sus a coloanei care apare apasă butonul +, apoi Add a custom connector.

Completează:

  • Name: orice dorești (ex: PrestaBlog API)
  • URL: URL-ul de conexiune MCP construit la pasul 2

Confirmă. Claude poate acum accesa blogul tău și poate crea, modifica și șterge articolele și categoriile direct.

Exemple de cereri pe care i le poți face lui Claude:

  • „Creează un articol despre încălțăminte de vară în categoria Fashion”
  • „Listează ultimele 10 articole publicate”
  • „Schimbă titlul articolului 42”
  • „Creează o categorie nouă numită Noutăți cu această descriere”
  • „Șterge categoria 5”

Documentație integrată

Documentația completă este integrată în conectorul MCP. Claude o citește automat, nu mai ai nimic de configurat.

4. Configurează cu Windsurf

În Windsurf, deschide panoul Cascade, apasă ... în colțul din dreapta sus, apoi apasă pictograma MCPs (ultima pictogramă din dreapta jos a meniului). Se deschide o fereastră de editare. Adaugă următoarea configurație după ce ai generat corect URL-ul (vezi pasul 2):

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

Salvează. Cascade afișează 1 MCP în partea de jos a panoului, confirmând că conexiunea este activă.

Exemple de cereri pe care i le poți face lui Cascade:

  • „Creează un articol despre încălțăminte de vară în categoria Fashion”
  • „Listează ultimele 10 articole publicate”
  • „Schimbă titlul articolului 42”
  • „Creează o categorie nouă numită Noutăți cu această descriere”
  • „Șterge categoria 5”

Documentație integrată

Documentația completă este integrată în conectorul MCP. Cascade o citește automat, nu mai ai nimic de configurat.

Autentificare (REST)

Fiecare cerere trebuie să includă cheia API într-un header HTTP. Sunt acceptate două formate:

Authorization: Bearer YOUR_API_KEY

sau

X-Api-Key: YOUR_API_KEY

Bună practică

Cheia nu trebuie niciodată transmisă ca parametru în URL, pentru a evita apariția ei în logurile serverului.

Blocare automată: după 5 încercări de autentificare eșuate de la același IP, acesta este blocat timp de 1 oră. Această durată este configurabilă în setările API.

Articole

Listează articolele

GET /prestablog-api/articles

Returnează lista paginată de articole. Parametri disponibili: lang (ID limbă), page, per_page (max 100), active (1 = doar publicate), category (ID categorie), search (căutare în titlu), 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"

Detalii articol

GET /prestablog-api/articles/{id}

Returnează toate datele unui articol: câmpuri multilingve, categorii, produse asociate, articole asociate, cuprins.

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

Creează un articol

POST /prestablog-api/articles

Exemplu minim:

curl -X POST "https://your-shop.com/prestablog-api/articles" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "languages": {
      "1": {
        "title": "Articolul meu",
        "content": "<h2>Introducere</h2><p>Conținutul articolului.</p>"
      }
    },
    "categories": [1],
    "active": true
  }'

Exemplu complet cu imagine, conținut multilingv și metadate:

{
  "languages": {
    "1": {
      "title": "Articolul meu",
      "introduction": "Text scurt afișat în liste",
      "content": "<h2>Secțiune</h2><p>Conținut HTML complet.</p>",
      "meta_title": "Articolul meu - Titlu SEO",
      "meta_description": "Descriere pentru motoarele de căutare",
      "meta_keywords": "word1, word2",
      "link_rewrite": "articolul-meu"
    },
    "2": {
      "title": "Articolul meu",
      "introduction": "Text scurt afișat în liste",
      "content": "<h2>Secțiune</h2><p>Conținut HTML complet.</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"
  }
}

Câmpuri disponibile:

FieldTypeDescription
languagesobjectConținut pe limbă, indexat după ID-ul limbii PrestaShop. Obligatoriu la creare
languages.{id}.titletextTitlul articolului. Obligatoriu pentru fiecare limbă
languages.{id}.introductionHTMLText scurt afișat în liste și în partea de sus a articolului
languages.{id}.contentHTMLCorpul articolului
languages.{id}.meta_titletextEticheta title SEO (max 500 caractere)
languages.{id}.meta_descriptiontextMeta description (max 500 caractere)
languages.{id}.meta_keywordstextCuvinte-cheie SEO
languages.{id}.link_rewritetextSlug URL. Generat automat din titlu dacă lipsește
categoriesarray of IDsCategorii PrestaBlog de asociat
productsarray of IDsProduse PrestaShop asociate
related_articlesarray of IDsArticole asociate
activebooleanPublicare imediată. Dacă lipsește, folosește setarea „Activează automat”
datedatetimeData publicării în format YYYY-MM-DD HH:MM:SS. O dată viitoare programează publicarea
enable_tocbooleanActivează cuprinsul generat din tag-urile h2/h3 din conținut
author_idintegerID autor PrestaBlog
image.urlURLImagine principală de descărcat dintr-un URL la distanță
id_shopintegerID magazin (doar multishop). Implicit: magazinul curent

Actualizează un articol

PUT /prestablog-api/articles/{id}

Actualizare parțială: sunt actualizate doar câmpurile prezente în cerere. Câmpurile neincluse își păstrează valoarea curentă. Pentru limbi, sunt actualizate doar cele incluse în payload.

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": "New title"
      }
    }
  }'

Șterge un articol

DELETE /prestablog-api/articles/{id}

Șterge articolul și toate datele asociate: imagini (toate variantele), categorii, produse asociate, articole asociate.

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

Imagine articol

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

Sunt disponibile trei metode, în funcție de context:

URL la distanță (imagine găzduită 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"}'

Fișier local (încărcare 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 (fallback):

Notă: base64 este foarte voluminos și poate deveni dificil de gestionat pentru imagini complexe. Când este posibil, preferă încărcarea prin URL la distanță.

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

Prin MCP (Claude)

Prin MCP sunt disponibile doar metodele URL și base64. Pentru a trimite un fișier local prin Claude, encodează-l mai întâi în base64.

Categorii

API-ul îți permite să creezi, să consulți, să modifici și să ștergi categorii, exact ca în cazul articolelor.

Listează categoriile

GET /prestablog-api/categories

Returnează categoriile sub formă de arbore, implicit. Folosește flat=1 pentru o listă plată, active=1 pentru doar cele active, lang pentru limbă.

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

Detalii categorie

GET /prestablog-api/categories/{id}

Returnează toate datele categoriei: câmpuri multilingve, numărul de articole, grupuri de clienți asociate.

Creează o categorie

POST /prestablog-api/categories

Exemplu minim:

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

Exemplu complet:

{
  "languages": {
    "1": {
      "title": "Noutăți",
      "description": "<p>Toate noutățile din magazinul nostru.</p>",
      "meta_title": "Noutăți - Titlu SEO",
      "meta_description": "Descriere SEO a categoriei",
      "meta_keywords": "noutăți",
      "link_rewrite": "news"
    },
    "2": {
      "title": "Noutăți",
      "description": "<p>Toate cele mai recente noutăți din magazinul nostru.</p>",
      "link_rewrite": "news"
    }
  },
  "parent": 0,
  "position": 1,
  "active": true,
  "image": {
    "url": "https://example.com/category.jpg"
  }
}

Câmpuri disponibile:

FieldTypeDescription
languagesobjectConținut pe limbă. Obligatoriu la creare
languages.{id}.titletextTitlul categoriei. Obligatoriu pentru fiecare limbă
languages.{id}.descriptionHTMLDescrierea categoriei
languages.{id}.meta_titletextEticheta title SEO (max 500 caractere)
languages.{id}.meta_descriptiontextMeta description (max 500 caractere)
languages.{id}.meta_keywordstextCuvinte-cheie SEO
languages.{id}.link_rewritetextSlug URL. Generat automat din titlu dacă lipsește
parentintegerID categorie părinte. 0 = rădăcină
positionintegerOrdine de afișare
activebooleanCategorie vizibilă pe front
image.urlURLImagine categorie de descărcat dintr-un URL la distanță

Actualizează o categorie

PUT /prestablog-api/categories/{id}

Actualizare parțială: sunt actualizate doar câmpurile prezente în cerere.

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": "Nume categorie nou",
        "description": "<p>Descriere nouă.</p>"
      }
    }
  }'

Șterge o categorie

DELETE /prestablog-api/categories/{id}

Șterge categoria și toate datele asociate: imagine, legături cu articolele, grupuri de clienți.

Atenție

Articolele asociate acestei categorii nu sunt șterse, însă își pierd legătura cu categoria.

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

Imagine categorie

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

Aceleași trei metode ca la articole: URL la distanță, fișier local (multipart) sau base64.

Notă: base64 este foarte voluminos și poate deveni dificil de gestionat pentru imagini complexe. Când este posibil, preferă încărcarea prin URL la distanță.

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

Autori

Autorii sunt doar în regim de citire prin API. Ei trebuie creați în back-office-ul PrestaBlog.

  • GET /prestablog-api/authors - listează toți autorii
  • GET /prestablog-api/authors/{id} - detalii autor cu biografii multilingve
curl -X GET "https://your-shop.com/prestablog-api/authors?lang=1" \
  -H "Authorization: Bearer YOUR_KEY"

Coduri de eroare

Toate răspunsurile de eroare urmează acest format:

{
  "success": false,
  "error": {
    "code": "validation_error",
    "message": "Human readable error message",
    "details": { "field": "languages.1.title" }
  }
}
CodHTTPSemnificație
unauthorized401Cheie API lipsă sau invalidă
api_disabled503API dezactivat în configurare
https_required426Cererea trebuie făcută prin HTTPS
rate_limited429Limită de cereri depășită sau IP blocat după eșecuri de autentificare
invalid_json400Body JSON invalid sau lipsă
validation_error422Valoare de câmp invalidă (detalii în error.details)
conflict409Conflict de slug: există deja un articol sau o categorie cu acest link
not_found404Resursă negăsită
method_not_allowed405Metodă HTTP nesuportată pentru acest endpoint
payload_too_large413Body-ul cererii este prea mare (limită: 10 MB)
internal_error500Eroare internă de server

Limită de cereri: când este depășită, răspunsul 429 include un header Retry-After care indică numărul de secunde de așteptat înainte de a reîncerca. Fiecare răspuns include și headerele X-RateLimit-Limit și X-RateLimit-Remaining.

Integrare Python

Pentru dezvoltatorii Python, biblioteca requests permite interacțiunea cu API-ul în doar câteva linii.

pip install requests
import requests

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

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

# Creează un articol
r = requests.post(f"{BASE}/articles", headers=headers, json={
    "languages": {"1": {"title": "Articolul meu", "content": "<p>Conținut</p>"}},
    "categories": [1],
    "active": True
})
print(r.json())

# Încarcă o imagine dintr-un fișier local
with open("image.jpg", "rb") as f:
    r = requests.post(f"{BASE}/articles/18/image", headers=headers, files={"file": f})
print(r.json())