A Termék API

A fejlesztői leírás a Termék API forrásokhoz — milyen JSON-t szolgáltat a webshopod, hogy beolvashassuk, és melyik végpontra küldi el a változásokat, ahogy megtörténnek.

Áttekintés

Egy Termék API forrás két irányban működik, és bármelyiket vagy mindkettőt használhatod:

  • Lekérés — küldünk egy GET kérést egy általad birtokolt címre, a forrásnál beállított ütemezés szerint, te pedig visszaadod a teljes katalógusodat.
  • Küldés — te POST-olod nekünk a megváltozott termékeket abban a pillanatban, amikor megváltoznak.

Az irányítópult API füle ugyanezt a leírást tartalmazza, a márkád valódi címeivel kitöltve, úgyhogy a bekötést érdemes ott kezdeni.

Minden, ami itt következik, kizárólag a Termék API forrásokra vonatkozik. A CSV folyam egy sima Google Shopping fájl — nincs küldési végpontja, titka és egyedi mezője.

Lekérés — mi olvassuk be a címedet

A kérés, amit küldünk

Egyetlen GET. Nincs lapozás: add vissza az egészet egy válaszban.

FejlécÉrték
Acceptapplication/json
User-AgentYapletBot/1.0 (+https://yaplet.com)
SignatureA megosztott titkod SHA-256 lenyomata, kisbetűs hexadecimálisan

Plusz minden további fejléc, amit a forráson beállítottál.

A Signature a megosztott titok egyszerű lenyomata — nem HMAC a törzs fölött, és nem változik kérésről kérésre. Úgy ellenőrizd, hogy lenyomatolod a saját példányodat a titokból, és összeveted. Kezeld TLS-sel védett hozzáférési kulcsként, ne kérésaláírásként: nem képes visszajátszást vagy manipulációt észlelni.

A címednek https-t kell használnia, az első kérésnél és minden átirányításnál. A privát és belső címeket elutasítjuk.

Amit visszaadsz

Egy alak van, akár vannak változatai a termékeidnek, akár nincsenek. Egy több ízben, kiszerelésben vagy színben kapható termék variants listát hordoz; egy olyan, aminek nincsenek változatai, a saját price és availability mezőjét viszi helyette.

{
  "products": [
    {
      "id": "whey-gold",
      "title": "Whey Gold fehérjepor",
      "link": "https://shop.example.com/products/whey-gold",
      "description": "Tejsavófehérje-koncentrátum hozzáadott emésztőenzimekkel.",
      "image": "https://shop.example.com/images/whey-gold.jpg",
      "brand": "Acme Nutrition",
      "category": "Fehérje > Tejsavó",
      "priority": 820,
      "attributes": {
        "Összetevők": ["tejsavófehérje-koncentrátum (tej)", "kakaó"],
        "Adagolás": "napi 1 adag (32 g)"
      },
      "search_terms": ["tejsavó", "fehérjeturmix"],
      "rule_keys": ["tejsavófehérje"],
      "variants": [
        {
          "id": "10803",
          "options": { "Íz": "Pisztácia", "Kiszerelés": "1 kg" },
          "price": "19 990 HUF",
          "availability": "in stock",
          "link": "https://shop.example.com/products/whey-gold?variant=10803",
          "attributes": {
            "Tápérték adagonként": { "Energia": "128 kcal", "Fehérje": "24 g" }
          },
          "priority": 950,
          "rule_keys": ["pisztácia"]
        },
        {
          "id": "10804",
          "options": { "Íz": "Pisztácia", "Kiszerelés": "2,3 kg" },
          "price": "39 990 HUF",
          "sale_price": "34 990 HUF",
          "availability": "out of stock"
        }
      ]
    },
    {
      "id": "SKU-1001",
      "title": "C-vitamin 1000 mg, 60 tabletta",
      "link": "https://shop.example.com/products/vitamin-c-1000",
      "description": "Nagy dózisú C-vitamin könnyen lenyelhető tablettában.",
      "price": "4990 HUF",
      "sale_price": "3990 HUF",
      "availability": "in stock",
      "brand": "Acme Health",
      "category": ["Vitaminok", "C-vitamin"],
      "attributes": {
        "Összetevők": ["aszkorbinsav", "csipkebogyó kivonat"],
        "Kiszerelés": "tabletta"
      },
      "rule_keys": ["aszkorbinsav"],
      "rules": ["A C-vitamin hozzájárul az immunrendszer normál működéséhez."]
    }
  ]
}
A változatok bevezetése előtt írt feed továbbra is érvényes feed. Egy variants nélküli terméket pontosan egy változattal tárolunk el, ami a terméken küldött árat és készletállapotot hordozza. Semmit nem kell átírnod ahhoz, hogy működjön tovább — a variants hozzáadása az, amivel csoportosított ízeket és kiszereléseket kapsz, amikor szeretnél.
A lekérés mindig teljes pillanatkép. Ennek a forrásnak minden olyan terméke, ami hiányzik a válaszodból, törlődik. Ha csak a változásokat akarod küldeni, használd a küldést.

Időzítés és hibák

Beolvasásonként három próbálkozás (egyenként 30 másodperc, 5, majd 15 másodperc várakozással), de csak időtúllépésre, hálózati hibára és 5xx válaszra. Egy 4xx azonnal hibára fut. A válasz törzse legfeljebb 50 MB lehet, és legfeljebb 20 000 terméket tartalmazhat.

A nulla termékkel visszatérő válasz hibának számít, így egy elromlott végpont soha nem ürítheti ki észrevétlenül a katalógust.

A termékobjektum

Kötelező

id
string vagy number required
Az állandó azonosítód. 1–200 karakter. A számokat elfogadjuk és szövegként tároljuk — tehát az 1001 és az "1001" ugyanaz a termék.
title
string required
1–500 karakter.
link
string required
A termékoldal. http vagy https URL kell legyen, legfeljebb 2048 karakter.

Nem kötelező

description
string
Legfeljebb 20 000 karakter. Teljes egészében indexeljük, és teljes egészében megkapja az AI — már nincs külön, rövidebb kereshető kivonat.
image
string
http vagy https URL.
price
string vagy number
Szabad szöveg, legfeljebb 100 karakter — a "4990 HUF" is jó. Csak akkor használjuk, ha a terméknek nincs variants listája.
sale_price
string vagy number
Ugyanaz, mint a price. Csak akkor használjuk, ha a terméknek nincs variants listája.
availability
string
Legfeljebb 100 karakter. Csak akkor használjuk, ha a terméknek nincs variants listája.
brand
string
Legfeljebb 200 karakter.
category
string vagy string[]
A termék kategóriája útvonalként, legfeljebb 6 szint, szintenként legfeljebb 100 karakter. Vagy egyetlen szöveg > jellel a szintek között ("Fehérje > Tejsavó"), vagy a szintek listája (["Fehérje", "Tejsavó"]). Egy mélyebb útvonaltól az elem érvénytelen lesz.
priority
number
A sorrend, amiben ezt a terméket fel akarod soroltatni. A magasabb kerül előrébb; az alapérték 0. Kizárólag a sorrendet dönti el — soha nem azt, hogy mit mondhat az AI egy termékről.
attributes
object
A saját mezőid. Lásd lentebb.
search_terms
string[]
További szavak, amiknek meg kell találniuk ezt a terméket — becenevek, egy régi név, egy gyakori elgépelés. Legfeljebb 100 szó termékenként, a változatokkal együtt. Az AI soha nem látja őket, és a szabályok sem illeszkednek rájuk.
rule_keys
string[]
A termék által hordozott kulcsok. Legfeljebb 500, egyenként legfeljebb 200 karakter.
rules
string[]
Mondatok, amiket az AI-nak követnie kell erről a termékről. Legfeljebb 100, egyenként legfeljebb 5000 karakter.
variants
object[]
A termék változatai — ízek, kiszerelések, színek. Legfeljebb 500. Lásd a következő szakaszt.

A változatobjektum

A variants minden eleme egy dolog, amit a vásárló meg tud venni. Csak az id kötelező.

id
string vagy number required
A változat saját, állandó azonosítója — általában a valódi cikkszámod. A terméken belül egyedinek kell lennie; ismétlődés esetén az egész termék érvénytelen lesz.
options
object
Ami megkülönbözteti ezt a változatot, név: érték alakban — { "Íz": "Pisztácia", "Kiszerelés": "1 kg" }. Legfeljebb 5 opció, a nevek legfeljebb 40, az értékek legfeljebb 60 karakterrel. Abban a sorrendben mutatjuk meg, ahogy küldöd, tehát úgy küldd őket, ahogy olvastatni szeretnéd.
price / sale_price / availability
string vagy number
Ennek a változatnak a saját ára, akciós ára és készletállapota. Ugyanazok a szabályok, mint a terméken.
link
string
Közvetlen link erre a változatra, ha van ilyened. Ha nincs, a termék linkjét használjuk.
image
string
A változat saját képe, ha eltér.
attributes
object
Kizárólag ehhez a változathoz tartozó mezők — például a saját tápértéktáblázata.
priority
number
Sorrend a terméken belül. A magasabb kerül előrébb.
search_terms / rule_keys / rules
string[]
Pontosan úgy, mint a terméken, csak erre a változatra. Egy változat kulcsai a termék kulcsainak számítanak, így egy olyan összetevőre kulcsolt szabály, ami csak az egyik ízben van benne, akkor is eléri a terméket.
Ha variants listát küldesz, a termék saját price, sale_price és availability mezőjét figyelmen kívül hagyjuk — ezeket a változatok hordozzák. A futásjelentés ezt „Figyelmen kívül hagyott termékárak (változatokat küldtél)" néven számolja, tehát ha ott nem nulla a szám, akkor mindkettőt küldöd, és az egyik nem csinál semmit.
Egy variants nélküli termék belül sem különleges eset: egy névtelen változattal rendelkező termék lesz belőle, ami a küldött árat és készletállapotot hordozza. Ezért működik változtatás nélkül tovább egy régebbi feed.
Nincsenek alternatív mezőnevek. Az sku, az url, az image_link, a salePrice és a product_url mind figyelmen kívül marad — pontosan a fenti neveket használd. Az ismeretlen kulcsokat csendben eldobjuk.

attributes — a saját mezőid

Egy objektum, aminek az értékei szöveg, szám, logikai érték, ezek tömbje, vagy egy szint mélységű beágyazott objektum lehetnek — így tudsz például tápértéktáblázatot küldeni:

"attributes": {
  "Adagolás": "1 adag (32 g)",
  "Tápérték adagonként": { "Energia": "128 kcal", "Fehérje": "24 g", "Zsír": "2,2 g" }
}
A szöveges értékeket vessző és pontosvessző mentén szétvágjuk. A "Darabszám": "12,5 kg" két értékké válik: 12 és 5 kg. Használj tömböt mindenhez, ami jogosan tartalmaz vesszőt vagy pontosvesszőt.

Az egy szintnél mélyebb beágyazás az egész terméket érvénytelenné teszi — nem csak azt az egy mezőt.

A mezőkre már nincs hosszkorlát. Korábban termékenként 4000 karakternél elvágtuk őket; most mindent megtartunk és indexelünk, amit küldesz. Már nem kell fontossági sorrendbe raknod a mezőidet, hogy megvédd őket, és a jelentés régi „Hossz miatt levágott mezők" számlálója sem jelenik meg többé.

rule_keys és rules

Mindkettőt tároljuk, de soha nem tesszük kereshetővé. Kizárólag a termékszabályok miatt léteznek.

  • A rule_keys dönti el, mely szabályok vonatkoznak erre a termékre.
  • A rules mondatait az AI szó szerint, minden alkalommal megkapja, amikor ez a termék megjelenik egy válaszban.
Mivel nem kereshetők, ha az összetevőlistát csak a rule_keys mezőben küldöd el, az AI soha nem fogja megtalálni a terméket az adott összetevő alapján. Tedd bele az attributes mezőbe is, ha a vásárlók rákeresnek.

Ami nem kereshető

A price, a sale_price és az availability szándékosan soha nem része annak, amit az AI megtanult — folyamatosan változnak, és a válasz készítésekor olvassuk ki őket élőben a változatokról. Az AI nem tud rájuk keresni.

A search_terms ennek a tükörképe: kizárólag kereshető. Segít a keresésnek megtalálni a terméket, és az AI soha nem látja, így egy termék beceneve nem szivároghat bele egy mondatba.

Érvénytelen elemek

Az érvénytelen elemeket kihagyjuk, soha nem végzetesek — a futás folytatódik, és a jelentés felsorolja az első 50-et az indokkal. Ha ugyanaz az id kétszer szerepel egy küldeményben, az utolsó nyer.

Egyetlen változatot soha nem hagyunk ki önmagában. Ha egy termék bármelyik változata megbukik az ellenőrzésen, az egész termék kimarad a futásból, hogy a katalógusban soha ne legyen olyan termék, aminek csendben hiányzik a fele kiszerelése. A jelentés ezeket külön, „Terméket megállító változatok" néven számolja.

Küldés — te küldöd nekünk a változásokat

A végpont

POST https://yaplet.com/api/products/push/{sourceId}

A {sourceId} a forrás azonosítója — másold ki a Küldési cím másolása gombbal a Források fülön.

Hitelesítés

Küldd el a szervezeti API kulcsodat a Y-API-Key fejlécben. Ez a Beállítások → API oldalról származó kulcs, nem a forrás megosztott titka.

Egy szervezeti kulcs a szervezet összes Termék API forrásához küldési hozzáférést ad; a célt az URL-ben szereplő forrásazonosító választja ki. A kulcs cseréje egy csapásra minden webshop-integrációt eltör a szervezetben.

A törzs

MezőAlapértelmezésJelentés
mode"merge"A "merge" csak azt frissíti, amit elküldesz. A "replace" teljes pillanatképpé teszi ezt a küldést.
products[]Termékobjektumok, pontosan a fentiek szerint.
deleted_ids[]Eltávolítandó termékek. replace módban figyelmen kívül marad.
const res = await fetch("https://yaplet.com/api/products/push/YOUR_SOURCE_ID", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Y-API-Key": "YOUR_API_KEY",
  },
  body: JSON.stringify({
    mode: "merge",
    products: [
      {
        id: "SKU-1001",
        title: "Vitamin C 1000 mg, 60 tablets",
        link: "https://shop.example.com/products/vitamin-c-1000",
        price: "12.90 EUR",
        availability: "in stock",
        attributes: { Ingredients: ["ascorbic acid"] },
        rule_keys: ["ascorbic acid"],
      },
    ],
    deleted_ids: ["SKU-0999"],
  }),
});

