StockSEO API

REST API do wbudowania funkcji SEO i AI StockSEO we własny produkt. Audyty, generowanie opisów produktów (także masowo), monitoring widoczności w wyszukiwarkach i w odpowiedziach AI.

Bazowy URL: https://stockseo.tojest.dev/ext/v1 JSON in / JSON out CORS: włączony

// wprowadzenie

API jest wersjonowane w ścieżce (/ext/v1/). Wszystkie odpowiedzi to JSON w spójnym kształcie: sukces ma ok: true i pole data, błąd ma ok: false i pole error. Nie musisz nic instalować — wystarczy klient HTTP.

API jest przeznaczone dla systemów, które chcą oferować swoim klientom funkcje SEO/AI: platform sklepowych, CRM-ów, wtyczek i narzędzi do zarządzania asortymentem. Endpointy dzielą się na publiczny health check oraz chronione, wymagające klucza API. Operacje masowe działają asynchronicznie przez system zadań. Żądania POST są limitowane na klucz (domyślnie 30/min; nagłówki X-RateLimit-*, po przekroczeniu 429 z Retry-After) — masowe operacje rób przez endpointy *-bulk, a status odpytuj GET-em, który limitu nie ma.

// uwierzytelnianie

Chronione endpointy wymagają klucza API w nagłówku:

# zalecane
X-API-Key: sk_stockseo_xxxxxxxxxxxx

# alternatywnie
Authorization: Bearer sk_stockseo_xxxxxxxxxxxx

Klucz otrzymujesz od StockSEO przy uruchamianiu integracji. Jest przypisany do Twojego systemu i ma zestaw uprawnień (scope): seo:read (analizy), seo:generate (generowanie treści), geo:read (widoczność w AI) albo * (wszystko). Brak uprawnienia zwraca 403 forbidden.

Klucz jest tajny. Trzymaj go po stronie serwera — nigdy w kodzie wykonywanym w przeglądarce.

// format odpowiedzi

Każda udana odpowiedź:

{
  "ok": true,
  "data": { /* zawartość zależna od endpointu */ },
  "meta": { "api": "v1" }
}

Każdy błąd:

{
  "ok": false,
  "error": {
    "code": "unauthorized",
    "message": "Brak lub nieprawidłowy klucz API",
    "hint": "Wyślij nagłówek X-API-Key: sk_stockseo_..."
  }
}

// kody błędów

HTTPcodeznaczenie
401unauthorizedBrak lub nieprawidłowy klucz API
403forbiddenKlucz nie ma wymaganego uprawnienia
404job_not_foundZadanie nie istnieje lub wygasło (po 1h)
400too_manyPrzekroczony limit pozycji (500 bulk / 20 promptów)
503program_unlicensedInstancja StockSEO chwilowo bez aktywnej subskrypcji
500internal_errorBłąd po stronie serwera
404no_releaseBrak opublikowanego wydania
404not_foundNieznany endpoint

// endpointy

GET/ext/v1/

Lista dostępnych endpointów i uprawnień Twojego klucza. Dobre miejsce, żeby sprawdzić, czy klucz działa.

curl https://stockseo.tojest.dev/ext/v1/ \
  -H "X-API-Key: sk_stockseo_..."
GET/ext/v1/status

Health check. Publiczny — nie wymaga klucza. Użyj do monitoringu dostępności.

curl https://stockseo.tojest.dev/ext/v1/status

{ "ok":true, "data":{
  "status":"operational", "version":"1.0.5", "licensed":true
}}
POST/ext/v1/content/product-bulk

Opisy produktów masowo. Główny endpoint dla integracji sklepowych — wrzucasz listę produktów po imporcie, dostajesz gotowe opisy SEO. Działa asynchronicznie: zwraca job_id, wynik odbierasz przez GET /ext/v1/jobs/{id}. Limit 500 pozycji. Wymaga seo:generate.

curl -X POST https://stockseo.tojest.dev/ext/v1/content/product-bulk \
  -H "X-API-Key: sk_stockseo_..." \
  -d '{"products":[{"id":1,"name":"Paleta mix elektronika"}]}'

{ "ok":true, "data":{
  "job_id":"job_a1b2c3", "status":"queued", "total":1
}}
GET/ext/v1/jobs/{id}

Status zadania masowego. Odpytuj co 3–5 sekund. Gdy status: "completed", w odpowiedzi jest pole results. Zadania wygasają po godzinie — zapisz wyniki u siebie.

curl https://stockseo.tojest.dev/ext/v1/jobs/job_a1b2c3 \
  -H "X-API-Key: sk_stockseo_..."

{ "ok":true, "data":{
  "status":"completed", "total":1, "done":1, "progress":100,
  "results":[{ "id":1, "description_html":"<p>...</p>" }]
}}
POST/ext/v1/content/alt-bulk

Teksty ALT do zdjęć produktowych, masowo. Ten sam wzorzec zadania. Limit 500 pozycji.

