API PriceZag — Conectează datele despre prețuri la sistemele tale

Folosește API-ul JSON PriceZag pentru a consulta prețurile și stocurile concurenților, a gestiona produsele și regulile de repricing, a descărca rapoarte și a automatiza procesele.

Exemplu rapid cu curl

Știm că dezvoltatorii preferă să vadă întâi cod funcțional. Aceste comenzi creează un produs de test, apoi îl citesc. Înlocuiește MYAPIKEY cu cheia contului tău (vezi Cheie API).
Creează un produs de test:
curl -vX POST 'https://pricezag.com/api/v3/MYAPIKEY' -d '{"actions":[{"a":"productCreate","code":"000-SOME-TEST-PRODUCT","name":"Some Test Product created via PriceZag API","price":12.34,"currency":"USD"}]}'
(dacă execuți comanda a doua oară, vei primi o eroare deoarece produsul există deja)
Acum poți citi acel produs:
curl -X POST 'https://pricezag.com/api/v3/MYAPIKEY' -d '{"actions":[{"a":"productGet","code":"000-SOME-TEST-PRODUCT"}]}' | python -mjson.tool
(elimină | python -mjson.tool dacă nu ai acel instrument pentru formatarea răspunsului JSON în terminal)

Prezentare generală

Ce poți face cu API-ul PriceZag

API-ul JSON PriceZag permite scripturilor și sistemelor tale să lucreze direct cu prețurile și stocurile pe care le monitorizăm. Poți consulta date despre produse, gestiona produse și categorii, calcula sume pe baza regulilor de repricing, configura alerte și descărca foi de calcul personalizate. Poți utiliza API-ul cu orice platformă de comerț electronic sau limbaj de programare capabil să trimită cereri HTTPS și să proceseze JSON.