const result = await res.json();
console.log(result.run_id, result.accepted);

Amit visszakapsz

A sikeres küldés 202 Accepted választ ad:

{
  "run_id": "3f9d2c6e-1b7a-4c1e-9f0a-2d8e5b6c7a90",
  "status": "running",
  "received": 1,
  "accepted": 1,
  "invalid": 0,
  "report_url": "/api/products/push/YOUR_SOURCE_ID/runs/3f9d2c6e-1b7a-4c1e-9f0a-2d8e5b6c7a90"
}
A 202 nem azt jelenti, hogy a termékek megérkeztek. Az elemeidet ellenőriztük, de maga a betöltés a háttérben fut — a korlátok, a tárolás és az indexelés utána is hibára futhat. Kérdezd le a futást, ha biztos akarsz lenni.

Egy futás lekérdezése

GET https://yaplet.com/api/products/push/{sourceId}/runs/{runId}

Ugyanaz a Y-API-Key fejléc. Kérdezd le addig, amíg a status már nem "running", aztán olvasd ki a számlálókat, és ha a status "failed", az error és az error_code mezőket.

Forrásonként csak a legutóbbi futás marad meg. A következő küldésed — vagy egy közben lefutó ütemezett beolvasás — felülírja, és a régi run_id ezután 404-et ad. Olvasd el a jelentést, mielőtt elküldöd a következő adagot. Egy sikertelen futás is 200-zal válaszol; a status mezőt nézd, ne a HTTP kódot.

