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
GETké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.
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 |
|---|---|
Accept | application/json |
User-Agent | YapletBot/1.0 (+https://yaplet.com) |
Signature | A megosztott titkod SHA-256 lenyomata, kisbetűs hexadecimálisan |
Plusz minden további fejléc, amit a forráson beállítottál.
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."]
}
]
}
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.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ő
1001 és az "1001" ugyanaz a termék.http vagy https URL kell legyen, legfeljebb 2048 karakter.Nem kötelező
http vagy https URL."4990 HUF" is jó. Csak akkor használjuk, ha a terméknek nincs variants listája.price. Csak akkor használjuk, ha a terméknek nincs variants listája.variants listája.> 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.A változatobjektum
A variants minden eleme egy dolog, amit a vásárló meg tud venni. Csak az id kötelező.
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.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.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.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" }
}
"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.
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_keysdönti el, mely szabályok vonatkoznak erre a termékre. - A
rulesmondatait az AI szó szerint, minden alkalommal megkapja, amikor ez a termék megjelenik egy válaszban.
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.
A törzs
| Mező | Alapértelmezés | Jelenté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);
curl -X POST "https://yaplet.com/api/products/push/YOUR_SOURCE_ID" \
-H "Content-Type: application/json" \
-H "Y-API-Key: YOUR_API_KEY" \
-d '{
"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"]
}'
$payload = json_encode([
"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"],
]);
$ch = curl_init("https://yaplet.com/api/products/push/YOUR_SOURCE_ID");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"Y-API-Key: YOUR_API_KEY",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode >= 200 && $httpCode < 300) {
$result = json_decode($response, true);
echo "Run: " . $result["run_id"];
} else {
echo "Error " . $httpCode . ": " . $response;
}
import requests
url = "https://yaplet.com/api/products/push/YOUR_SOURCE_ID"
headers = {
"Content-Type": "application/json",
"Y-API-Key": "YOUR_API_KEY",
}
body = {
"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"],
}
response = requests.post(url, headers=headers, json=body)
if response.ok:
result = response.json()
print("Run:", result["run_id"])
else:
print("Error", response.status_code, response.text)
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"
}
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.
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
mergecsak az általad küldött azonosítókhoz nyúl. Minden más érintetlen marad. - A
deleted_idstermé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ó aproductsés adeleted_idslistá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.
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.{"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ód | Mikor |
|---|---|
400 | Hibás JSON, rossz mode, több mint 20 000 elem, vagy üres merge |
401 | Hiányzó vagy érvénytelen Y-API-Key |
403 | A szervezetednek nincs Tartalomforrások jogosultsága |
404 | Ismeretlen forrás, másik szervezet forrása, vagy CSV forrás |
409 | Ehhez a forráshoz épp fut egy másik beolvasás vagy küldés — várj és próbáld újra |
411 | Nincs Content-Length — a darabolt feltöltést nem fogadjuk el |
413 | A törzs nagyobb, mint 25 MB |
429 | Tú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.
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
A termék ahhoz a forráshoz kerül, amelyik utoljára szállította, és elveszíti az előző forrás kulcsait és szabályait. Ne futtass két forrást átfedő azonosítótartományon.
A forráson beállított további fejléceket alkalmazzuk utoljára, így ha egyet Signature, Accept vagy User-Agent névre keresztelsz, az csendben lecseréli a miénket.
A JSON tiltja a vezető nullát a számokban, úgyhogy az ilyen azonosítókat szövegként küldd.
A sikertelen ütemezett beolvasással ellentétben a sikertelen küldés nem számít hibapontnak, és senki nem kap e-mailt. Csak a lekérdező kódod fogja észrevenni.
Egy ellenőrzésen elbukott változat az egész termékét kiveszi a futásból — egy érvénytelen változatot soha nem dobunk el csendben, önmagában. A jelentés ezt „Terméket megállító változatok" néven számolja, és megnevezi az első okot, úgyhogy ezt a számlálót nézd meg, amikor egy biztosan elküldött termék hiányzik.
Megtartjuk azt a sorrendet, ahogy az options mezőt küldöd, tehát a {"Szín": …, "Méret": …} „Szín · Méret" alakban olvasható, a fordítottja pedig „Méret · Szín" alakban. Ha a képernyőn nem a várt sorrend van, az a küldeményed sorrendje.
A változatok nyernek, és a termék árát figyelmen kívül hagyjuk — ez nem hiba, és a pillanatban semmi nem figyelmeztet rá. A futásjelentés „Figyelmen kívül hagyott termékárak (változatokat küldtél)" számlálója az egyetlen jelzés.
Az egész elemet visszautasítjuk, nem vágjuk le. Ha a webshopodnak mély kategóriafái vannak, a végét lapítsd bele az utolsó szintbe küldés előtt.