Poți cere și asistentului tău AI preferat să scrie scripturile pentru tine. Oferă-i URL-ul acestei documentații (https://pricezag.com/integrations/api), explică ce dorești să automatizezi și precizează limbajul de programare sau platforma de comerț electronic folosită. Păstrează cheia API privată și nu o introduce într-o conversație cu un AI.

PriceZag se ocupă de monitorizare în platforma noastră, deci API-ul este opțional. Este util când vrei să conectezi propriile sisteme la aceste date. Shopify și WooCommerce au și integrări directe.

Cheie API și permisiuni

În contul tău PriceZag, deschide Automation > API. Apasă pe Reveal the current API key pentru a vedea cheia actuală sau pe Change the API key pentru a o înlocui. Ambele operații solicită parola contului. Utilizatorul tău trebuie să aibă permisiunile necesare pentru vizualizarea sau generarea cheilor API. În caz contrar, contactează un administrator al contului.

Păstrează cheia API secretă. Aceasta poate permite modificări importante ale datelor contului, inclusiv ștergeri. Nu introduce cheia în depozite publice de cod, în cod executat în browser sau în conversații AI. Dacă cineva te ajută să creezi o integrare, oferă-i un utilizator PriceZag cu permisiunile necesare și schimbă cheia API când este cazul.

Accesul prin API depinde de abonamentul tău. Cu acces complet, scripturile pot lucra cu toate produsele. Fără acesta, API-ul poate accesa doar primele 10 produse, sortate alfanumeric după codul de referință. De exemplu, dacă ai 1.000 de produse cu coduri de la SKU0001 până la SKU1000, API-ul poate accesa produsele de la SKU0001 până la SKU0010. Perioada de testare gratuită de 14 zile include acces complet la API. Poți activa accesul complet și ca opțiune a abonamentului.

Jurnalul activității API și ultima cerere

Pagina Automation > API din contul tău afișează ora ultimei cereri API și un buton API Activity Log. Verifică-le dacă un script nu funcționează: astfel vezi dacă cererile au ajuns la PriceZag și poți investiga erori sau modificări neașteptate.

Modificările făcute prin API apar și în History of Edits din întregul cont, sub numele de utilizator API. De exemplu, în istoricul unui produs poate apărea Price edited by API în loc de Price edited by JOHN. PriceZag permite mai mulți utilizatori în același cont, astfel încât poți distinge modificările automate de cele făcute de membrii echipei.

URL-ul și metodele cererilor

Toate cererile API folosesc același URL HTTPS. Trimite cereri POST la această adresă, înlocuind MYAPIKEY cu cheia ta:

https://pricezag.com/api/v3/MYAPIKEY

Ce dorești să faci cu API-ul ("actions") și parametrii acestora se află în corpul JSON al cererii, nu în URL.
Trimite un obiect JSON cu una sau mai multe acțiuni în corpul cererii POST. URL-ul rămâne exact același indiferent dacă citești un produs, actualizezi prețuri sau descarci o foaie de calcul.

Nu poți trimite POST?
Ca ultimă soluție poți trimite o cerere GET, cu corpul JSON codificat base64 în parametrul URL ?data=. URL-urile au limite de lungime, așadar POST este recomandat.

Cum funcționează acțiunile

Ceea ce numim o acțiune este o operație în contul tău, precum editarea câmpurilor unui produs, modificarea unei reguli de repricing sau citirea prețurilor tuturor concurenților pentru un produs.
API-ul și interfața utilizator (UI) execută aceleași funcții în backend-ul nostru, astfel încât aproape orice operație din interfață poate fi făcută și prin API.
Când trimiți o cerere API, datele JSON conțin un tablou cu toate acțiunile pe care vrei să le execuți, de la 1 la maximum 1.000 per cerere. De exemplu, poți redenumi trei produse și crea o categorie nouă într-o singură cerere cu patru acțiuni. Poți și citi 1.000 de produse simultan, prin 1.000 de acțiuni "productGet".
Acțiunile sunt executate în ordinea din tablou. Dacă creezi o regulă de repricing și apoi îi atribui produse, păstrează această ordine, astfel încât regula să existe când sunt modificate produsele.
Mai jos găsești lista cu toate acțiunile disponibile.

Obiectul JSON al cererii

Pentru scripturi și cod generat de AI: Exemplele din această referință conțin // comentarii și ... marcaje explicative pentru câmpuri. Acestea sunt ilustrative, nu JSON valid care poate fi trimis ca atare. Elimină comentariile și marcajele înainte de trimitere. Cele două exemple curl de mai sus conțin corpuri JSON valide.

Toate datele POST trebuie să formeze un singur obiect JSON {...} care conține tabloul acțiunilor de executat.
{
	"stopOnFailure"	: 1,  // (opțional) În mod normal se continua cu acțiunea urmatoare chiar dacă una eșuează. Folosește 1 pentru oprire.

	// Tablou cu toate acțiunile:
	"actions" : [
		// Acțiunea 1:
		{
			"a"	: "someActionName",  // Numele acțiunii este întotdeauna variabila "a" din fiecare obiect.
			"xx"	: "some parameter this action needs"	// Tot ce este în afara de "a" reprezintă parametrii necesari acțiunii.
		},
		// Acțiunea 2:
		{
			"a"	: "anotherActionName",
			"abc"	: "some parameter this action needs",
			"xyz"	: {"x":"some object this action needs", "y":5, "z":6}
		},
		// Acțiunea 3:
		{
			"a"	: "aThirdAction",
			"xyz"	: ["some array this action needs", "..."]
		}
	]
}

Răspunsul serverului și codurile HTTP

Serverul returnează text/plain pentru erori legate de formatul cererii sau, de exemplu, când contul este dezactivat. În aceste cazuri, textul conține mesajul de eroare.
Dacă cererea este corectă, în mod normal primești un obiect JSON ca răspuns, cu excepția unor acțiuni marcate ca excepții (de exemplu, descărcarea unei foi de calcul). Acest lucru este indicat de antetul de răspuns Content-Type: application/json.
Codul de răspuns HTTP este:
► 200 când toate acțiunile au reușit (rezultatul neutru ok=0 este considerat succes)
► 406 când unele acțiuni au reușit, iar altele au eșuat.
► 422 când toate acțiunile au eșuat, dar nu din motivele de mai jos.
► 400 când obiectul JSON primit nu a putut fi decodat.
► 403 când autentificarea eșuează (de obicei din cauza unei chei API greșite).
Poți folosi aceste coduri de răspuns direct în scripturile tale. Dacă ai nevoie de mai multe detalii, obiectul JSON returnat oferă informații suplimentare:
{
	"ok"		: 15,  // numărul acțiunilor executate cu succes (ok>0)
	"errors"	: 0,  // numărul acțiunilor care au generat o eroare (ok<0)
	"actionsCount"	: 20,  // numărul total de acțiuni solicitate inițial (lungimea tabloului "actions")
	// NOTA: rezulta ca 5 acțiuni au returnat ok=0 (fără eroare, dar fără modificări).
	
	// Tabloul tuturor acțiunilor solicitate (în aceeași ordine):
	"actions" : [
		...
		// Obiectul de răspuns al fiecarei acțiuni:
		{
			"a"	: "someActionName",
			"ok"	: 4,		// Rezultat: >0 = succes, 0 = fără modificări, <0 = eroare
						// De exemplu 0 dacă schimbi prețul unui produs cu același preț.
						// -1 dacă produsul nu există.
						// >0 depinde de acțiune. Adesea este numărul câmpurilor sau elementelor modificate.
			"error"	: "...",  // Mesaj de eroare dacă ok < 0
						// Mesajele noastre de eroare sunt detaliate. Salvează-le în jurnal
						// deoarece contin informațiile necesare pentru diagnosticarea problemei.
			...	// Alte date returnate, specifice acestei acțiuni
		},
		...
	]
}

Exemple?

Uneori exemplele clarifică lucrurile. Consultă mai multe exemple la finalul acestei pagini.

Limite de cereri și programare

Avem un firewall care ne protejează pe noi și pe tine împotriva atacurilor sau a volumelor excesive de cereri. Dacă blochează un host, site-ul nostru poate părea indisponibil: fără conexiune, răspuns sau ping.
Pentru a evita blocarea cererilor legitime:
► Nu utiliza o cheie API greșită; firewall-ul tolerează foarte puține încercări cu chei incorecte (la fel ca parolele greșite pe site).
► Grupează mai multe acțiuni într-o singură cerere și într-un singur obiect JSON (maximum 1.000). Pentru a crea 1.000 de produse, trimite o singură cerere, nu 1.000.
► Dacă ai nevoie de multe cereri, așteaptă 500 ms între ele și reutilizează aceeași conexiune HTTPS. Deschiderea unei conexiuni noi la fiecare cerere este o greșeală frecventă. Un număr mare de cereri se justifică de obicei doar pentru sute de mii de produse, cu 1.000 de acțiuni per cerere.
Nu există o limită fixă a ratei cererilor; firewall-ul nostru decide pe baza a zeci de parametri. Cel mai bine este să folosești bunul-simț.
 
Cereri programate:
Dacă programezi cereri la intervale regulate, adaugă o întârziere aleatorie pentru a le trimite într-o secundă mai puțin obișnuită. Mulți clienți trimit exact la începutul minutului (secunda 0). Astfel reduci întârzierile și riscul de timeout.

Toate acțiunile API disponibile

Fiecare acțiune este documentată mai jos cu parametrii săi și exemple de cereri și răspunsuri. Navigarea din stânga duce direct la fiecare acțiune.

Produse

AcțiuneScop
productCreateCreează un produs nou
productEditEditează un produs existent
productCompetitorsEditează URL-urile concurenților unui produs (fără a le înlocui pe toate)
productCategoriesEditează categoriile unuia sau mai multor produse (fără a le înlocui pe toate)
productRepricingAtribuie multe produse unei reguli de repricing
productDeleteȘterge unul sau mai multe produse
productGetConsultă un produs (și datele concurenților săi)
productGetAllConsultă toate produsele (și datele concurenților lor)

Categorii

AcțiuneScop
categoryCreateCreează o categorie nouă
categoryEditEditează o categorie existentă
categoryDeleteȘterge una sau mai multe categorii
categoryCopyCopiază sau mută produse între categorii
categoryGetConsultă o categorie
categoryGetAllConsultă toate categoriile

Alerte

AcțiuneScop
alertRecipientCreateCreează un destinatar de alerte
alertRecipientEditEditează un destinatar și/sau regulile sale de alertă
alertRecipientDeleteȘterge un destinatar de alerte
alertRuleEditEditează o regulă de alertă existentă
alertRuleCreate ?Această acțiune nu există. Folosește alertRecipientEdit cu un tablou "rulesAdd".
alertRuleDelete ?Această acțiune nu există. Folosește alertRecipientEdit cu un tablou "rulesRemove".
alertGetAllConsultă toți destinatarii și regulile lor de alertă

Reguli de repricing

AcțiuneScop
repricingCreateCreează o regulă de repricing
repricingEditEditează o regulă de repricing existentă
repricingDeleteȘterge o regulă de repricing
repricingGetAllConsultă toate regulile de repricing

Foi de calcul

AcțiuneScop
spreadsheetDownloadDescarcă o foaie de calcul
spreadsheetPresetEditRedenumește sau șterge o presetare pentru foi de calcul
spreadsheetAutoCreateCreează un export automat de foi de calcul
spreadsheetAutoEditEditează un export automat de foi de calcul

Concurenți și altele

AcțiuneScop
competitorDeleteAllȘterge un concurent din toate produsele sau categoriile
mathEditSetează sau editează calculele de preț pentru domeniul unui concurent

Produse

productCreate - Creează un produs nou

Aceasta este aceeași funcție folosită de interfață în pagina New Product.
{ "actions" : [
	...
	{
		"a"		: "productCreate",
		"code"		: "UNIQUE-REF-CODE",  // între 1 și 80 ([a-z\d][a-z\d_-]{0,78}[a-z\d]); fără diferențiere majuscule (convertit la majuscule)
		"name"		: "The Product Name",  // între 1 și 200
		"price"		: 1234.90,  // Atentie la virgule și puncte. Fără separator de mii; zecimalele folosesc punct.
		"currency"	: "USD",
		"cost"		: 1234.90,  // (opțional)
		"costCurrency"	: "USD",  // obligatoriu dacă există cost
		"repricingRule"	: "The Rule Name",  // (opțional) Regulă de repricing atribuita (gol = dezactivat, inexistentă = eroare)
		"myWebsite"	: "https://...",  // (opțional) URL sau shopify:productId:variantId ori woocommerce:productId(:variationId)
		"competitors"	: ["https://...", "https://..."],  // (opțional)
		"categories"	: ["The Category 1", "The Category 2"],  // (opțional) categoriile produsului (cele inexistente sunt create)
		"comments"	: "Some comments\nAnd another line",  // (opțional) maximum 1000 caractere UTF-8
		"custom_someFieldName1"	: "Value of custom field",		// (opțional)
		"custom_someFieldName2"	: "Value of other\nCustom\tField",  // (opțional)
		// Campurile personalizate sunt pentru uz intern. Pot fi folosite în multe locuri, de exemplu drept coloane la exportul unei foi de calcul.
		// Maximum 20 câmpuri personalizate per produs. Nume de max. 40 litere/cifre/underscore (sensibil la majuscule), fără prefixul "custom_" (47 total).
		// Valoarea are max. 500 bytes (de obicei caractere). Poți seta un număr (custom_varname:123),
		// dar returnam mereu șiruri (custom_varname:"123"); converteste valorile dacă este necesar.
		// Pentru a șterge un câmp personalizat, seteaza "". Se aplica în productEdit, nu în productCreate.
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "productCreate",
			"ok"	: 1,
			"code"	: "REF-CODE",  // Codul final în baza de date (putem modifică unele caractere speciale)
		},
		...
	]
}

productEdit - Editează un produs existent

Este aceeași funcție folosită de interfață la editarea unui câmp al produsului. Interfața trimite câte un câmp, dar API-ul permite, de exemplu, modificarea numelui și a prețului printr-un singur apel.
{ "actions" : [
	...
	{
		"a"		: "productEdit",
		"code"		: "REF-CODE",
		...		// Folosește parametrii din productCreate, toți optionali.
		"newCode"	: "REF-CODE-RENAMED",  // (opțional)
		"competitors"	: ["https://...", "https://..."],  // Dacă este furnizat, ÎNLOCUIEȘTE toate URL-urile existente ale concurenților.
		// Dacă vrei doar să adaugi sau să elimini concurenți din lista existentă, folosește în schimb acțiunea productCompetitors.
		"categories"	: ["The Category 1", "The Category 2"],  // Dacă este furnizat, ÎNLOCUIEȘTE categoriile curente. Alternativ folosește productCategories sau categoryEdit.
		"custom_someFieldName"	: "New value or empty to delete that custom field",
		// Maximum 20 câmpuri personalizate per produs. Pentru a adaugă altele, șterge mai întâi unele cu "".
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "productEdit",
			"ok"	: 3,  // Număr de modificări (de ex. prețul meu + 2 URL-uri de concurenți = 3)
			"code"	: "REF-CODE",  // Codul nou final în baza de date (unele caractere speciale pot fi modificate)
		},
		...
	]
}

productCompetitors - Editează URL-urile concurenților unui produs

Editează URL-urile concurenților unui produs fără să le înlocuiești pe toate (spre deosebire de acțiunea productEdit ).
{ "actions" : [
	...
	{
		"a"			: "productCompetitors",
		"code"			: "REF-CODE",
		"competitorsAdd"	: ["https://...", "https://..."],  // (opțional) Adaugă aceste URL-uri de concurenți la cele existente
		"competitorsRemove"	: ["https://...", "example.com/a0ff80...5f00", "example.net"],  // (opțional) Șterge acesti concurenți. Fiecare element poate fi:
		// > URL-ul (inclusiv modificatorul hashtag). Etichetele sunt optionale.
		// > "ref" al concurentului (returnat de alte acțiuni: domeniu rădăcină și md5 de 32 caractere)
		// > Domeniul rădăcină sau hostname-ul complet; toate URL-urile domeniului vor fi eliminate din produs.
		// NOTA: "competitorsAdd" și "competitorsRemove" pot fi și șiruri, nu doar tablouri cu un element.
		// Mai întâi se șterge, apoi se adaugă: poți elimină un domeniu întreg și apoi adaugă un URL de acolo.
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"			: "productCompetitors",
			"ok"			: 3,  // Numărul URL-urilor de concurenți modificate
			"competitorsAdded"	: 2,  // Numărul URL-urilor de concurenți adăugate produsului
			"competitorsRemoved"	: 1,  // Numărul URL-urilor de concurenți șterse din produs
			// ERORI:
			// > Adaugarea unui URL existent NU genereaza eroare (ok = 0)
			// > Ștergerea unui URL sau "ref" inexistent genereaza eroare (ok = -1)
			// > Ștergerea tuturor URL-urilor unui domeniu inexistent NU genereaza eroare (ok = 0)
		},
		...
	]
}

productCategories - Editează categoriile unuia sau mai multor produse

Editează categoriile unuia sau mai multor produse fără să le înlocuiești pe toate (spre deosebire de acțiunea productEdit).
Este aceeași funcție pe care o folosește interfața când accesezi All Products, selectezi unul sau mai multe produse și apeși pe Selected Products > Edit Categories. Poți consulta acea pagină pentru explicații mai detaliate.
Poți consulta și acțiunea categoryEdit pentru a decide care ți se potrivește.
{ "actions" : [
	...
	{
		"a"			: "productCategories",
		"code"			: "REF-CODE",  // nu distinge majuscule (șir), SAU:
		"code"			: ["REF-CODE-1", "REF-CODE-2"],  // poate fi și un tablou cu mai multe produse (maximum 100.000)
		"categoriesRemove"	: ["The Category 1", "The Category 2"],  // (opțional) Mai întâi se elimină din aceste categorii.
		"categoriesRemoveAll"	: 1,  // (opțional) Mai întâi se elimină din toate categoriile (ca productEdit).
		"deleteEmptyCategories"	: 1,  // Astfel, orice categorie care rămâne goala
		// după eliminarea produselor va fi stearsa.
		"categoriesAdd"		: ["The Category 1", "The Category 2"],  // (opțional) Apoi adaugă în aceste categorii (cele inexistente sunt create)
		"categoriesAddClear"	: 1,  // (opțional) Mai întâi goleste categoriile în care sunt adăugate produsele
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "productCategories",
			"ok"	: 3,  // Număr de produse modificate
		},
		...
	]
}

productRepricing - Atribuie multe produse unei reguli de repricing

Atribuie până la 100.000 de produse unei reguli de repricing.
Face același lucru ca acțiunea productEdit, însă fiecare cerere permite cel mult 1.000 de acțiuni. De aceea, pentru 50.000 de produse ar fi necesare 50 de cereri cu productEdit, iar execuția ar fi mult mai lentă.
Dacă vrei să modifici doar câteva produse, poți folosi productEdit în schimb.
{ "actions" : [
	...
	{
		"a"			: "productRepricing",
		"repricingRule"		: "The Rule Name",  // fără diferențiere majuscule; "" (șir gol prezent) inseamna fără regulă (dezactivare repricing)
		"products"		: ["REF-CODE-1", "REF-CODE-2"],  // fără diferențiere majuscule (maximum 100.000)
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"		: "productRepricing",
			"ok"		: 10,  // Număr de produse modificate
			// Dacă toate produsele foloseau deja această regulă, vei primi ok=0.
		},
		...
	]
}

productDelete - Șterge unul sau mai multe produse

AVERTISMENT: produsul și URL-urile concurenților sunt șterse imediat din cont și nu pot fi recuperate.
Este aceeași funcție pe care o folosește interfața când accesezi All Products, selectezi unul sau mai multe produse și apeși pe Selected Products > Delete.
{ "actions" : [
	...
	{
		"a"	: "productDelete",
		"code"	: "REF-CODE",  // nu distinge majuscule (șir), SAU:
		"code"	: ["REF-CODE-1", "REF-CODE-2"],  // poate fi și un tablou pentru a șterge mai multe produse (maximum 100.000)
		"deleteEmptyCategories"	: 1,  // Astfel, orice categorie care rămâne goala
		// astfel sunt șterse și categoriile ramase goale
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "productDelete",
			"ok"	: 2,  // Număr de produse șterse cu succes
		},
		...
	]
}

productGet - Consultă un produs

{ "actions" : [
	...
	{
		"a"			: "productGet",
		"code"			: "REF-CODE",  // fără diferențiere majuscule
		"currency"		: "EUR",  // (opțional) converteste toate sumele în aceasta moneda, nu în moneda produsului
		"withStats"		: 1,  // (opțional) returnează obiectul de statistici
		"noCompetitors"		: 1,  // (opțional) nu returna tabloul concurenților (răspuns mai mic)
		"noComments"		: 1,  // (opțional) nu returna comentariile (...)
		"withScreenshots"	: 1,  // (opțional) returnează URL-ul ultimei capturi pentru fiecare concurent
		"sickMax"		: 2,  // (opțional, implicit 1) 0-3; returnează doar URL-urile cu nivel de eroare până la N
	},
	...
] }
Returnează toate informațiile despre un produs, inclusiv prețurile și stocurile actuale ale concurenților.
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"			: "productGet",
			"ok"			: 1,
			"code"			: "REF-CODE",
			"name"			: "The Product Name",
			"price"			: 1234.90,  // Prețul tău, întotdeauna în moneda originală
			"currency"		: "USD",  // Moneda originală pentru "price"
			"convCurrency"		: "EUR",  // Moneda pentru sumele convertite ("currency" furnizată sau moneda produsului)
			"priceConv"		: 1234.90,  // Prețul propriu convertit în "convCurrency", sau egal cu "price"
			"cost"			: 1234.90,
			"costCurrency"		: "USD",
			"costPriceConv"		: 1234.90,  // Costul propriu convertit în moneda "currency"
			"costConv"		: 1234.90,  // Costul propriu convertit în "convCurrency"
			"margin"		: 10.5,  // Procent (poate fi negativ)
			"repricingRule"		: "The Rule Name",  // Aceste 3 variabile de repricing LIPSESC dacă nu există repricing.
			"reprice"		: 1234.90,  // Sumă curenta de repricing calculata după repricingRule
			"repriceCurrency"	: "USD",  // Identic cu "convCurrency", doar pentru claritate
			"myWebsite"		: "https://...",
			"created"		: 1234567890,  // Timp Epoch cand a fost creat produsul
			"createdBy"		: "SOMEUSER",  // Numele utilizatorului sau "API"
			"edited"		: 1234567890,  // Timp Epoch al ultimei editari (dacă există)
			"editedBy"		: "SOMEUSER",  // Numele utilizatorului sau "API"
			"comments"		: "Some comments\nAnd another line",
			"commentsLast"		: 1234567890,  // Timp Epoch al ultimei editari a comentariilor (dacă există)
			"commentsLastBy"	: "SOMEUSER",  // Numele utilizatorului sau "API"
			"categories"		: ["The Category 1", "The Category 2"],
			"stats"		: {
				// Doar URL-urile concurenților cu nivel 0 sau 1 conteaza în statistici, indiferent de "sickMax".
				// Toate sumele sunt în "convCurrency", adica "currency" furnizată sau moneda originală a produsului.
				// AVERTISMENT: dacă nu există sumă (de ex. compIn* fără concurenți cu stoc), valoarea este 0.
				"rank"			: 1.23,  // Poziția ta la preț (1 = nimeni sub tine)
				"rankIn"		: 1.23,  // Poziția ta între concurenții cu stoc
				"compCount"		: 3,  // Număr concurenți cu preț valid
				"compInCount"		: 3,  // Număr concurenți cu stoc ...
				"compOutCount"		: 3,  // Număr concurenți fără stoc ...
				"compAvg"		: 123.56,  // Media tuturor concurenților
				"compAvgVsMe"		: 123.56,  // Diferenta (în convCurrency) între prețul tău și medie (negativ = esti mai ieftin)
				"compInAvg"		: 123.56,  // Media concurenților cu stoc
				"compInAvgVsMe"		: 123.56,  // Ca "compAvgVsMe", dar doar cu stoc
				"compLowest"		: 123.56,  // Cel mai ieftin concurent
				"compLowestVsMe"	: 123.56,  // Ca "compAvgVsMe", dar cu minimul, nu media
				"compInLowest"		: 123.56,  // Cel mai ieftin concurent cu stoc
				"compInLowestVsMe"	: 123.56,  // Ca "compInAvgVsMe", dar ...
				"compHighest"		: 123.56,  // Cel mai scump concurent
				"compHighestVsMe"	: 123.56,  // Ca "compAvgVsMe", dar ...
				"compInHighest"		: 123.56,  // Cel mai scump concurent cu stoc
				"compInHighestVsMe"	: 123.56,  // Ca "compInAvgVsMe", dar ...
			},
			"competitors"	: [
				// Tablou de concurenți (cel mai ieftin primul), fiecare fiind un obiect:
				...
				{
					"url"		: "https://...",  // Include orice modificator hashtag
					"ref"		: "example.com/123abc...def",
					// Referinta URL (domeniu rădăcină + md5 de 32 caractere); așa identificam intern URL-urile.
					"domain"	: "example.com",  // Domeniul rădăcină al acestui concurent
					"price"		: 1234.90,  // Ultima sumă găsită (după calculele configurate)
					"currency"	: "USD",  // Moneda găsită pe site
					"priceConv"	: 1234.90,  // Preț convertit în "convCurrency"
					"stock"		: "5",  // Stoc (șir). "A" = disponibil, "2" = 2 bucăți, "0" = epuizat, "" = necunoscut.
					"salesWk"	: 123,  // vânzări estimate pe săptămână (dacă există date; vezi ajutorul din pagina produsului)
					"screenshotURL"	: "https://pricezag.com/.../screenshot.png",
					// dacă "withScreenshots", URL-ul ultimei capturi (accesibil fără autentificare prin linkul lung)
					"confidence"	: 98,
					// Procent de încredere în prețul detectat (vezi (?) în pagina produsului)
					// Sub 70% (configurabil) marcam prețul ca "nesigur" cu un semn de întrebare.
					// Este independent de nivelul de eroare. URL-ul poate esua acum, deși ultimul preț era corect,
					// sau poate functiona, dar fără sa fim siguri ca prețul detectat este corect.
					"sick"		: 0,  // Nivelul de eroare al URL-ului: de la 0 la 3
					// 0: ultima vizita reușită (pagina incarcata și preț găsit)
					// 1: ultima vizita esuata, dar reușită recent (lucru obisnuit)
					// 2: nu avem preț valid de mai multe zile
					// 3: nu avem preț valid de mai multe săptămâni
					// NOTA: "price" și "priceConv" apar numai pentru URL-uri cu nivel <=1. Nivelurile 2 și 3 nu au preț.
				},
				...
			],
			"custom"	: {
				// Acestea sunt câmpurile tale personalizate. Pentru explicatii deschide
				// un produs în interfata și apasa pe (?) langa CUSTOM FIELDS.
				// Dacă nu există câmpuri personalizate, obiectul "custom" lipseste.
				"variable_1"	: "value 1",  // Valorile sunt mereu șiruri, chiar și cand reprezintă numere.
				"variable_2"	: "value 2",  // Nu există valoare goala: aceasta ar șterge variabila.
				...
			}
		},
		...
	]
}