Küldési szabályok

  • A merge csak az általad küldött azonosítókhoz nyúl. Minden más érintetlen marad.
  • A deleted_ids termékazonosítók, nem változatazonosítók. Egy termék törlésével a változatai is törlődnek. Egy nem hozzád tartozó vagy nem létező azonosítót csendben figyelmen kívül hagyunk. Ha egy azonosító a products és a deleted_ids listában is szerepel, a termék nyer.
  • A mode: "replace" törli a forrás minden olyan termékét, ami nincs benne a küldeményben.
Egy elküldött termék az összes változatát lecseréli. Nincs mód egyetlen változat külön hozzáadására vagy eltávolítására: a terméket azzal a teljes variants listával küldd el, amilyennek a végén látni szeretnéd. Egy változat, amit kihagysz ebből a listából, törlődik.
A {"mode": "replace", "products": []}törli a forrás összes termékét. A lekéréssel ellentétben a replace módban nincs üres-küldemény védelem.

Azok a termékek, amiknek a tartalma nem változott, semmibe nem kerülnek — nem indexeljük őket újra. Ha csak az árat, az akciós árat vagy az elérhetőséget módosítod, a sor frissül, de semmit nem indexelünk újra.

Egy sikeres küldés visszahozza azokat a termékeket is, amiket a forrás hibázása miatt rejtettünk el. Azt viszont nem indítja újra, ha az ütemezés három sikertelen beolvasás után leállt — arra csak a Beolvasás most való.