-d '{"images":[{"id":5,"context":"paleta elektroniki"}]}'
POST/ext/v1/geo/monitor

Widoczność marki w AI. Sprawdza, czy modele AI wymieniają markę klienta, odpowiadając na pytania zakupowe. Zwraca score (procent pytań z wzmianką) — gotowa metryka na wykres w Twoim panelu. Limit 20 pytań. Wymaga geo:read.

-d '{"brand":"TwojSklep.pl","prompts":["gdzie kupić palety zwrotów"]}'

{ "ok":true, "data":{
  "checked":1, "mentions":1, "score":100,
  "results":[{ "prompt":"...", "mentioned":true }]
}}
POST/ext/v1/geo/audit

Audyt widoczności w AI: czy modele znają firmę, czego brakuje w treściach, konkretne zalecenia.

-d '{"brand":"TwojSklep.pl","industry":"hurtownia zwrotów","city":"Gdynia"}'
POSTpozostałe endpointy

Wszystkie przyjmują JSON i zwracają ten sam format. Pełne opisy pól: GET /ext/v1/.

# treści
POST /ext/v1/content/refine        {content, goal?}
POST /ext/v1/seo/article          {topic, keywords?, length?}
POST /ext/v1/seo/product          {name, features?, category?}
POST /ext/v1/seo/meta             {title, content?}

# analizy
POST /ext/v1/seo/audit            {url | content}
POST /ext/v1/seo/keywords         {keyword}
POST /ext/v1/seo/longtail         {keyword}
POST /ext/v1/serp/plan            {keywords, site?}
POST /ext/v1/research/competitor  {url | content}
POST /ext/v1/research/topics      {niche, count?, city?}

# GEO i pozostałe
POST /ext/v1/geo/gap-analysis     {brand, competitors?}
POST /ext/v1/links/ideas          {niche, city?, site?}
POST /ext/v1/social/tiktok-script {topic | product}

// przykłady integracji

Najczęstszy przypadek: klient zaimportował paletę, chcesz wygenerować opisy dla wszystkich produktów naraz.

PHP (curl)

$KEY = "sk_stockseo_...";
$BASE = "https://stockseo.tojest.dev/ext/v1";

// 1. Zlec zadanie
$ch = curl_init($BASE . "/content/product-bulk");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => ["Content-Type: application/json", "X-API-Key: " . $KEY],
  CURLOPT_POSTFIELDS => json_encode(["products" => $produkty]),
  CURLOPT_RETURNTRANSFER => true,
]);
$job = json_decode(curl_exec($ch), true);
$jobId = $job["data"]["job_id"];

// 2. Odpytuj co 5 sekund, az gotowe
do {
  sleep(5);
  $ctx = stream_context_create(["http" => ["header" => "X-API-Key: " . $KEY]]);
  $st = json_decode(file_get_contents($BASE . "/jobs/" . $jobId, false, $ctx), true);
} while ($st["data"]["status"] !== "completed");

// 3. Zapisz opisy przy produktach
foreach ($st["data"]["results"] as $r) {
  zapiszOpis($r["id"], $r["description_html"]);
}

JavaScript (fetch)

const KEY = "sk_stockseo_...", BASE = "https://stockseo.tojest.dev/ext/v1";
const H = { "Content-Type": "application/json", "X-API-Key": KEY };

const job = await (await fetch(BASE + "/content/product-bulk", {
  method: "POST", headers: H, body: JSON.stringify({ products })
})).json();

let st;
do {
  await new Promise(r => setTimeout(r, 5000));
  st = await (await fetch(BASE + "/jobs/" + job.data.job_id, { headers: H })).json();
} while (st.data.status !== "completed");

st.data.results.forEach(r => zapiszOpis(r.id, r.description_html));

Python (requests)

import requests, time
KEY = "sk_stockseo_..."; BASE = "https://stockseo.tojest.dev/ext/v1"
H = {"X-API-Key": KEY}

job = requests.post(f"{BASE}/content/product-bulk",
                    json={"products": produkty}, headers=H).json()
job_id = job["data"]["job_id"]

while True:
    time.sleep(5)
    st = requests.get(f"{BASE}/jobs/{job_id}", headers=H).json()
    if st["data"]["status"] == "completed": break

for r in st["data"]["results"]:
    zapisz_opis(r["id"], r["description_html"])

// zmiany API

wersjadatazmiany
v12026-07API integracyjne: treści (w tym masowe przez zadania), audyty SEO, GEO/widoczność w AI, badania konkurencji, link building, social.
stabilność
Wersja v1 jest stabilna. Zmiany łamiące kompatybilność trafią do v2 pod nową ścieżką — v1 będzie działać dalej. Zmiany nie-łamiące (nowe pola, nowe endpointy) dochodzą do v1 bez zapowiedzi.

Pytania o integrację? kontakt@stockseo.pl