productGetAll - Consultă toate produsele

Asigură-te că setările de timeout sunt suficient de mari: serverul poate avea nevoie de timp în funcție de numărul de produse și concurenți.
{ "actions" : [
	...
	{
		"a"			: "productGetAll",
		"currency"		: "EUR",  // (opțional) converteste sumele în aceasta moneda, nu în moneda fiecarui produs
		"withStats"		: 1,  // (opțional) returnează obiectul de statistici
		"noCompetitors"		: 1,  // (opțional) nu returna tabloul concurenților (răspuns mai mic)
		"noComments"		: 1,  // (opțional) nu returna comentariile (...)
		"withScreenshots"	: 1,  // (opțional) returnează URL-ul ultimei capturi pentru fiecare concurent
		"sickMax"		: 2,  // (opțional, implicit 1) 0-3; returnează doar URL-urile cu nivel de eroare până la N
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"		: "productGetAll",
			"ok"		: 10,  // Numărul total de produse
			"products"	: [ // Tablou de produse (ordine alfabetică după cod), fiecare produs fiind un obiect:
				...
				{ ... },  // Obiect de produs, la fel ca cel returnat de acțiunea productGet (imediat mai sus)
				...
			],
		},
		...
	]
}
Te-ar putea interesa și acțiunea categoryGet .

Categorii

categoryCreate - Creează o categorie nouă

Aceasta este aceeași funcție folosită de interfață în pagina Categories când apeși pe butonul New Category, dar prin API poți atribui produse chiar în momentul creării categoriei.
Spre deosebire de alte acțiuni care acceptă categorii noi sau existente (de exemplu, productCreate), această acțiune eșuează dacă o categorie există deja.
{ "actions" : [
	...
	{
		"a"		: "categoryCreate",
		"name"		: "The New Category Name",
		"name"		: ["New Category 1", "New Category 2"],  // poate fi și un tablou
		"products"	: ["REF-CODE-1", "REF-CODE-2"],  // (opțional) Pune aceste produse în categorii la creare
		"comments"	: "Some comments\nAnd another line",  // (opțional) maximum 1000 caractere UTF-8
	},
	...
] }