Hibák

KódMikor
400Hibás JSON, rossz mode, több mint 20 000 elem, vagy üres merge
401Hiányzó vagy érvénytelen Y-API-Key
403A szervezetednek nincs Tartalomforrások jogosultsága
404Ismeretlen forrás, másik szervezet forrása, vagy CSV forrás
409Ehhez a forráshoz épp fut egy másik beolvasás vagy küldés — várj és próbáld újra
411Nincs Content-Length — a darabolt feltöltést nem fogadjuk el
413A törzs nagyobb, mint 25 MB
429Túl sok kérés. A Retry-After megmondja, mennyit kell várni

Sebességkorlátok

Percenként 12 küldés forrásonként, és percenként 60 szervezetenként. Minden válasz tartalmazza az X-RateLimit-Limit, az X-RateLimit-Remaining és az X-RateLimit-Reset fejlécet.

Egy előfizetés és egyenleg nélküli szervezet kisebb korlátokat kap: törzsenként 5 MB, küldésenként 1000 elem, és percenként 6 küldés a 60 helyett. A túl nagy törzset 413, a túl sok elemet tartalmazó küldést 400 utasítja vissza. Egyenleg feltöltése vagy előfizetés indítása azonnal visszaadja a teljes korlátokat.Az irányítópult API füle mindig a saját szervezetedre érvényes számokat írja ki, és jelzi, ha ezek az ingyenes készletből valók — tehát inkább ott nézd meg, semmint hogy a fenti értékeket feltételezd.

Amin sokan elcsúsznak