categoryEdit - Editează o categorie existentă

Poți consulta și acțiunea productCategories pentru a decide care ți se potrivește.
{ "actions" : [
	...
	{
		"a"			: "categoryEdit",
		"name"			: "The Category Name",		// fără diferențiere majuscule
		"newName"		: "The Category Renamed",  // (opțional)
		"products"		: ["REF-CODE-1", "REF-CODE-2"],  // (opțional) Înlocuiește lista de produse
		"productsAdd"		: ["REF-CODE-1", "REF-CODE-2"],  // (opțional) Adaugă produsele în categorie
		"productsRemove"	: ["REF-CODE-3", "REF-CODE-4"],  // (opțional) Scoate produse din categorie (NU le șterge)
		"comments"		: "To overwrite the comments.",  // (opțional) maximum 1000 caractere UTF-8
	},
	...
] }
Așadar, "products", "productsAdd" și "productsRemove" au același scop: modifică produsele categoriei, dar în moduri diferite. Pentru a elimina toate produsele, folosește "products" : []
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"			: "categoryEdit",
			"ok"			: 5,  // Numărul modificărilor
			// (redenumirea și editarea comentariilor conteaza cate 1; la fel fiecare produs adaugat/scos)
			"name"			: "The Category Name",  // numele nou dacă s-a redenumit, altfel numele vechi
			"productsCount"		: 30,  // Numărul nou de produse din categorie (indiferent dacă s-a modificat)
			"productsAdded"		: 2,  // Numărul produselor adăugate în categorie
			"productsRemoved"	: 2,  // Numărul produselor scoase din categorie
		},
		...
	]
}

categoryDelete - Șterge una sau mai multe categorii

Este aceeași funcție pe care o folosește interfața când accesezi Categories, selectezi categoriile respective și apeși pe Selected Categories > Delete.
{ "actions" : [
	...
	{
		"a"			: "categoryDelete",
		"name"			: "The Category Name",  // nu distinge majuscule (șir), SAU:
		"name"			: ["Category 1", "Category 2"],  // poate fi și un tablou pentru a șterge mai multe categorii (maximum 1000)
		"deleteProducts"	: 1,
		// Implicit se șterge categoria, dar produsele ei rămân,
		// dar cu deleteProducts toate produsele categoriei sunt șterse fără confirmare,
		// iar URL-urile concurentilor sunt șterse impreuna cu ele, fără recuperare!
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"			: "categoryDelete",
			"ok"			: 2,  // Numărul categoriilor șterse
			"productsCount"		: 123,  // Numărul produselor afectate de aceste categorii
			"productsDeleted"	: 123,  // Numărul produselor șterse prin optiunea "deleteProducts"
			// NOTA: un produs care se afla în mai multe categorii specificate se numără o singura data
		},
		...
	]
}

categoryCopy - Copiază sau mută produse între categorii

Copiază sau mută produse din categorii în alte categorii, noi sau existente. Poți și să COMBINI categorii (vezi exemplele de la final).
Această operație nu șterge produse: doar le mută între categorii.
Este aceeași funcție pe care o folosește interfața când accesezi Categories, selectezi categoriile respective și apeși pe Selected Categories > Copy & More. Poți consulta acea pagină pentru explicații mai detaliate.
{ "actions" : [
	...
	{
		"a"			: "categoryCopy",
		"categoriesFrom"	: ["Category 1", "Category 2"],  // Selectează produsele din aceste categorii (sursa)
		"removeMode"		: "cat",  // (opțional) Scoate produsele corespunzătoare din "categoriesFrom" furnizate
		"removeMode"		: "all",  // (opțional) Scoate produsele corespunzătoare din toate categoriile lor
		// Fără removeMode produsele rămân în "categoriesFrom" și sunt adăugate la "categoriesTo" (copiere, nu mutare)
		"deleteMode"		: "cat",  // (opțional) Șterge categoriile "categoriesFrom" după copiere
		"deleteMode"		: "all",  // (opțional) Șterge toate categoriile din care fac parte produsele
		// Fără deleteMode, "categoriesFrom" rămân existente chiar dacă removeMode a scos produsele.
		"categoriesTo"		: ["Another Category 1", "Another Category 2"],
		// Pune toate produsele potrivite în aceste categorii destinatie (cele inexistente sunt create)
		"categoriesToClear"	: 1,  // (opțional) Mai întâi goleste categoriile în care sunt adăugate produsele
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"			: "categoryCopy",
			"ok"			: 3,  // Numărul categoriilor modificate (sursa și destinatie)
			// "ok" este sumă categoriesModified + categoriesCreated + categoriesDeleted
			"categoriesModified"	: 2,  // Numărul categoriilor existente modificate (sursa și destinatie)
			"categoriesCreated"	: 1,  // Numărul categoriilor nou create
			"categoriesDeleted"	: 0,  // Numărul categoriilor șterse prin "deleteMode"
			"productsCount"		: 123,  // Numărul produselor din "categoriesFrom" furnizate
			// NOTA: un produs în mai multe "categoriesFrom" se numără o singura data
		},
		...
	]
}

categoryGet - Consultă o categorie

{ "actions" : [
	...
	{
		"a"		: "categoryGet",
		"name"		: "The Category Name",  // fără diferențiere majuscule
		"currency"	: "EUR",  // (OBLIGATORIU dacă withStats sau withProducts) moneda pentru statistici
		"withStats"	: 1,  // returnează și statisticile (mai lent)
		"withProducts"	: 1,  // returnează și produsele categoriei (poate genera multe date)
		"noCompetitors"	: 1,  // dacă withProducts, nu returna tabloul concurenților (mai putine date)
		"noComments"	: 1,  // dacă withProducts, nu returna comentariile produselor (cele ale categoriei rămân)
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"			: "categoryGet",
			"ok"			: 1,
			"name"			: "The Category Name",
			"created"		: 1234567890,  // Timp Epoch
			"createdBy"		: "SOMEUSER",  // Numele utilizatorului sau "API"
			"comments"		: "Comments of this category",
			"commentsLast"		: 1234567890,  // Timp Epoch al ultimei editari a comentariilor (dacă există)
			"commentsLastBy"	: "SOMEUSER",  // Numele utilizatorului sau "API"
			"productsCount"		: 10,  // Numărul produselor din categorie
			"stats"		: {
				// Aceste statistici apar în pagina categoriei și în coloanele listei de categorii.
				// Pentru detalii, selectează-le ca o coloana în lista categoriilor și apasa (?).
				// Toate sumele sunt în "currency" furnizată în cerere.
				// AVERTISMENT: dacă nu există sumă (de ex. compIn* fără concurenți cu stoc), valoarea este 0.
				"priceAvg"		: 123.45,  // Media prețului tău propriu
				"costAvg"		: 123.45,  // Doar produsele cu cost participa la aceasta medie
				"marginAvg"		: 10.5,  // Procent (poate fi negativ; numai produse cu cost)
				"rankAvg"		: 1.23,  // Poziția ta medie după preț (1 = nimeni nu este sub tine)
				"rankInAvg"		: 1.23,  // Poziția ta medie între concurenții cu stoc
				"productsCountComp"	: 9,  // Numărul produselor cu concurenți
				"productsCountCompIn"	: 7,  // Numărul produselor cu concurenți în stoc
				"compAvg"		: 123.56,  // Media mediilor tuturor concurenților
				"compAvgVsMe"		: 123.56,  // Diferenta medie (în currency) între prețul tău și concurenți (negativ = esti mai ieftin)
				"compInAvg"		: 123.56,  // Ca "compAvg", dar doar concurenți cu stoc
				"compInAvgVsMe"		: 123.56,  // Ca "compAvgVsMe", dar doar cu stoc
				"compLowest"		: 123.56,  // Ca "compAvg", dar media celui mai ieftin concurent pentru fiecare produs
				"compLowestVsMe"	: 123.56,  // Ca "compAvgVsMe", dar ...
				"compInLowest"		: 123.56,  // Ca "compInAvg", dar ...
				"compInLowestVsMe"	: 123.56,  // Ca "compInAvgVsMe", dar ...
				"compHighest"		: 123.56,  // Ca "compAvg", dar media celui mai scump concurent pentru fiecare produs
				"compHighestVsMe"	: 123.56,  // Ca "compAvgVsMe", dar ...
				"compInHighest"		: 123.56,  // Ca "compInAvg", dar ...
				"compInHighestVsMe"	: 123.56,  // Ca "compInAvgVsMe", dar ...
			},
			"products"	: [ // Tablou de produse (ordine alfabetică după cod), fiecare produs fiind un obiect:
				...
				{ ... },  // Obiect de produs, la fel ca cel returnat de acțiunea productGet
				...
			],
		},
		...
	]
}

categoryGetAll - Consultă toate categoriile

Spre deosebire de categoryGet, acțiunea categoryGetAll nu returnează detaliile complete ale fiecărui produs. Același produs poate aparține mai multor categorii, ceea ce ar genera multe date redundante. Pentru aceste detalii, folosește categoryGet pentru fiecare categorie ori productGetAll și apoi grupează rezultatele după categorii.
{ "actions" : [
	...
	{
		"a"		: "categoryGetAll",
		"withStats"	: 1,  // returnează și statisticile (mai lent)
		"noComments"	: 1,  // nu returna comentariile (mai putine date)
		"noProducts"	: 1,  // nu returna tabloul produselor (...)
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"		: "categoryGetAll",
			"ok"		: 10,  // Total categorii (lungimea tabloului "categories")
			"categories"	: [ // Tablou de categorii (ordine alfabetică), fiecare un obiect:
				...
				{
					"name"			: "The Category Name",
					"created"		: 1234567890,  // Timp Epoch
					"createdBy"		: "SOMEUSER",  // Numele utilizatorului sau "API"
					"comments"		: "Comments of this category",
					"commentsLast"		: 1234567890,  // Timp Epoch al ultimei editari a comentariilor (dacă există)
					"commentsLastBy"	: "SOMEUSER",  // Numele utilizatorului sau "API"
					"productsCount"		: 2,  // Numărul produselor din categorie
					"products"	: ["REF-CODE-1", "REF-CODE-2"],  // Codurile produselor (ordine alfabetică), cu exceptia noProducts=1
					"stats"		: {
						// Dacă este folosit "withStats", același obiect de statistici ca în acțiunea categoryGet (imediat mai sus)
						...
					},
				}
				...
			],
		},
		...
	]
}

Alerte

alertRecipientCreate - Creează un destinatar de alerte

Este aceeași funcție pe care o folosește interfața când accesezi Alerts și apeși pe butonul New Recipient.
Apasă pe pictogramele verzi cu semn de întrebare din cont pentru detalii despre fiecare câmp.
{ "actions" : [
	...
	{
		"a"		: "alertRecipientCreate",
		"email"		: "john@example.net",  // poate fi și număr de telefon pentru alerte SMS; vezi ajutorul din UI
		"name"		: "john",  // Nume afisat simplu (de obicei prenume; fără diferențiere majuscule)
		"maxFrequency"	: 1800,  // (opțional, implicit 7200) vezi ajutorul din UI
		"simplify"	: 0,  // (opțional, implicit 1) Activează simplificarea (vezi UI)
		"sleepEnabled"	: 1,  // (opțional) Activează perioada de odihna
		"sleepFrom"	: "18:30",  // (numai dacă sleepEnabled) format 24 ore
		"sleepTo"	: "07:00",  // (numai dacă sleepEnabled) format 24 ore
		"timezone"	: "America/Los_Angeles",  // (numai dacă sleepEnabled) calea Linux /usr/share/zoneinfo
				// Spațiile sunt convertite în underscore.
				// Găsește fusul orar în formularul [New Recipient] din UI pentru numele exact.
		"status"	: "hold",  // (opțional) "hold" sau "disable". Orice altă valoare (precum "") este activa.
		"rules"		: [...],  // (opțional) Reguli inițiale pentru alerte (tablou de obiecte de regulă), ca "rulesAdd" în alertRecipientEdit de mai jos
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "alertRecipientCreate",
			"ok"	: 1,
		},
		...
	]
}

alertRecipientEdit - Editează un destinatar și/sau regulile sale de alertă

Este aceeași funcție pe care o folosește interfața când accesezi Alerts și apeși pe butonul Settings sau Rules pentru destinatar.
Apasă pe pictogramele verzi cu semn de întrebare din cont pentru detalii despre fiecare câmp.
Pagina "email" determină ce destinatar va fi actualizat. Celelalte câmpuri îi modifică setările.
{ "actions" : [
	...
	{
		"a"		: "alertRecipientEdit",
		"email"		: "john@example.net",  // Adresa de email sau numărul de telefon actual (exact în formatul returnat de acțiunea alertGetAll)
		"newEmail"	: "john2@example.net",  // (opțional) Email sau telefon nou; vezi ajutorul UI
		"name"		: "john2",  // (opțional) Nume nou
		"maxFrequency"	: 1800,  // (opțional) vezi ajutorul din UI
		"simplify"	: 1,  // (opțional) Activează simplificarea (vezi UI)
		"sleepEnabled"	: 1,  // (opțional) Activează perioada de odihna
		"sleepFrom"	: "18:30",  // (numai dacă sleepEnabled) format 24 ore
		"sleepTo"	: "07:00",  // (numai dacă sleepEnabled) format 24 ore
		"timezone"	: "America/Los_Angeles",  // (numai dacă sleepEnabled) vezi acțiunea alertRecipientCreate de mai sus
		"status"	: "hold",  // (opțional) "hold" sau "disable". Orice altă valoare (precum "") devine "active".
		"rules"		: [{ruleObject}, {ruleObject}],  // (opțional) Înlocuiește toate regulile (tablou gol pentru a le elimină pe toate)
				  // Nu furniza tabloul "rules" dacă vrei sa păstrezi regulile existente
		"rulesAdd"	: [ // (opțional) Adaugă aceste reguli la cele existente
			...
			{  // ACESTA ESTE FORMATUL OBIECTULUI DE REGULA:
				"name"		: "me_cross_avg",  // mergi la Alerts > [Rules] > [+ New Rule] și selectează o regulă pentru numele ei API
				"disabled"	: 1,  // (opțional) Nu prea are sens să creezi o regulă dezactivată, dar acțiunea alertRuleEdit de mai jos poate folosi această opțiune
				"var_n"		: 123.00,  // O variabila "X" devine "var_x",
				"var_c"		: "USD",  // ... deci oferă parametrii de care are nevoie regula,
				"var_h"		: 24,  // ... unele reguli nu au variabile.
				"direction"	: "both",  // Sau "drop" ori "rise" dacă regula are direcție
				"categories"	: ["The Category 1", "The Category 2"],  // (opțional) Gol sau omis inseamna TOATE PRODUSELE
				"ignoreOos"	: 1,  // (opțional) Ignora concurenții fără stoc (vezi UI)
				"urlInclude"	: "",  // (opțional, fără diferențiere majuscule)
				"urlExclude"	: "amazon",  // (opțional, fără diferențiere majuscule)
				// "ruleNumber" identifică fiecare regulă (de exemplu, pentru editare sau ștergere).
				// Il vei vedea cand citesti regulile, dar nu il poți seta.
			}
			...
		],
		"rulesRemove"	: [1,4,7],  // (opțional) "ruleNumber" al regulilor de eliminat
					// Vei obține acest "ruleNumber" din acțiunea alertGetAll de mai jos.
					// NOTA: pentru a elimină toate regulile folosește "rules" = [].
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "alertRecipientEdit",
			"ok"	: 3,  // Număr de modificări (variabile și reguli adăugate/șterse)
		},
		...
	]
}

alertRecipientDelete - Șterge un destinatar de alerte

Ștergerea este definitivă. Toate regulile și istoricul acelui destinatar sunt șterse imediat și nu pot fi recuperate.
{ "actions" : [
	...
	{
		"a"		: "alertRecipientDelete",
		"email"		: "john@example.net",  // Adresa de email sau numărul de telefon actual (exact în formatul returnat de acțiunea alertGetAll)
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "alertRecipientDelete",
			"ok"	: 1,
		},
		...
	]
}

alertRuleEdit - Editează o regulă de alertă existentă

Permite modificarea unei reguli de alertă existente fără a înlocui sau adăuga altele. De exemplu, poți schimba variabila N sau activa/dezactiva regula.
Pentru a șterge o regulă, folosește tabloul "rulesRemove" al acțiunii alertRecipientEdit ; pentru a adăuga una nouă, folosește tabloul "rulesAdd".
{ "actions" : [
	...
	{
		"a"		: "alertRuleEdit",
		"email"		: "john@example.net",  // Adresa de email sau numărul de telefon al destinatarului (exact în formatul returnat de acțiunea alertGetAll)
		"ruleNumber"	: 1,  // Numărul de referință al regulii de modificat, returnat de acțiunea alertGetAll de mai jos.
		"rule"		: {
			// Variabilele regulii care trebuie suprascrise. Vezi "rulesAdd" din alertRecipientEdit de mai sus pentru FORMATUL OBIECTULUI DE REGULĂ.
			"disabled"	: 1,  // de exemplu activarea sau dezactivarea regulii
			"var_n"		: 5,  // sau altă variabila, precum N, după tipul regulii
			...
		},
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "alertRuleEdit",
			"ok"	: 1,  // Numărul variabilelor modificate
		},
		...
	]
}

alertGetAll - Consultă toți destinatarii și regulile lor de alertă

{ "actions" : [
	...
	{
		"a"	: "alertGetAll",
		// Aceasta acțiune nu are parametri
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"		: "alertGetAll",
			"ok"		: 3,  // Număr destinatari (lungimea tabloului "recipients")
			"recipients"	: [ // Tablou cu toți destinatarii, fiecare reprezentat de un obiect ca în acțiunea alertRecipientCreate de mai sus
				...
				{
					"email"		: "john@example.net",
					"name"		: "john",
					"maxFrequency"	: 1800,
					"simplify"	: 0,
					"sleepEnabled"	: 1,
					"sleepFrom"	: "18:30",
					"sleepTo"	: "07:00",
					"timezone"	: "America/Los_Angeles",
					"status"	: "active",
					"rules"		: [ // Tablou de reguli, fiecare reprezentată de un obiect descris în acțiunea alertRecipientEdit de mai sus
						...
						{
							"ruleNumber"	: 4,  // Numărul de referință folosit pentru a modifica această regulă prin acțiunea alertRuleEdit de mai sus
							"name"		: "me_cross_avg",
							"disabled"	: 0,
							"var_n"		: "123.00",  // NOTA: toate variabilele sunt returnate ca șiruri, chiar și numerele
							"var_c"		: "USD",
							"var_h"		: "24",
							"direction"	: "both",
							"categories"	: [],  // gol inseamna toate produsele
							"ignoreOos"	: 0,
							"urlInclude"	: "",
							"urlExclude"	: "amazon",
						}
						...
					],
				}
				...
			],
		},
		...
	]
}

Reguli de repricing

repricingCreate - Creează o regulă de repricing

Este aceeași funcție pe care o folosește interfața când accesezi Repricing și apeși pe butonul New Repricing Rule.
Apasă pe pictogramele verzi cu semn de întrebare din cont pentru detalii despre fiecare câmp.
Cum atribui produse regulii? Editează produsele prin acțiunea productEdit sau productRepricing . O regulă nu conține produse: fiecare produs face referire la regula pe care o utilizează.
{ "actions" : [
	...
	{
		"a"	: "repricingCreate",
		"name"	: "The Rule Name",  // maximum 50 caractere
		"init"	: { // obiect inițial (primul rând "Setează prețul meu la")
			"target"	: "cheapest_n",  // (vezi lista de mai jos)
			"var_n"		: 3,  // doar dacă țintă necesită variabila N
			"plusAmount"	: -2,  // pozitiv: deasupra; negativ: dedesubt
			"plusCurrency"	: "%",  // moneda (de ex. "USD") sau "%"
			// Corespunde la "Setează prețul meu cu 2% sub media celor mai ieftini 3 concurenți"
			// AVERTISMENT: Spre deosebire de obiectele "never", initializarea nu are "direction". Semnul lui "plusAmount" determina deasupra/dedesubt.
		},
		"never"	: [ // (opțional) obiecte "but never" executate în ordine (maximum 10)
			{
				"target"	: "cheapest_n_in",  // (vezi lista de mai jos)
				"var_n"		: 1,  // doar dacă țintă necesită variabila N
				"direction"	: "below",  // sau "above"
				"plusAmount"	: -10,  // pozitiv: plus; negativ: minus (obligatoriu chiar dacă 0)
				"plusCurrency"	: "USD",  // moneda sau "%" (obligatoriu chiar dacă plusAmount=0)
				// Corespunde la "Dar niciodată sub prețul celui mai ieftin concurent cu stoc, minus 10,00 USD"
			},
			{
				"target"	: "cost",
				"direction"	: "below",
				"plusAmount"	: 5,
				"plusCurrency"	: "%",
				// Corespunde la "Dar niciodată sub costul meu plus 5%"
			}
		],
		"ignoreDomains"	: "amazon ebay.com MyLabel1",  // (opțional) domenii/etichete de ignorat (fără diferențiere majuscule; vezi UI)
		"charm"		: "none|zeros|charm",  // (opțional, implicit "none") prețuri psihologice ("", "none" sau omis sunt identice)
		"confidence"	: 82,  // (opțional, implicit 70) încredere minimă 0-99% (vezi UI)
		"disabled"	: 1,  // (opțional)
	},
	...
] }
// ========== Siruri "target" disponibile: ==========
// "average" : Media tuturor concurenților
// "average_in" : Media concurenților cu stoc
// "cheapest_n" : Media celor N concurenți mai ieftini (sau cel mai ieftin dacă N=1)
// "cheapest_n_in" : Media celor N concurenți mai ieftini cu stoc (sau ...)
// "highest_n" : Media celor N concurenți mai scumpi (sau ...)
// "highest_n_in" : Media celor N concurenți mai scumpi cu stoc (sau ...)
// "cost" : Costul meu
// "me_avg_n" : Prețul meu mediu din ultimele N ore (limitează viteza schimbărilor)
// "domain:example.com" : prețul example.com (minimul dacă sunt mai multe URL-uri)
// "domainIn:example.com" : prețul example.com doar dacă există stoc (...)
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "repricingCreate",
			"ok"	: 3,  // Numărul obiectelor procesate și salvate (de ex. init + never[0] + never[1] = 3)
			"name"	: "The Rule Name",  // Numele final în baza de date (anumite caractere speciale pot fi modificate)
		},
		...
	]
}

repricingEdit - Editează o regulă de repricing existentă

Modifică o regulă de repricing existentă.
Consultă repricingCreate mai sus pentru a înțelege aceste variabile.
Modifică regula, nu produsele care o folosesc. Pentru a atribui produse, utilizează productEdit sau productRepricing în schimb.
{ "actions" : [
	...
	{
		"a"		: "repricingEdit",
		"name"		: "The Rule Name",  // fără diferențiere majuscule
		"newName"	: "The Rule Renamed",  // (opțional) maximum 50 caractere
		"init"		: { // (opțional) Dacă este furnizat, înlocuiește variabilele initializarii (vezi repricingCreate)
			"plusAmount"	: 1,  // de ex. schimbi doar "plusAmount" și păstrezi celelalte variabile
			// AVERTISMENT: dacă noul "target" necesită variabila N, trebuie sa furnizezi "var_n"
		},
		"never"		: [...], // (opțional) Poți înlocui intregul tablou "never", dar de obicei este preferabil never_*
		// "never":[] șterge toate conditiile. Omite variabila pentru a le păstra.
		"never_0"	: { // (opțional) înlocuiește primul obiect "but never" (index 0)
			"var_n"		: 2,  // de ex. schimbi doar "var_n" și păstrezi celelalte variabile
		},
		"never_2"	: {
			"target"	: "",  // dezactiveaza a treia condiție "but never" (index 2)
			// Nu trebuie sa te preocupi de alte variabile dacă "target" este "".
			// "never_2":{} face același lucru
		},
		"never_6"	: {...}, // Poate fi o condiție nouă "but never"; necesită toate variabilele ca în repricingCreate
		// "never_9" este maximul; tabloul "never" permite până la 10 elemente
		"ignoreDomains"	: "",  // (opțional) ca repricingCreate
		"charm"		: "zeros",  // (opțional) ...
		"confidence"	: 82,  // (opțional) ...
		"disabled"	: 1,  // (opțional) 0 pentru activarea unei reguli dezactivate
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "repricingEdit",
			"ok"	: 3,  // Numărul modificărilor (de ex. variabila din never_N, una din "init" și "charm")
			"name"	: "The Rule Name",  // Numele nou final în baza de date (unele caractere speciale pot fi modificate)
		},
		...
	]
}

repricingDelete - Șterge o regulă de repricing

Ștergerea este definitivă. Regula este ștearsă imediat și nu poate fi recuperată. Produsele care o foloseau rămân fără regulă și repricing-ul lor nu va mai funcționa.
{ "actions" : [
	...
	{
		"a"		: "repricingDelete",
		"name"		: "The Rule Name",  // fără diferențiere majuscule
		"onlyIfUnused"	: 1,  // (opțional) Pentru siguranță, generează o eroare dacă există produse care folosesc această regulă
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"		: "repricingDelete",
			"ok"		: 1,
			"productsCount"	: 10,  // Numărul produselor care foloseau această regulă (acum fără regulă)
		},
		...
	]
}

repricingGetAll - Consultă toate regulile de repricing

Consultă mai întâi repricingCreate mai sus, deoarece formatul răspunsului este foarte asemănător cu cel trimis către repricingCreate.
{ "actions" : [
	...
	{
		"a"	: "repricingGetAll",
		// Aceasta acțiune nu necesită alti parametri
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "repricingGetAll",
			"ok"	: 10,  // Numărul total de reguli (lungimea lui "rules")
			"rules"	: [ // Tablou de reguli de repricing (ordine alfabetică), fiecare ca obiect:
				...
				{
					"name"		: "Some Repricing Rule",
					"created"	: 1234567890,  // Timpul Epoch când a fost creată regula
					"createdBy"	: "SOMEUSER",  // Numele utilizatorului sau "API"
					"edited"	: 1234567890,  // Ultima editare (dacă există, altfel variabila lipseste)
					"editedBy"	: "SOMEUSER",  // Utilizator sau "API" (sau absent)
					"disabled"	: 1234567890,  // Dacă regula este dezactivată: timp Epoch al ultimei dezactivări; altfel absent.
					"disabledBy"	: "SOMEUSER",  // Utilizator sau "API" (sau absent)
					"productsCount"	: 10,  // Numărul produselor care folosesc acum această regulă
					"ignoreDomains"	: "amazon ebay.com MyLabel1",  // domenii sau etichete de concurenți ignorate (vezi UI)
					"charm"		: "charm",  // mod de prețuri psihologice (none|zeros|charm)
					"confidence"	: 82,  // încredere minimă 0-99% (vezi UI)
					"init"	: { // obiect inițial (primul rând "Setează prețul meu la")
						"target"	: "cheapest_n",  // (vezi lista din repricingCreate)
						"var_n"		: 3,  // dacă țintă necesită N, altfel absent
						"plusAmount"	: -2,  // pozitiv: deasupra; negativ: dedesubt
						"plusCurrency"	: "%",  // moneda (de ex. "USD") sau "%"
						// Corespunde la "Setează prețul meu cu 2% sub media celor mai ieftini 3 concurenți"
						// AVERTISMENT: Spre deosebire de obiectele "never", initializarea nu are "direction". Semnul lui "plusAmount" determina deasupra/dedesubt.
					},
					"never"	: [ // obiecte "but never" executate în ordine
						{
							"target"	: "cheapest_n_in",
							"var_n"		: 1,
							"direction"	: "below",  // sau "above"
							"plusAmount"	: -10,  // pozitiv: plus; negativ: minus
							"plusCurrency"	: "USD",  // moneda sau "%"
							// Corespunde la "Dar niciodată sub prețul celui mai ieftin concurent cu stoc, minus 10,00 USD"
						},
						{},  // Acest al doilea rând de condiții "But never" este gol
						{
							"target"	: "cost",
							"direction"	: "below",
							"plusAmount"	: 5,
							"plusCurrency"	: "%",
							// Corespunde la "Dar niciodată sub costul meu plus 5%"
						}
					],
				}
				...
			],
		},
		...
	]
}

Foi de calcul

spreadsheetDownload - Descarcă o foaie de calcul

Această acțiune este o EXCEPȚIE: nu o poți combina cu alte acțiuni și returnează un fișier de calcul, nu un răspuns JSON. (cu excepția utilizării "savePreset" sau "downloadURL", descrise mai jos)
Este echivalentul opțiunilor din pagina Export din cont.
Asigură-te că setările de timeout sunt suficient de mari, deoarece generarea unei foi de calcul mari poate dura.
MAI SIMPLU: Apasă pe butonul Show API equivalent din pagina Export. Acesta generează cererea JSON completă și comanda curl pentru opțiunile selectate în formular.
{ "actions" : [
	{
		"a"		: "spreadsheetDownload",
		"preset"	: "Some Preset Name",  // (opțional) În loc sa furnizezi toți parametrii de mai jos, poți folosi o presetare proprie sau a noastra
			// Pentru presetarile proprii: numele complet fără utilizator în fata sau moneda la final.
			// Pentru presetarile noastre, vezi numele din meniul DIRECT DOWNLOAD al paginii Export (treci cu mouse-ul peste ele).
			// De exemplu "pricezag_backup" este o presetare speciala pentru backup (vezi "Special BACKUP format to re-import" din DIRECT DOWNLOAD)
			// Poți furniza variabile suplimentare pentru a înlocui optiunile presetarii (moneda, format sau categorii).
		"savePreset"	: "My New Preset Name",  // (opțional) Salvează parametrii de mai jos ca presetare nouă (folosită în UI și API)
			// EXCEPTIE A EXCEPTIEI: cu savePreset nu se descarcă fișier, ci se returnează un obiect JSON.
		"savePresetOverwrite"	: 1,  // (opțional) Înlocuiește presetarea existentă din "savePreset" (altfel eroare)
			// AVERTISMENT: inlocuirea șterge toate setările anterioare; nu modifică doar un câmp.
			// Pentru a redenumi sau șterge o presetare, folosește acțiunea spreadsheetPresetEdit de mai jos.
		"downloadURL"	: 1,  // (opțional) EXCEPTIE: în loc de fișier returnează JSON cu "fileURL",
			// URL public al fișierului, fără autentificare sau cheie API. Disponibil 15 minute pentru descărcare de oriunde.
			// "ok" este numărul de rânduri; "fileSize" mărimea fișierului în bytes.
		"format"	: "xlsx|xls|csv|csv-tab",  // (implicit csv pentru API)
		"currency"	: "USD",  // (OBLIGATORIU fără preset) moneda tuturor sumelor
		"categories"	: ["Category 1", "Category 2"],  // Doar produsele din aceste categorii (altfel toate)
		"historyPeriod"	: "prev_6mo",  // (opțional, implicit "now")
			// MAI INTAI: consulta (?) despre perioadele istorice în Export, unde există explicatii detaliate.
			// "historyPeriod" determina cât de departe citim în trecut; "historyRow" imparte datele în rânduri per produs.
			// "now": fără istoric, doar datele curente (fără "historyRow")
			// "all": tot istoricul disponibil de la inscriere (sau pentru acele produse). POATE FI LENT.
			// "1234500000-1237800000": interval personalizat (marcaje temporale Epoch de început și sfârșit)
			// "123h": ultimele 123 ore, fără aliniere la ora; finalul este acum, inceputul poate fi între ore.
			// "cur_123(d|wk|mo|yr)": ultimele 123 zile/săptămâni/luni/ani inclusiv perioada incompleta. "cur_2mo" în ziua 10 = 40 de zile.
			// "prev_123(d|wk|mo|yr)": 123 perioade anterioare complete. "prev_2mo" pe 10 feb. = decembrie+ianuarie (62 zile).
			// Inceputul cur_* și prev_* (și sfarsitul prev_*) se aliniaza la miezul noptii; cur_* se termina acum.
			// Astfel "cur_2d" la prânz acoperă 36 de ore; "prev_2d" acoperă 48 de ore până acum 12 ore.
		"historyRow"	: "2w",  // (obligatoriu dacă "historyPeriod" nu este "now")
			// "historyRow" determina durata fiecarui rând (media perioadei), mai multe rânduri per produs (exceptie "all").
			// "historyRow" este impartirea lui "historyPeriod" în rânduri pentru fiecare produs.
			// "all": media pentru întreg historyPeriod, un rând per produs.
			// "123(d|wk|mo|qt|yr)": intervale calendaristice de 123 zile/săptămâni/luni/trimestre/ani, aliniate la miezul noptii. 123 opțional dacă este 1 ("wk" = "1wk")
			// Dacă descarci sâmbătă cu historyRow:"7d", fiecare rând este media de sâmbătă 00:00 până vineri 23:59.
			// Cu historyRow:"1wk", rândurile medieaza luni 00:00 - duminica 23:59; ultimul rând este săptămână incompleta curenta.
			// LIMITA 500.000 RANDURI: UI și API resping parametrii istorici care produc peste 500K rânduri.
			// Se poate întâmpla cu historyRow:"day" și un historyPeriod lung, de ex. 365 zile x 1400 produse.
			// Dacă ai nevoie, descarcă pe categorii de cateva sute de produse.
		"timezone"	: "America/Los_Angeles",  // (opțional, implicit "UTC") calea Linux /usr/share/zoneinfo
			// Spațiile sunt convertite în underscore.
			// Fusul orar conteaza doar dacă history* folosește perioade calendaristice (pentru miezul noptii).
			// UI folosește fusul orar al utilizatorului; API nu are setare și trebuie furnizat în cerere.
		// ========== COLOANE: ==========
		// Variabilele column* determina coloanele fișierului (vezi formularul Export pentru detalii)
		// Implicit 0 (nu se include), exceptie Code.
		"columnCode"		: 1,  // Această coloană nu se poate elimina: REF-CODE este mereu inclus.
		"columnName"		: 1,  // Nume produs
		"columnCategories"	: 1,  // Categorii produs ("Category 1; Category 2" într-o celulă)
		"columnComments"	: 1,  // Comentarii produs
		"columnCreated"		: 1,  // Data creării YYYY/MM/DD (în sistemul nostru)
		"columnCustom"		: 1,  // Câmpuri personalizate (o coloana per variabila unica între produse)
		"columnPrice"		: 1,  // Preț produs în moneda solicitata (NU în moneda proprie)
		"columnCost"		: 1,  // Cost produs (în ...)
		"columnMargin"		: 1,  // Marja procentuala bazata pe preț și cost
		"columnRank"		: 1,  // Poziția mea
		"columnInRank"		: 1,  // Poziția mea dintre ofertele în stoc
		"columnMyWebsite"	: 1,  // URL-ul site-ului meu
		"columnReprice"		: 1,  // Sumă de repricing (în ...)
		"columnRepricingRule"	: 1,  // Numele regulii de repricing
		"columnRecommended"	: 1,  // Preț recomandat (vezi ajutorul din Export)
		"columnCompUrls"	: 1,  // URL-uri concurenți (unul per coloana)
		"columnCompUrlsJoin"	: 1,  // URL-uri concurenți (separate prin spații într-o celulă)
		"columnCompMinMaxAvg"	: 1,  // Adaugă 3 coloane: Min/Max/Media concurenților
		"columnInCompMinMaxAvg"	: 1,  // Adaugă 3 coloane: Min/Max/Media concurenților CU STOC
		"columnCompPrice"	: 1,  // O coloana per concurent cu prețul (în ...)
		"columnCompStock"	: 1,  // O coloana per concurent cu stocul (123|IN|OUT)
		"columnCompSales"	: 1,  // O coloana per concurent cu vânzări/săptămână
		"columnCompRank"	: 1,  // O coloana per concurent cu poziția între toți (inclusiv tu)
		"columnCompInRank"	: 1,  // O coloana per concurent cu poziția între cei CU STOC (inclusiv tu)
		// ========== PARAMETRI AVANSATI ASCUNSI: ==========
		// Există și opțiuni neoficiale, putin documentate, unele folosite de "pricezag_backup".
		"originalCurrencies"	: 1,  // În loc de numere convertite în moneda aleasa, celulele contin text cu moneda originală ("123.90 USD")
		"keepUrlLabels"		: 1,  // În mod normal eliminam etichetele URL-urilor; aici se păstrează (utile la backup).
		"csvSeparator"		: ";",  // Pentru a folosi în CSV alt separator decat virgula sau tab.
		"csvNoQuote"		: 1,  // Impiedica ghilimelele (") în CSV. Poate produce un format invalid.
	}
] }
// Exemplu simplu de descarcare a unui backup CSV:
// curl --connect-timeout 15 --max-time 600 --retry 2 -X POST 'https://pricezag.com/api/v3/MYAPIKEY' -d '{"actions":[{"a":"spreadsheetDownload","preset":"pricezag_backup"}]}' -o pricezag-backup-20241225.csv

spreadsheetPresetEdit - Redenumește sau șterge o presetare de export

Este echivalentul funcției din cont, în pagina Export, apăsând pe Edit Presets.
Acțiunea permite doar REDENUMIREA sau ȘTERGEREA unei presetări. Pentru creare sau modificare folosește acțiunea spreadsheetDownload de mai sus.
{ "actions" : [
	{
		"a"		: "spreadsheetPresetEdit",
		"preset"	: "Some Preset Name",  // Numele curent al presetarii
		"newName"	: "The Renamed Preset",  // Redenumeste aceasta presetare
		"delete"	: 1,  // Șterge acel "preset" din cont
		// NOTA: nu poți șterge o presetare folosită în auto-export (eroare).
		// Șterge mai întâi exporturile automate programate (vezi Export).
	}
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "spreadsheetPresetEdit",
			"ok"	: 1,
		},
		...
	]
}

spreadsheetAutoCreate - Creează un export automat de foi de calcul

Este echivalentul funcției din cont, în pagina Export, apăsând pe Add a new Auto-Export.
{ "actions" : [
	{
		"a"			: "spreadsheetAutoCreate",
		"preset"		: "The Preset Name",
		"email"			: "john@example.net",
		"currency"		: "USD",  // (opțional) implicit "preset": folosește moneda presetarii
		"attach"		: "link",  // (opțional, implicit "attach") "attach" pentru atasament, "link" pentru link găzduit
		"everyMonday"		: 1,  // Trimite foaia în fiecare luni
		"everyTuesday"		: 1,  // ... și așa pentru toate zilele până la "everySunday"
		"everyMonthDay1"	: 15,  // Trimite în fiecare zi de 15 a lunii
		"everyMonthDay2"	: 21,  // ... și în fiecare zi de 21
		"everyMonthDay3"	: "last",  // ... și în ultima zi a fiecarei luni
			// everyMonthDay* de la 0 la 9, maximum 10 zile din luna
		"time"			: "3:59pm",  // "15.59" este valid și echivaleaza cu "3:59pm". "0:9", "0.09", "00:09", "0:09am" sunt echivalente.
		"timezone"		: "America/Los_Angeles",  // (opțional, implicit "UTC") calea Linux /usr/share/zoneinfo
			// Spațiile din numele orașului devin underscore.
	}
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "spreadsheetAutoCreate",
			"ok"	: 1,
			"id"	: "5gwi6fqa",  // ID-ul de referință al acestui export automat, dacă trebuie să îl modifici ulterior (vezi acțiunea spreadsheetAutoEdit de mai jos)
		},
		...
	]
}

spreadsheetAutoEdit - Editează un export automat de foi de calcul

Este echivalentul funcției din cont, în pagina Export, apăsând pe un buton Edit din lista aflată sub AUTO-EXPORT TO EMAIL.
{ "actions" : [
	{
		"a"			: "spreadsheetAutoEdit",
		"id"			: "5gwi6fqa",  // ID-ul auto-exportului de editat
			// ID returnat de spreadsheetAutoCreate; apare și în titlul ferestrei Edit a auto-exportului din UI.
		"disabled"		: 1,  // (opțional) 0 pentru activarea unui auto-export dezactivat
		"delete"		: 1,  // (opțional) Șterge complet acest auto-export
		// ===== Câmpurile următoare (toate opționale) sunt aceleași ca în acțiunea spreadsheetAutoCreate de mai sus =====
		"preset"		: "The Preset Name",
		"email"			: "john@example.net",
		"currency"		: "USD",
		"attach"		: "link",
		"everyMonday"		: 1,  // AVERTISMENT: dacă furnizezi orice variabilă every*, se șterg toate valorile every* existente.
		"everyMonthDay1"	: 15,  // Dacă aveai "everyFriday"=1 și setezi "everyMonthDay3", se elimină "everyFriday".
		// ... și așa mai departe (vezi every* în spreadsheetAutoCreate)
		"time"			: "3:59pm",
		"timezone"		: "America/Los_Angeles",
	}
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "spreadsheetAutoEdit",
			"ok"	: 3,  // Numărul modificărilor
		},
		...
	]
}

Concurenți și altele

competitorDeleteAll - Șterge un concurent din toate produsele sau categoriile

Șterge în masă URL-urile unui concurent, din toate produsele sau doar din produsele anumitor categorii.
AVERTISMENT: URL-urile concurentului sunt șterse imediat din cont și nu pot fi recuperate.
Este aceeași funcție folosită de interfață când deschizi pagina unui concurent și apeși pe Delete from all Products sau când deschizi pagina unei categorii și apeși pe pictograma (X) din lista de concurenți.
{ "actions" : [
	...
	{
		"a"		: "competitorDeleteAll",
		"domain"	: "competitordomain.com",
		"categories"	: ["The Category 1", "The Category 2"],  // (opțional) Dacă lipseste, trebuie sa folosești "allProducts" = 1
		"allProducts"	: 1,  // (opțional) elimină din toate produsele (NU furniza "categories")
		// Folosește "categories" SAU "allProducts", niciodata ambele sau niciuna.
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "competitorDeleteAll",
			"ok"	: 10,  // Numărul URL-urilor șterse
		},
		...
	]
}

mathEdit - Setează sau editează calculele de preț pentru domeniul unui concurent

Este aceeași funcție pe care o folosește interfața când accesezi Domains, apasă pe domeniul unui concurent, apoi pe Mathematically alter the price. Toate opțiunile acelui formular sunt disponibile și prin acțiunea API mathEdit.
Apasă pe pictogramele verzi cu semn de întrebare din cont pentru detalii despre fiecare câmp.
{ "actions" : [
	...
	{
		"a"		: "mathEdit",
		"domain"	: "competitordomain.com",
		"clear"		: 1,  // (opțional) Dezactiveaza toate calculele domeniului (șterge setările anterioare)
		// Dacă clear:1, nu furniza alte câmpuri, altfel eroare.
		"math"	: [  // Tablou de blocuri matematice de aplicat
			{  // Obiect bloc matematic; toate câmpurile optionale
				"categories"		: ["Category 1", "Category 2"],  // Doar produsele din aceste categorii
				"theirPriceMin"		: 1234.90,  // Doar dacă prețul lor este >= N
				"theirPriceMinCurrency"	: "USD",  // Moneda ("original" = moneda site-ului)
				"theirPriceMax"		: 1234.90,  // ... <= N
				"theirPriceMaxCurrency"	: "USD",  // Moneda (...)
				"themMeMin"		: -20.00,  // Doar dacă [ei - eu] >= N (vezi UI)
				"themMeMinCurrency"	: "USD",  // Moneda sau "%" din prețul tău (NU "original")
				"themMeMax"		: -1.5,  // ... <= N
				"themMeMaxCurrency"	: "%",  // Moneda (...)
				"addPre"		: -10.00,  // Sumă adăugată înainte de inmultire (negativ pentru scadere)
				"addPreCurrency"	: "USD",  // Moneda ("original" = moneda site-ului)
				"multiply"		: 1.1,  // Inmulteste cu acest factor
				"divide"		: 1.1,  // SAU imparte (nu folosi ambele)
				"addPost"		: 5.00,  // Sumă adăugată după inmultire (negativ pentru scadere)
				"addPostCurrency"	: "USD",  // Moneda (...)
				// Pare complicat? Vezi exemplul simplu de sub răspuns.
			},
			... // Maximum 10 blocuri (aplicate în ordine)
		],
		// NOTĂ: momentan nu poți modifica un singur câmp/bloc. Tabloul "math" înlocuiește totul.
		// NOTA: un bloc fără inmultire/impartire (lipsa sau 1) și fără addPre/addPost diferite de 0 este ignorat;
		// dacă toate sunt ignorate, efectul este ca stergerea tuturor calculelor prin clear:1.
		// Cu alte cuvinte, calculele trebuie sa faca ceva pentru a fi salvate.
		// TRUC: pentru a dezactiva temporar calculele unui domeniu fără a le șterge,
		// folosește categories: ["Some Empty Existing Category"]
	},
	...
] }
RĂSPUNS:
{
	...
	"actions" : [
		...
		{
			"a"	: "mathEdit",
			"ok"	: 3,  // Număr de blocuri matematice modificate (inclusiv ștergere/golire)
		},
		...
	]
}
EXEMPLU SIMPLU — Elimină o taxă de 10% pentru întreg amazon.co.uk:
{ "actions" : [
	{
		"a"		: "mathEdit",
		"domain"	: "amazon.co.uk",
		"math"		: [
			{
				"divide"	: 1.1
			}
		]
	}
] }

Mai multe exemple

Aceste cereri reprezintă date POST trimise către https://pricezag.com/api/v3/MYAPIKEY
▶ EXEMPLUL 1 — Actualizează costul unui produs
CERERE:
{
	"actions" : [
		{
			"a"		: "productEdit",
			"code"		: "SKU-1234",
			"cost"		: 140.50,
			"costCurrency"	: "EUR"
		}
	]
}
RĂSPUNS:
{
	"ok"		: 1,  // ar returna 0 dacă SKU-1234 avea deja acel cost
	"errors"	: 0,  // ar returna 1 dacă SKU-1234 nu există
	"actionsCount"	: 1,
	"actions" : [
		{
			"a"	: "productEdit",
			"ok"	: 1  // 0 dacă același cost, -1 dacă produsul nu există
		}
	]
}

▶ EXEMPLUL 2 — Consultă un produs inexistent
CERERE:
{
	"actions" : [
		{
			"a"		: "productGet",
			"code"		: "NON-EXISTING-SKU",
			"currency"	: "USD"
		}
}
RĂSPUNS:
{
	"ok"		: 0,  // deoarece nicio acțiune nu a returnat ok>0
	"errors"	: 1,  // deoarece o acțiune a returnat ok<0
	"actionsCount"	: 1,
	"actions" : [
		{
			"a"	: "productGet",
			"ok"	: -1,  // așa stii ca a eșuat
			"error"	: "Sorry, the product #NON-EXISTING-SKU does not exist. Maybe someone else just removed or renamed it?"
		}
	]
}

▶ EXEMPLUL 3 — Creează o categorie, o regulă de repricing și apoi două produse atribuite lor
CERERE:
{
	"actions" : [
		{
			"a"		: "categoryCreate",
			"name"		: "My New Category"
		},
		{
			"a"		: "repricingCreate",
			"name"		: "My New Repricing Rule",
			"init"	: {
				"target"	: "cheapest_n",
				"var_n"		: 2,
				"plusAmount"	: 0,
				"plusCurrency"	: "%"
				// Corespunde la "Setează prețul meu la mijlocul intervalului dintre cei mai ieftini 2 concurenți"
			},
			"never"	: [
				{
					"target"	: "cost",
					"direction"	: "below",
					"plusAmount"	: 5,
					"plusCurrency"	: "%"
					// Corespunde la "Dar niciodată sub costul meu + 5%"
				}
			],
			"charm"		: "charm"
		},
		{
			"a"		: "productCreate",
			"code"		: "SKU-1001",
			"name"		: "My New Product 1",
			"price"		: 199.90,
			"currency"	: "USD",
			"cost"		: 112.00,
			"costCurrency"	: "USD",
			"repricingRule"	: "My New Repricing Rule",  // același nume al regulii pe care tocmai am creat-o
			"categories"	: ["My New Category"],	// același nume de categorie tocmai creat
			// ... deși productCreate creeaza categorii inexistente, deci categoryCreate nu era necesar
			"competitors"	: ["https://...", "https://..."]
		},
		{
			"a"		: "productCreate",
			"code"		: "SKU-1002",
			"name"		: "My New Product 2",
			"price"		: 59.95,
			"currency"	: "USD",
			"cost"		: 31.50,
			"costCurrency"	: "USD",
			"repricingRule"	: "My New Repricing Rule",
			"categories"	: ["My New Category"],
			"competitors"	: ["https://...", "https://..."]
		}
	]
}
RĂSPUNS:
{
	"ok"		: 4,  // deoarece toate cele 4 acțiuni au returnat ok>0
	"errors"	: 0,  // deoarece nicio acțiune nu a returnat ok<0
	"actionsCount"	: 4,
	"actions" : [
		{
			"a"	: "categoryCreate",
			"ok"	: 1
		},
		{
			"a"	: "repricingCreate",
			"ok"	: 1
		},
		{
			"a"	: "productCreate",
			"ok"	: 1
		},
		{
			"a"	: "productCreate",
			"ok"	: 1
		}
	]
}

▶ EXEMPLUL 4 — Combină două categorii într-una nouă și șterge-le pe cele originale
CERERE:
{
	"actions" : [
		{
			"a"			: "categoryCopy",
			"categoriesFrom"	: ["Original Category 1", "Original Category 2"],
			"deleteMode"		: "cat",
			// "removeMode":"cat" este inutil deoarece deleteMode șterge cele doua categorii
			"categoriesTo"		: ["A New Category"]
		}
}
RĂSPUNS:
{
	"ok"		: 1,  // deoarece o acțiune a returnat ok>0
	"errors"	: 0,  // deoarece nicio acțiune nu a returnat ok<0
	"actionsCount"	: 1,
	"actions" : [
		{
			"a"			: "categoryCopy",
			"ok"			: 3,  // deoarece 3 categorii s-au modificat: 2 originale șterse și 1 destinatie creată
			"categoriesCreated"	: 1,
			"categoriesDeleted"	: 2,
			"categoriesModified"	: 0,
			"productsCount"		: 123
		}
	]
}

▶ EXEMPLUL 5 — Modifică variabila N și direcția unei reguli de alertă
CERERE:
{
	"actions" : [
		{
			"a"		: "alertRuleEdit",
			"email"		: "john@example.net",
			"ruleNumber"	: 3,
			"rule"		: {
				"var_n"		: 1.5,
				"direction"	: "drop"
			}
		}
}
RĂSPUNS:
{
	"ok"		: 1,  // deoarece o acțiune a returnat ok>0
	"errors"	: 0,  // deoarece nicio acțiune nu a returnat ok<0
	"actionsCount"	: 1,
	"actions" : [
		{
			"a"	: "alertRuleEdit",
			"ok"	: 2  // deoarece 2 variabile au fost modificate cu succes
		}
	]
}