API PriceZag - Połącz dane cenowe ze swoimi systemami

Korzystaj z JSON API PriceZag, aby pobierać ceny i stany magazynowe konkurentów, zarządzać produktami i regułami automatycznej zmiany cen, pobierać raporty i automatyzować pracę.

Szybki przykład z curl

Wiemy, że programiści wolą najpierw zobaczyć działający kod. Te polecenia tworzą produkt testowy, a następnie pobierają jego dane. Zastąp MYAPIKEY kluczem API swojego konta (zobacz Klucz API).
Utwórz produkt testowy:
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"}]}'
(jeśli wykonasz polecenie drugi raz, pojawi się błąd, ponieważ produkt już istnieje)
Teraz możesz pobrać dane utworzonego produktu:
curl -X POST 'https://pricezag.com/api/v3/MYAPIKEY' -d '{"actions":[{"a":"productGet","code":"000-SOME-TEST-PRODUCT"}]}' | python -mjson.tool
(usuń | python -mjson.tool, jeśli nie masz narzędzia do formatowania odpowiedzi JSON w terminalu)

Przegląd

Co możesz zrobić za pomocą API PriceZag

JSON API PriceZag pozwala Twoim skryptom i systemom firmowym bezpośrednio korzystać z monitorowanych przez nas cen i stanów magazynowych konkurentów. Pobieraj dane produktów, zarządzaj produktami i kategoriami, obliczaj kwoty według reguł automatycznej zmiany cen, konfiguruj alerty i pobieraj niestandardowe arkusze. Możesz używać API z dowolną platformą e-commerce lub językiem programowania obsługującym żądania HTTPS i przetwarzanie JSON.

Możesz również poprosić swojego ulubionego asystenta AI o napisanie skryptów. Podaj mu adres tej dokumentacji (https://pricezag.com/integrations/api), wyjaśnij, co chcesz zautomatyzować, i wskaż używany język programowania lub platformę e-commerce. Chroń swój klucz API i nie wklejaj go do rozmowy z AI.

PriceZag sam zajmuje się monitorowaniem, więc korzystanie z API jest opcjonalne. Przydaje się, gdy chcesz połączyć te dane z własnymi systemami. Shopify i WooCommerce oferują również bezpośrednie integracje.

Klucz API i uprawnienia

Na koncie PriceZag otwórz Automation > API. Kliknij Reveal the current API key, aby zobaczyć aktualny klucz, albo Change the API key, aby go zmienić. Obie czynności wymagają hasła do konta. Użytkownik musi mieć odpowiednie uprawnienia do wyświetlania lub generowania kluczy API. Jeśli ich nie ma, powinien skontaktować się z administratorem konta.

Chroń swój klucz API. Klucz ten może umożliwiać szerokie zmiany w danych konta, w tym usuwanie danych. Nie umieszczaj go w publicznych repozytoriach, kodzie działającym w przeglądarce ani rozmowach z AI. Jeśli ktoś pomaga Ci tworzyć integrację, utwórz dla niego konto użytkownika PriceZag z odpowiednimi uprawnieniami i w razie potrzeby zmień klucz API.

Dostęp do API zależy od Twojego abonamentu. Przy pełnym dostępie skrypty mogą pracować ze wszystkimi produktami. Bez niego API udostępnia tylko 10 pierwszych produktów posortowanych alfanumerycznie według kodu referencyjnego. Jeśli masz na przykład 1000 produktów z kodami od SKU0001 do SKU1000, API udostępni kody od SKU0001 do SKU0010. W ramach 14-dniowego bezpłatnego okresu próbnego otrzymujesz pełny dostęp do API. Możesz też włączyć pełny dostęp do API jako opcję abonamentu.

Dziennik aktywności API i ostatnie żądanie

Strona Automation > API na Twoim koncie pokazuje czas ostatniego żądania API oraz przycisk API Activity Log. Jeśli skrypt nie działa, sprawdź, czy żądania dotarły do PriceZag, i poszukaj przyczyn błędów lub nieoczekiwanych zmian.

Zmiany wprowadzone przez API pojawiają się również w History of Edits na całym koncie, pod nazwą użytkownika API. Na przykład historia produktu może zawierać wpis Price edited by API zamiast Price edited by JOHN. PriceZag umożliwia korzystanie z jednego konta wielu użytkownikom, więc łatwo odróżnisz zmiany automatyczne od wprowadzonych przez członków zespołu.

Adres URL i metody żądań

Wszystkie żądania API korzystają z tego samego adresu HTTPS. Wysyłaj do niego żądania POST, zastępując MYAPIKEY swoim kluczem:

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

Operacje, które ma wykonać API ("actions"), i ich parametry umieść w treści żądania JSON, a nie w adresie URL.
W treści żądania POST wyślij obiekt JSON zawierający co najmniej jedną akcję. Adres URL pozostaje taki sam niezależnie od tego, czy pobierasz produkt, aktualizujesz ceny, czy pobierasz arkusz.

Nie możesz wysyłać żądań POST?
W ostateczności możesz wysłać żądanie GET, przekazując treść JSON zakodowaną w Base64 w parametrze adresu URL ?data=. Adresy URL mają ograniczoną długość, dlatego zdecydowanie zalecamy POST.

Jak działają akcje

Przez akcję rozumiemy operację na koncie, np. edycję pól produktu, zmianę reguły cenowej lub pobranie cen wszystkich konkurentów dla danego produktu.
Nasze API i interfejs użytkownika (UI) wykonują te same funkcje na serwerze, więc prawie wszystkie operacje dostępne w interfejsie można wykonać również przez API.
W żądaniu API dane JSON zawierają tablicę wszystkich akcji, które chcesz wykonać, od 1 do maksymalnie 1000 na żądanie. W jednym żądaniu możesz na przykład zmienić nazwy 3 produktów i utworzyć kategorię, czyli wykonać 4 akcje. Możesz też pobrać dane 1000 produktów za pomocą 1000 akcji "productGet".
Akcje wykonywane są w kolejności podanej w tablicy. Jeśli najpierw tworzysz regułę cenową, a potem przypisujesz do niej produkty, zachowaj tę kolejność, aby reguła istniała już w momencie edycji produktów.
Poniżej znajdziesz listę wszystkich dostępnych akcji.

Obiekt żądania JSON

Dla skryptów i kodu generowanego przez AI: Poniższe przykłady dokumentacyjne zawierają // komentarze oraz ... wartości zastępcze objaśniające pola. To tylko ilustracje, a nie poprawny JSON gotowy do wysłania. Przed wysłaniem usuń komentarze i zastąp wartości przykładowe. Dwa powyższe przykłady curl zawierają prawidłową treść JSON.

Cała treść żądania POST musi być pojedynczym obiektem JSON {...} zawierającym tablicę akcji do wykonania.
{
	"stopOnFailure"	: 1,  // (opcjonalnie) Domyślnie serwer przechodzi do następnej akcji nawet po błędzie. Ustaw 1, aby przerwać wykonywanie.

	// Tablica wszystkich akcji:
	"actions" : [
		// Akcja 1:
		{
			"a"	: "someActionName",  // Nazwa akcji zawsze znajduje się w polu "a" każdego obiektu akcji.
			"xx"	: "some parameter this action needs"	// Wszystko poza "a" to parametry wymagane przez daną akcję.
		},
		// Akcja 2:
		{
			"a"	: "anotherActionName",
			"abc"	: "some parameter this action needs",
			"xyz"	: {"x":"some object this action needs", "y":5, "z":6}
		},
		// Akcja 3:
		{
			"a"	: "aThirdAction",
			"xyz"	: ["some array this action needs", "..."]
		}
	]
}

Odpowiedź serwera i kody HTTP

W razie błędnego formatu żądania lub na przykład wyłączenia konta serwer zwraca odpowiedź text/plain zawierającą komunikat błędu.
Jeśli żądanie jest poprawne, zazwyczaj otrzymasz obiekt JSON w odpowiedzi, z wyjątkiem kilku wyraźnie oznaczonych akcji (np. pobrania arkusza). Wskazuje na to nagłówek odpowiedzi Content-Type: application/json.
Kody odpowiedzi HTTP to:
► 200 gdy wszystkie akcje się powiodły (neutralny wynik ok=0 również jest uznawany za sukces)
► 406 gdy część akcji się powiodła, a część zakończyła błędem.
► 422 gdy wszystkie akcje zakończyły błędem z przyczyn innych niż wymienione poniżej.
► 400 gdy nie udało się zdekodować otrzymanego obiektu JSON.
► 403 gdy uwierzytelnianie zakończyło się niepowodzeniem (zwykle z powodu nieprawidłowego klucza API).
Możesz oprzeć logikę skryptu na tych kodach odpowiedzi. Jeśli potrzebujesz szczegółów, znajdziesz je w zwróconym obiekcie JSON:
{
	"ok"		: 15,  // Liczba pomyślnie wykonanych akcji (wynik akcji ok>0)
	"errors"	: 0,  // Liczba akcji zakończonych błędem (wynik akcji ok<0)
	"actionsCount"	: 20,  // Łączna liczba pierwotnie żądanych akcji (długość tablicy "actions")
	// UWAGA: Wynika z tego, że 5 akcji zwróciło ok=0 (nie wystąpił błąd, ale nic się nie zmieniło).
	
	// Tablica wszystkich pierwotnie żądanych akcji (w tej samej kolejności):
	"actions" : [
		...
		// Obiekt odpowiedzi dla każdej akcji:
		{
			"a"	: "someActionName",
			"ok"	: 4,		// Wynik: >0 = sukces, 0 = bez zmian, <0 = błąd
						// Na przykład 0, jeśli ustawisz cenę produktu na tę samą wartość.
						// -1 na przykład wtedy, gdy produkt nie istnieje.
						// Znaczenie >0 zależy od akcji. Często oznacza liczbę faktycznie zmienionych pól lub elementów.
			"error"	: "...",  // Komunikat błędu, jeśli ok < 0
						// Nasze komunikaty błędów są bardzo szczegółowe. Zapisuj je w dzienniku,
						// ponieważ pomogą ustalić przyczynę problemu.
			...	// Pozostałe dane właściwe dla danej akcji
		},
		...
	]
}

Przykłady?

Czasem przykłady wyjaśniają wszystko najlepiej. Zobacz więcej przykładów na samym końcu tej strony.

Limity żądań i harmonogram

Nasza zapora sieciowa chroni platformę i Twoje dane przed atakami oraz nadmierną liczbą żądań. Gdy zablokuje dany serwer, strona może wyglądać na niedostępną (brak połączenia, odpowiedzi i reakcji na ping).
Aby uniknąć blokowania prawidłowych żądań:
► Nie używaj nieprawidłowego klucza API. Zapora szybko reaguje na błędne klucze (tak samo jak na błędne hasła logowania).
► Grupuj wiele akcji w jednym obiekcie JSON i jednym żądaniu (maksymalnie 1000). Aby utworzyć 1000 produktów, wyślij jedno żądanie zamiast tysiąca.
► Jeśli naprawdę potrzebujesz wielu żądań, zachowaj między nimi odstęp 500 ms i korzystaj ponownie z tego samego połączenia HTTPS. Otwieranie nowego połączenia przy każdym żądaniu to częsty błąd. Wiele żądań ma uzasadnienie przede wszystkim przy aktualizacji setek tysięcy produktów, po 1000 akcji na żądanie.
Nie stosujemy stałego limitu liczby żądań. Zapora podejmuje decyzje na podstawie dziesiątek parametrów. Najlepiej zachować rozsądne tempo wysyłania żądań.
 
Zaplanowane żądania:
Jeśli regularnie wysyłasz żądania, dodaj losowe opóźnienie, aby nie trafiały zawsze na zerową sekundę minuty. Wielu klientów wysyła je jednocześnie. Rozłożenie żądań w czasie przyspiesza odpowiedź i zmniejsza ryzyko przekroczenia limitu czasu przy obciążeniu serwera.

Wszystkie dostępne akcje API

Każda akcja opisana jest poniżej wraz z parametrami oraz przykładami żądań i odpowiedzi. Nawigacja po lewej prowadzi bezpośrednio do każdej akcji.

Produkty

AkcjaZastosowanie
productCreateUtworzyć nowy produkt
productEditEdytować istniejący produkt
productCompetitorsEdytować adresy URL konkurentów dla produktu (bez konieczności zastępowania wszystkich)
productCategoriesEdytować kategorie jednego lub wielu produktów (bez konieczności zastępowania wszystkich)
productRepricingPrzypisać wiele produktów do reguły cenowej
productDeleteUsunąć jeden lub wiele produktów
productGetPobrać produkt (wraz z danymi konkurentów)
productGetAllPobrać wszystkie produkty (wraz z danymi ich konkurentów)

Kategorie

AkcjaZastosowanie
categoryCreateUtworzyć nową kategorię
categoryEditEdytować istniejącą kategorię
categoryDeleteUsunąć jedną lub wiele kategorii
categoryCopyKopiować/przenosić produkty między kategoriami
categoryGetPobrać kategorię
categoryGetAllPobrać wszystkie kategorie

Alerty cenowe

AkcjaZastosowanie
alertRecipientCreateUtworzyć nowego odbiorcę alertów
alertRecipientEditEdytować odbiorcę i/lub jego reguły alertów
alertRecipientDeleteUsunąć odbiorcę alertów
alertRuleEditEdytować istniejącą regułę alertu odbiorcy
alertRuleCreate ?Taka akcja nie istnieje. Użyj alertRecipientEdit z tablicą "rulesAdd".
alertRuleDelete ?Taka akcja nie istnieje. Użyj alertRecipientEdit z tablicą "rulesRemove".
alertGetAllPobrać wszystkich odbiorców alertów i ich reguły

Reguły automatycznej zmiany cen

AkcjaZastosowanie
repricingCreateUtworzyć nową regułę cenową
repricingEditEdytować istniejącą regułę cenową
repricingDeleteUsunąć regułę cenową
repricingGetAllPobrać wszystkie reguły cenowe

Arkusze kalkulacyjne

AkcjaZastosowanie
spreadsheetDownloadPobrać arkusz kalkulacyjny
spreadsheetPresetEditZmienić nazwę/usunąć ustawienia eksportu
spreadsheetAutoCreateUtworzyć automatyczny eksport arkuszy
spreadsheetAutoEditEdytować automatyczny eksport arkuszy

Konkurenci i inne funkcje

AkcjaZastosowanie
competitorDeleteAllUsunąć konkurenta ze wszystkich produktów lub kategorii
mathEditUstawić/edytować obliczenia cen dla domeny konkurenta

Produkty

productCreate - Utworzenie produktu

To ta sama funkcja, z której interfejs korzysta na stronie New Product.
{ "actions" : [
	...
	{
		"a"		: "productCreate",
		"code"		: "UNIQUE-REF-CODE",  // Długość 1–80 ([a-z\d][a-z\d_-]{0,78}[a-z\d]); wielkość liter bez znaczenia (konwersja na wielkie litery).
		"name"		: "The Product Name",  // Długość 1–200
		"price"		: 1234.90,  // Uwaga na przecinki i kropki. Bez separatora tysięcy; część dziesiętna oddzielana kropką.
		"currency"	: "USD",
		"cost"		: 1234.90,  // (opcjonalnie)
		"costCurrency"	: "USD",  // Wymagane, jeśli podano cost
		"repricingRule"	: "The Rule Name",  // (opcjonalnie) Przypisana reguła cenowa (puste = wyłączona, nieistniejąca = błąd)
		"myWebsite"	: "https://...",  // (opcjonalnie) URL albo shopify:productId:variantId lub woocommerce:productId(:variationId)
		"competitors"	: ["https://...", "https://..."],  // (opcjonalnie)
		"categories"	: ["The Category 1", "The Category 2"],  // (opcjonalnie) Kategorie produktu (nieistniejące zostaną utworzone)
		"comments"	: "Some comments\nAnd another line",  // (opcjonalnie) Maksymalnie 1000 znaków UTF-8
		"custom_someFieldName1"	: "Value of custom field",		// (opcjonalnie)
		"custom_someFieldName2"	: "Value of other\nCustom\tField",  // (opcjonalnie)
		// Pola niestandardowe służą do użytku wewnętrznego. Mogą być np. kolumnami eksportowanego arkusza.
		// Maksymalnie 20 pól niestandardowych na produkt. Nazwa może zawierać do 40 liter, cyfr i znaków podkreślenia (wielkość liter ma znaczenie), bez prefiksu "custom_" (łącznie 47 znaków).
		// Wartość jest ograniczona do 500 bajtów (niekoniecznie znaków). Możesz zapisać liczbę (custom_varname:123),
		// ale API zawsze zwraca ciąg znaków (custom_varname:"123"); w razie potrzeby przekształć typ.
		// Aby usunąć pole niestandardowe, ustaw wartość na "". Dotyczy to productEdit, nie productCreate.
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "productCreate",
			"ok"	: 1,
			"code"	: "REF-CODE",  // Ostateczny kod zapisany w bazie danych (możemy np. zmienić znaki specjalne).
		},
		...
	]
}

productEdit - Edycja istniejącego produktu

To ta sama funkcja, z której korzysta interfejs podczas edycji pól produktu. Interfejs wysyła każdą zmianę osobno, a API pozwala na przykład zmienić nazwę i cenę jednym wywołaniem.
{ "actions" : [
	...
	{
		"a"		: "productEdit",
		"code"		: "REF-CODE",
		...		// Przyjmuje te same parametry co productCreate, wszystkie opcjonalne.
		"newCode"	: "REF-CODE-RENAMED",  // (opcjonalnie)
		"competitors"	: ["https://...", "https://..."],  // Jeśli podano, ZASTĄPI wszystkie istniejące adresy URL konkurentów.
		// Aby tylko dodawać lub usuwać adresy URL, użyj akcji productCompetitors.
		"categories"	: ["The Category 1", "The Category 2"],  // Jeśli podano, ZASTĄPI obecne kategorie. Zamiast tego użyj productCategories lub categoryEdit.
		"custom_someFieldName"	: "New value or empty to delete that custom field",
		// Pamiętaj o limicie 20 pól niestandardowych na produkt. Aby dodać kolejne, możesz najpierw usunąć stare, ustawiając ich wartość na "".
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "productEdit",
			"ok"	: 3,  // Liczba zmian (np. moja cena + 2 adresy URL konkurentów = 3)
			"code"	: "REF-CODE",  // Ostateczny (nowy) kod w bazie danych (np. po zmianie znaków specjalnych).
		},
		...
	]
}

productCompetitors - Edycja adresów URL konkurentów dla produktu

Edytuj adresy URL konkurentów dla produktu bez zastępowania całej listy (w przeciwieństwie do akcji productEdit ).
{ "actions" : [
	...
	{
		"a"			: "productCompetitors",
		"code"			: "REF-CODE",
		"competitorsAdd"	: ["https://...", "https://..."],  // (opcjonalnie) Dodać te adresy URL konkurentów do istniejących
		"competitorsRemove"	: ["https://...", "example.com/a0ff80...5f00", "example.net"],  // (opcjonalnie) Usunąć tych konkurentów. Każda pozycja może być:
		// > Adres URL (wraz z ewentualnym modyfikatorem po #). Etykiety są opcjonalne.
		// > Wartość "ref" konkurenta (zwracana przez inne akcje; domena główna i 32-znakowy skrót MD5)
		// > Domena główna lub pełna nazwa hosta; usunięte zostaną wszystkie adresy URL tej domeny.
		// UWAGA: "competitorsAdd" i "competitorsRemove" mogą być ciągami znaków zamiast jednoelementowych tablic.
		// Usuwanie odbywa się przed dodawaniem, więc możesz usunąć całą domenę, a następnie dodać jeden jej adres URL.
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"			: "productCompetitors",
			"ok"			: 3,  // Liczba zmienionych adresów URL konkurentów
			"competitorsAdded"	: 2,  // Liczba adresów URL konkurentów dodanych do produktu
			"competitorsRemoved"	: 1,  // Liczba adresów URL konkurentów usuniętych z produktu
			// BŁĘDY:
			// > Dodanie istniejącego już adresu URL NIE spowoduje błędu (ok = 0)
			// > Usunięcie nieistniejącego pełnego adresu URL lub "ref" spowoduje błąd (ok = -1)
			// > Usunięcie wszystkich adresów URL nieistniejącej domeny NIE spowoduje błędu (ok = 0)
		},
		...
	]
}

productCategories - Edycja kategorii produktów

Edytuj kategorie jednego lub wielu produktów bez zastępowania całej listy (w przeciwieństwie do akcji productEdit).
To ta sama funkcja, z której korzysta interfejs: otwórz All Products, zaznacz jeden lub więcej produktów i kliknij Selected Products > Edit Categories. Szczegółowy opis tej funkcji znajdziesz w interfejsie.
Zobacz również akcję categoryEdit i wybierz wygodniejszą metodę.
{ "actions" : [
	...
	{
		"a"			: "productCategories",
		"code"			: "REF-CODE",  // Wielkość liter bez znaczenia (ciąg znaków), LUB:
		"code"			: ["REF-CODE-1", "REF-CODE-2"],  // Może też być tablicą wielu produktów (limit 100 000)
		"categoriesRemove"	: ["The Category 1", "The Category 2"],  // (opcjonalnie) Najpierw usunąć z tych kategorii.
		"categoriesRemoveAll"	: 1,  // (opcjonalnie) Najpierw usunąć ze wszystkich kategorii (jak productEdit)
		"deleteEmptyCategories"	: 1,  // W ten sposób każda kategoria, która stanie się pusta
		// po usunięciu z niej produktów, zostanie usunięta.
		"categoriesAdd"		: ["The Category 1", "The Category 2"],  // (opcjonalnie) Następnie dodać do tych kategorii (nieistniejące zostaną utworzone)
		"categoriesAddClear"	: 1,  // (opcjonalnie) Najpierw opróżnić kategorie, do których dodajemy produkty
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "productCategories",
			"ok"	: 3,  // Liczba zmodyfikowanych produktów
		},
		...
	]
}

productRepricing - Masowe przypisywanie produktów do reguły cenowej

Przypisz do 100 000 produktów do jednej reguły cenowej.
Działa tak samo jak akcja productEdit, jednak przy limicie 1000 akcji na żądanie przypisanie 50 000 produktów wymagałoby 50 żądań i trwałoby znacznie dłużej.
Jeśli zmieniasz tylko kilka produktów, rozważ użycie akcji productEdit.
{ "actions" : [
	...
	{
		"a"			: "productRepricing",
		"repricingRule"		: "The Rule Name",  // Wielkość liter bez znaczenia; "" (pusty, ale istniejący ciąg) oznacza brak reguły (wyłączenie automatycznej zmiany cen)
		"products"		: ["REF-CODE-1", "REF-CODE-2"],  // Wielkość liter bez znaczenia (limit 100 000)
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"		: "productRepricing",
			"ok"		: 10,  // Liczba zmodyfikowanych produktów
			// Jeśli wszystkie produkty były już przypisane do tej reguły, wynik to ok=0.
		},
		...
	]
}

productDelete - Usunięcie jednego lub wielu produktów

OSTRZEŻENIE: Produkt i jego adresy URL konkurentów zostaną natychmiast i nieodwracalnie usunięte z konta.
To ta sama funkcja, z której korzysta interfejs: otwórz All Products, zaznacz jeden lub więcej produktów i kliknij Selected Products > Delete.
{ "actions" : [
	...
	{
		"a"	: "productDelete",
		"code"	: "REF-CODE",  // Wielkość liter bez znaczenia (ciąg znaków), LUB:
		"code"	: ["REF-CODE-1", "REF-CODE-2"],  // Może też być tablicą wielu produktów do usunięcia (limit 100 000)
		"deleteEmptyCategories"	: 1,  // W ten sposób każda kategoria, która stanie się pusta
		// również zostanie usunięta w wyniku skasowania tych produktów.
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "productDelete",
			"ok"	: 2,  // Liczba pomyślnie usuniętych produktów
		},
		...
	]
}

productGet - Pobranie produktu

{ "actions" : [
	...
	{
		"a"			: "productGet",
		"code"			: "REF-CODE",  // Wielkość liter bez znaczenia
		"currency"		: "EUR",  // (opcjonalnie) Przeliczyć wszystkie kwoty na tę walutę zamiast na walutę ceny produktu
		"withStats"		: 1,  // (opcjonalnie) Zwrócić obiekt statystyk
		"noCompetitors"		: 1,  // (opcjonalnie) Nie zwracać tablicy konkurentów (aby zmniejszyć ilość danych)
		"noComments"		: 1,  // (opcjonalnie) Nie zwracać komentarzy (...)
		"withScreenshots"	: 1,  // (opcjonalnie) Zwrócić URL najnowszego zrzutu ekranu każdego konkurenta
		"sickMax"		: 2,  // (opcjonalnie, domyślnie 1) 0–3: zwrócić tylko adresy URL konkurentów z poziomem problemów nie większym niż N
	},
	...
] }
Zwraca wszystkie informacje o produkcie, w tym aktualne ceny i stany magazynowe konkurentów.
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"			: "productGet",
			"ok"			: 1,
			"code"			: "REF-CODE",
			"name"			: "The Product Name",
			"price"			: 1234.90,  // Twoja cena, zawsze w oryginalnej walucie
			"currency"		: "USD",  // Oryginalna waluta pola "price"
			"convCurrency"		: "EUR",  // Waluta przeliczonych kwot (podana "currency" lub waluta ceny produktu)
			"priceConv"		: 1234.90,  // Twoja cena przeliczona według "convCurrency" lub taka sama jak "price"
			"cost"			: 1234.90,
			"costCurrency"		: "USD",
			"costPriceConv"		: 1234.90,  // Twój koszt przeliczony na walutę pola "currency"
			"costConv"		: 1234.90,  // Twój koszt przeliczony na "convCurrency"
			"margin"		: 10.5,  // Wartość procentowa (może być ujemna)
			"repricingRule"		: "The Rule Name",  // Te 3 zmienne automatycznej zmiany cen NIE WYSTĘPUJĄ, gdy nie ustawiono reguły.
			"reprice"		: 1234.90,  // Aktualna kwota obliczona na podstawie repricingRule
			"repriceCurrency"	: "USD",  // To samo co "convCurrency", powtórzone dla przejrzystości
			"myWebsite"		: "https://...",
			"created"		: 1234567890,  // Czas utworzenia produktu (Unix epoch)
			"createdBy"		: "SOMEUSER",  // Nazwa użytkownika albo "API"
			"edited"		: 1234567890,  // Czas ostatniej edycji (jeśli była; Unix epoch)
			"editedBy"		: "SOMEUSER",  // Nazwa użytkownika albo "API"
			"comments"		: "Some comments\nAnd another line",
			"commentsLast"		: 1234567890,  // Czas ostatniej edycji komentarzy (jeśli była; Unix epoch)
			"commentsLastBy"	: "SOMEUSER",  // Nazwa użytkownika albo "API"
			"categories"		: ["The Category 1", "The Category 2"],
			"stats"		: {
				// Statystyki uwzględniają tylko adresy URL konkurentów o poziomie problemów 0 lub 1, niezależnie od "sickMax".
				// Wszystkie kwoty są w "convCurrency", czyli w podanej "currency" lub oryginalnej walucie produktu.
				// OSTRZEŻENIE: Jeśli brak kwoty (np. compIn* bez konkurentów z dostępnym towarem), wartość wynosi 0.
				"rank"			: 1.23,  // Twoja pozycja cenowa (1 = nikt nie jest tańszy)
				"rankIn"		: 1.23,  // Twoja pozycja wśród konkurentów mających towar na stanie
				"compCount"		: 3,  // Liczba konkurentów z prawidłową ceną
				"compInCount"		: 3,  // Liczba konkurentów z dostępnym towarem ...
				"compOutCount"		: 3,  // Liczba konkurentów bez towaru ...
				"compAvg"		: 123.56,  // Średnia wszystkich konkurentów
				"compAvgVsMe"		: 123.56,  // Różnica (w convCurrency) między Twoją ceną a średnią konkurentów (ujemna = jesteś tańszy)
				"compInAvg"		: 123.56,  // Średnia konkurentów mających towar na stanie
				"compInAvgVsMe"		: 123.56,  // Jak "compAvgVsMe", ale tylko konkurenci z dostępnym towarem
				"compLowest"		: 123.56,  // Najniższa cena konkurenta
				"compLowestVsMe"	: 123.56,  // Jak "compAvgVsMe", ale dla najniższej ceny zamiast średniej
				"compInLowest"		: 123.56,  // Najniższa cena konkurenta z dostępnym towarem
				"compInLowestVsMe"	: 123.56,  // Jak "compInAvgVsMe", ale ...
				"compHighest"		: 123.56,  // Najwyższa cena konkurenta
				"compHighestVsMe"	: 123.56,  // Jak "compAvgVsMe", ale ...
				"compInHighest"		: 123.56,  // Najwyższa cena konkurenta z dostępnym towarem
				"compInHighestVsMe"	: 123.56,  // Jak "compInAvgVsMe", ale ...
			},
			"competitors"	: [
				// Tablica konkurentów (od najtańszego), każdy jako osobny obiekt:
				...
				{
					"url"		: "https://...",  // Wraz z ewentualnym modyfikatorem po #
					"ref"		: "example.com/123abc...def",
					// Identyfikator URL (domena główna i 32-znakowy skrót MD5). Tak identyfikujemy adresy URL wewnętrznie.
					"domain"	: "example.com",  // Domena główna konkurenta
					"price"		: 1234.90,  // Ostatnia cena znaleziona na stronie (po ewentualnych obliczeniach według ustawień)
					"currency"	: "USD",  // Waluta wykryta na stronie
					"priceConv"	: 1234.90,  // Cena przeliczona na "convCurrency"
					"stock"		: "5",  // Dostępność (ciąg znaków): "A" = dostępny, "2" = 2 sztuki na stanie, "0" = brak, "" = nie wiadomo.
					"salesWk"	: 123,  // Szacowana sprzedaż tygodniowa (jeśli dostępna; zobacz pomoc pod znakiem zapytania na stronie produktu)
					"screenshotURL"	: "https://pricezag.com/.../screenshot.png",
					// Jeśli "withScreenshots", URL najnowszego zrzutu ekranu (bez logowania, publiczny dostęp przez ten długi adres URL)
					"confidence"	: 98,
					// Procent pewności, że wybrano właściwą cenę (zobacz ikonę (?) na stronie produktu)
					// Poniżej 70% (wartość konfigurowalna) cena jest oznaczana jako "niepewna" znakiem zapytania.
					// Nie zależy to od poziomu problemów URL. Adres może być problematyczny, ale cena poprawna,
					// albo adres działa, lecz nie mamy pewności, czy na stronie wybrano właściwą cenę.
					"sick"		: 0,  // Poziom problemów adresu URL od 0 do 3
					// 0: Ostatnie pobranie się powiodło (otworzyliśmy stronę i znaleźliśmy cenę).
					// 1: Ostatnie pobranie się nie powiodło, ale niedawno było udane (częsta sytuacja, bez powodu do obaw).
					// 2: Nie udało się uzyskać prawidłowej ceny od wielu dni.
					// 3: Nie udało się uzyskać prawidłowej ceny od wielu tygodni.
					// UWAGA: Pola "price" i "priceConv" występują tylko dla adresów URL z poziomem problemów do 1. Dla poziomów 2 i 3 ceny nie ma.
				},
				...
			],
			"custom"	: {
				// To Twoje pola niestandardowe. Jeśli nie wiesz, jak działają, otwórz
				// stronę produktu w interfejsie i kliknij ikonę (?) przy sekcji CUSTOM FIELDS.
				// Jeśli nie ma takich pól, cały obiekt "custom" nie występuje.
				"variable_1"	: "value 1",  // Wartości zawsze są ciągami znaków, nawet gdy oznaczają liczby.
				"variable_2"	: "value 2",  // Nie ma pustych wartości, ponieważ spowodowałoby to usunięcie zmiennej.
				...
			}
		},
		...
	]
}

productGetAll - Pobranie wszystkich produktów

Upewnij się, że ustawienie timeout jest odpowiednio wysokie, ponieważ czas odpowiedzi serwera zależy od liczby produktów i konkurentów.
{ "actions" : [
	...
	{
		"a"			: "productGetAll",
		"currency"		: "EUR",  // (opcjonalnie) Przeliczyć wszystkie kwoty na tę walutę zamiast na waluty cen poszczególnych produktów
		"withStats"		: 1,  // (opcjonalnie) Zwrócić obiekt statystyk
		"noCompetitors"		: 1,  // (opcjonalnie) Nie zwracać tablicy konkurentów (aby zmniejszyć ilość danych)
		"noComments"		: 1,  // (opcjonalnie) Nie zwracać komentarzy (...)
		"withScreenshots"	: 1,  // (opcjonalnie) Zwrócić URL najnowszego zrzutu ekranu każdego konkurenta
		"sickMax"		: 2,  // (opcjonalnie, domyślnie 1) 0–3: zwrócić tylko adresy URL konkurentów z poziomem problemów nie większym niż N
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"		: "productGetAll",
			"ok"		: 10,  // Łączna liczba produktów
			"products"	: [ // Tablica produktów (alfabetycznie według kodu referencyjnego), każdy jako obiekt:
				...
				{ ... },  // Obiekt produktu taki sam jak odpowiedź akcji productGet (powyżej)
				...
			],
		},
		...
	]
}
Może Ci się również przydać akcja categoryGet.

Kategorie

categoryCreate - Utworzenie nowej kategorii

To ta sama funkcja, z której interfejs korzysta na stronie Categories, gdy klikniesz przycisk New Category. API pozwala dodatkowo przypisać produkty podczas tworzenia kategorii.
W przeciwieństwie do innych akcji (np. productCreate przyjmuje zarówno istniejące, jak i nowe kategorie) ta akcja zakończy się błędem, jeśli kategoria już istnieje.
{ "actions" : [
	...
	{
		"a"		: "categoryCreate",
		"name"		: "The New Category Name",
		"name"		: ["New Category 1", "New Category 2"],  // Może też być tablicą
		"products"	: ["REF-CODE-1", "REF-CODE-2"],  // (opcjonalnie) Podczas tworzenia przypisać te produkty do tych kategorii
		"comments"	: "Some comments\nAnd another line",  // (opcjonalnie) Maksymalnie 1000 znaków UTF-8
	},
	...
] }

categoryEdit - Edycja istniejącej kategorii

Zobacz również akcję productCategories i wybierz wygodniejszą metodę.
{ "actions" : [
	...
	{
		"a"			: "categoryEdit",
		"name"			: "The Category Name",		// Wielkość liter bez znaczenia
		"newName"		: "The Category Renamed",  // (opcjonalnie)
		"products"		: ["REF-CODE-1", "REF-CODE-2"],  // (opcjonalnie) Zastąpić listę produktów
		"productsAdd"		: ["REF-CODE-1", "REF-CODE-2"],  // (opcjonalnie) Dodać te produkty do kategorii
		"productsRemove"	: ["REF-CODE-3", "REF-CODE-4"],  // (opcjonalnie) Usunąć te produkty z kategorii (NIE usuwa samych produktów)
		"comments"		: "To overwrite the comments.",  // (opcjonalnie) Maksymalnie 1000 znaków UTF-8
	},
	...
] }
Parametry "products", "productsAdd" i "productsRemove" robią zasadniczo to samo: zmieniają przynależność produktów do kategorii, ale na różne sposoby. Aby usunąć wszystkie produkty z kategorii, użyj "products" : []
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"			: "categoryEdit",
			"ok"			: 5,  // Liczba wprowadzonych zmian
			// (zmiana nazwy i edycja komentarza liczą się jako jedna zmiana; podobnie dodanie/usunięcie każdego produktu)
			"name"			: "The Category Name",  // Nowa nazwa po zmianie, w przeciwnym razie poprzednia
			"productsCount"		: 30,  // Nowa liczba produktów w kategorii (niezależnie od tego, czy się zmieniła)
			"productsAdded"		: 2,  // Liczba produktów dodanych do kategorii
			"productsRemoved"	: 2,  // Liczba produktów usuniętych z kategorii
		},
		...
	]
}

categoryDelete - Usunięcie jednej lub wielu kategorii

To ta sama funkcja, z której korzysta interfejs: otwórz Categories, zaznacz jedną lub więcej kategorii i kliknij Selected Categories > Delete.
{ "actions" : [
	...
	{
		"a"			: "categoryDelete",
		"name"			: "The Category Name",  // Wielkość liter bez znaczenia (ciąg znaków), LUB:
		"name"			: ["Category 1", "Category 2"],  // Może też być tablicą wielu kategorii do usunięcia (maksymalnie 1000)
		"deleteProducts"	: 1,
		// Domyślnie kategoria jest usuwana, a produkty przestają do niej należeć,
		// ale przy deleteProducts wszystkie produkty w kategorii są usuwane bez potwierdzenia,
		// a wraz z nimi adresy URL konkurentów, bez możliwości przywrócenia!
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"			: "categoryDelete",
			"ok"			: 2,  // Liczba usuniętych kategorii
			"productsCount"		: 123,  // Liczba produktów należących do tych kategorii
			"productsDeleted"	: 123,  // Liczba produktów usuniętych w wyniku opcji "deleteProducts"
			// UWAGA: Produkt należący do kilku wskazanych kategorii jest liczony tylko raz.
		},
		...
	]
}

categoryCopy - Kopiowanie/przenoszenie produktów między kategoriami

Kopiuj lub przenoś produkty z wybranych kategorii do innych, nowych lub istniejących kategorii. Możesz w ten sposób również SCALAĆ kategorie (zobacz przykłady na końcu strony).
Ta akcja nie usuwa żadnych produktów, a jedynie zmienia ich przypisanie do kategorii.
To ta sama funkcja, z której korzysta interfejs: otwórz Categories, zaznacz jedną lub więcej kategorii i kliknij Selected Categories > Copy & More. Szczegółowy opis tej funkcji znajdziesz w interfejsie.
{ "actions" : [
	...
	{
		"a"			: "categoryCopy",
		"categoriesFrom"	: ["Category 1", "Category 2"],  // Wybrać produkty z tych kategorii źródłowych
		"removeMode"		: "cat",  // (opcjonalnie) Usunąć pasujące produkty ze wskazanych "categoriesFrom"
		"removeMode"		: "all",  // (opcjonalnie) Usunąć pasujące produkty ze wszystkich kategorii, do których należą
		// Bez removeMode produkty pozostaną w "categoriesFrom" i zostaną też dodane do "categoriesTo" (kopiowanie zamiast przenoszenia).
		"deleteMode"		: "cat",  // (opcjonalnie) Po skopiowaniu produktów usunąć wskazane "categoriesFrom"
		"deleteMode"		: "all",  // (opcjonalnie) Usunąć wszystkie kategorie, do których należą te produkty
		// Bez deleteMode kategorie "categoriesFrom" pozostaną, nawet gdy produkty usunięto z nich przez "removeMode".
		"categoriesTo"		: ["Another Category 1", "Another Category 2"],
		// Umieścić wszystkie pasujące produkty w tych kategoriach docelowych (nieistniejące zostaną utworzone)
		"categoriesToClear"	: 1,  // (opcjonalnie) Najpierw opróżnić kategorie, do których dodajemy produkty
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"			: "categoryCopy",
			"ok"			: 3,  // Liczba zmienionych kategorii (źródłowych i docelowych)
			// "ok" to suma categoriesModified + categoriesCreated + categoriesDeleted
			"categoriesModified"	: 2,  // Liczba zmienionych istniejących kategorii (źródłowych i docelowych)
			"categoriesCreated"	: 1,  // Liczba nowo utworzonych kategorii
			"categoriesDeleted"	: 0,  // Liczba kategorii usuniętych przez "deleteMode"
			"productsCount"		: 123,  // Liczba produktów pasujących do wskazanych "categoriesFrom"
			// UWAGA: Produkt należący do kilku wskazanych "categoriesFrom" jest liczony tylko raz.
		},
		...
	]
}

categoryGet - Pobranie kategorii

{ "actions" : [
	...
	{
		"a"		: "categoryGet",
		"name"		: "The Category Name",  // Wielkość liter bez znaczenia
		"currency"	: "EUR",  // (WYMAGANE przy withStats lub withProducts) Waluta statystyk
		"withStats"	: 1,  // Zwrócić również statystyki (wolniejsze)
		"withProducts"	: 1,  // Zwrócić również produkty tej kategorii (możliwa duża ilość danych)
		"noCompetitors"	: 1,  // Przy withProducts nie zwracać tablicy konkurentów (mniej danych)
		"noComments"	: 1,  // Przy withProducts nie zwracać komentarzy produktów (komentarze kategorii pozostają)
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"			: "categoryGet",
			"ok"			: 1,
			"name"			: "The Category Name",
			"created"		: 1234567890,  // Czas Unix epoch
			"createdBy"		: "SOMEUSER",  // Nazwa użytkownika albo "API"
			"comments"		: "Comments of this category",
			"commentsLast"		: 1234567890,  // Czas ostatniej edycji komentarzy (jeśli była; Unix epoch)
			"commentsLastBy"	: "SOMEUSER",  // Nazwa użytkownika albo "API"
			"productsCount"		: 10,  // Liczba produktów w tej kategorii
			"stats"		: {
				// Te statystyki są takie same jak na stronie kategorii w interfejsie oraz w kolumnach listy kategorii.
				// Szczegóły znajdziesz, dodając odpowiednią kolumnę do listy i klikając (?).
				// Wszystkie kwoty są w walucie "currency" podanej w żądaniu.
				// OSTRZEŻENIE: Jeśli brak kwoty (np. compIn* bez konkurentów z dostępnym towarem), wartość wynosi 0.
				"priceAvg"		: 123.45,  // Twoja średnia cena
				"costAvg"		: 123.45,  // Do tej średniej wliczane są tylko produkty z podanym kosztem
				"marginAvg"		: 10.5,  // Wartość procentowa (może być ujemna, liczą się tylko produkty z podanym kosztem)
				"rankAvg"		: 1.23,  // Twoja średnia pozycja cenowa (1 = nikt nie jest tańszy)
				"rankInAvg"		: 1.23,  // Twoja średnia pozycja wśród konkurentów mających towar
				"productsCountComp"	: 9,  // Liczba produktów mających konkurentów
				"productsCountCompIn"	: 7,  // Liczba produktów mających konkurentów z dostępnym towarem
				"compAvg"		: 123.56,  // Średnia ze średnich wszystkich konkurentów
				"compAvgVsMe"		: 123.56,  // Średnia różnica (w walucie) między Twoją ceną a konkurentami (ujemna = jesteś tańszy)
				"compInAvg"		: 123.56,  // Jak "compAvg", ale tylko konkurenci z dostępnym towarem
				"compInAvgVsMe"		: 123.56,  // Jak "compAvgVsMe", ale tylko konkurenci z dostępnym towarem
				"compLowest"		: 123.56,  // Jak "compAvg", ale średnia z najniższych cen konkurentów dla każdego produktu
				"compLowestVsMe"	: 123.56,  // Jak "compAvgVsMe", ale ...
				"compInLowest"		: 123.56,  // Jak "compInAvg", ale ...
				"compInLowestVsMe"	: 123.56,  // Jak "compInAvgVsMe", ale ...
				"compHighest"		: 123.56,  // Jak "compAvg", ale średnia z najwyższych cen konkurentów dla każdego produktu
				"compHighestVsMe"	: 123.56,  // Jak "compAvgVsMe", ale ...
				"compInHighest"		: 123.56,  // Jak "compInAvg", ale ...
				"compInHighestVsMe"	: 123.56,  // Jak "compInAvgVsMe", ale ...
			},
			"products"	: [ // Tablica produktów (alfabetycznie według kodu referencyjnego), każdy jako obiekt:
				...
				{ ... },  // Obiekt produktu jak w odpowiedzi akcji productGet
				...
			],
		},
		...
	]
}

categoryGetAll - Pobranie wszystkich kategorii

W przeciwieństwie do akcji categoryGet akcja categoryGetAll nie zwraca szczegółowego obiektu dla każdego produktu. Ten sam produkt może należeć do wielu kategorii, więc odpowiedź byłaby bardzo duża i pełna powtórzeń. Jeśli potrzebujesz danych produktów, użyj categoryGet dla każdej kategorii albo productGetAll i posortuj wyniki według kategorii.
{ "actions" : [
	...
	{
		"a"		: "categoryGetAll",
		"withStats"	: 1,  // Zwrócić również statystyki (wolniejsze)
		"noComments"	: 1,  // Nie zwracać komentarzy (mniejsza ilość danych)
		"noProducts"	: 1,  // Nie zwracać tablicy produktów (...)
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"		: "categoryGetAll",
			"ok"		: 10,  // Łączna liczba kategorii (długość tablicy "categories")
			"categories"	: [ // Tablica kategorii (alfabetycznie), każda jako obiekt:
				...
				{
					"name"			: "The Category Name",
					"created"		: 1234567890,  // Czas Unix epoch
					"createdBy"		: "SOMEUSER",  // Nazwa użytkownika albo "API"
					"comments"		: "Comments of this category",
					"commentsLast"		: 1234567890,  // Czas ostatniej edycji komentarzy (jeśli była; Unix epoch)
					"commentsLastBy"	: "SOMEUSER",  // Nazwa użytkownika albo "API"
					"productsCount"		: 2,  // Liczba produktów w tej kategorii
					"products"	: ["REF-CODE-1", "REF-CODE-2"],  // Kody referencyjne jej produktów (alfabetycznie), pominięte przy noProducts=1
					"stats"		: {
						// Przy "withStats" ten sam obiekt statystyk co w categoryGet (powyżej)
						...
					},
				}
				...
			],
		},
		...
	]
}

Alerty cenowe

alertRecipientCreate - Utworzenie nowego odbiorcy alertów

To ta sama funkcja, z której korzysta interfejs: otwórz Alerts i kliknij przycisk New Recipient.
Szczegóły każdego pola znajdziesz po kliknięciu zielonej ikony ze znakiem zapytania na koncie.
{ "actions" : [
	...
	{
		"a"		: "alertRecipientCreate",
		"email"		: "john@example.net",  // Może też być numer telefonu do alertów SMS; zobacz pomoc w interfejsie
		"name"		: "john",  // Prosta wyświetlana nazwa (zwykle imię; wielkość liter bez znaczenia)
		"maxFrequency"	: 1800,  // (opcjonalnie, domyślnie 7200) Zobacz pomoc w interfejsie
		"simplify"	: 0,  // (opcjonalnie, domyślnie 1) Włączyć uproszczenie (zobacz pomoc w interfejsie)
		"sleepEnabled"	: 1,  // (opcjonalnie) Włączyć okres ciszy
		"sleepFrom"	: "18:30",  // (tylko przy sleepEnabled) Format 24-godzinny
		"sleepTo"	: "07:00",  // (tylko przy sleepEnabled) Format 24-godzinny
		"timezone"	: "America/Los_Angeles",  // (tylko przy sleepEnabled) Format ścieżki pliku Linuksa /usr/share/zoneinfo
				// Spacje zostaną zamienione na podkreślenia.
				// Sprawdź dokładną nazwę strefy czasowej w formularzu [New Recipient] w interfejsie.
		"status"	: "hold",  // (opcjonalnie) Ustawić tryb "hold" lub "disable". Każda inna wartość (np. "") oznacza aktywność.
		"rules"		: [...],  // (opcjonalnie) Początkowe reguły alertów (tablica obiektów), jak "rulesAdd" w alertRecipientEdit poniżej
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "alertRecipientCreate",
			"ok"	: 1,
		},
		...
	]
}

alertRecipientEdit - Edycja odbiorcy alertów i jego reguł

To ta sama funkcja, z której korzysta interfejs: otwórz Alerts i kliknij przycisk Settings lub Rules dla danego odbiorcy.
Szczegóły każdego pola znajdziesz po kliknięciu zielonej ikony ze znakiem zapytania na koncie.
Strona "email" wskazuje, który odbiorca ma zostać zmodyfikowany. Pozostałe pola zmieniają jego ustawienia.
{ "actions" : [
	...
	{
		"a"		: "alertRecipientEdit",
		"email"		: "john@example.net",  // Bieżący e-mail lub numer telefonu (dokładnie w formacie zwracanym przez alertGetAll)
		"newEmail"	: "john2@example.net",  // (opcjonalnie) Nowy e-mail lub numer telefonu; zobacz pomoc w interfejsie
		"name"		: "john2",  // (opcjonalnie) Nowa nazwa
		"maxFrequency"	: 1800,  // (opcjonalnie) Zobacz pomoc w interfejsie
		"simplify"	: 1,  // (opcjonalnie) Włączyć uproszczenie (zobacz pomoc w interfejsie)
		"sleepEnabled"	: 1,  // (opcjonalnie) Włączyć okres ciszy
		"sleepFrom"	: "18:30",  // (tylko przy sleepEnabled) Format 24-godzinny
		"sleepTo"	: "07:00",  // (tylko przy sleepEnabled) Format 24-godzinny
		"timezone"	: "America/Los_Angeles",  // (tylko przy sleepEnabled) Zobacz akcję alertRecipientCreate powyżej
		"status"	: "hold",  // (opcjonalnie) Ustawić tryb "hold" lub "disable". Inna wartość (np. "") ustawi "active".
		"rules"		: [{ruleObject}, {ruleObject}],  // (opcjonalnie) Zastąpić wszystkie istniejące reguły (pusta tablica usunie wszystkie)
				  // Jeśli chcesz zachować istniejące reguły, nie podawaj tablicy "rules".
		"rulesAdd"	: [ // (opcjonalnie) Dodać te reguły do istniejących
			...
			{  // TO JEST FORMAT OBIEKTU REGUŁY:
				"name"		: "me_cross_avg",  // Na stronie Alerts wybierz [Rules] > [+ New Rule], a następnie regułę, aby zobaczyć jej nazwę API.
				"disabled"	: 1,  // (opcjonalnie) Tworzenie wyłączonej reguły nie ma większego sensu, ale akcja alertRuleEdit poniżej może z tego korzystać
				"var_n"		: 123.00,  // Zmienna "X" staje się "var_x",
				"var_c"		: "USD",  // ... więc podaj tu parametry wymagane przez regułę,
				"var_h"		: 24,  // ... (niektóre reguły nie mają żadnych zmiennych).
				"direction"	: "both",  // Albo "drop" lub "rise", jeśli reguła ma kierunek
				"categories"	: ["The Category 1", "The Category 2"],  // (opcjonalnie) Puste lub pominięte oznacza WSZYSTKIE PRODUKTY
				"ignoreOos"	: 1,  // (opcjonalnie) Ignorować konkurentów bez towaru (zobacz interfejs)
				"urlInclude"	: "",  // (opcjonalnie, wielkość liter bez znaczenia)
				"urlExclude"	: "amazon",  // (opcjonalnie, wielkość liter bez znaczenia)
				// Każda reguła ma identyfikator "ruleNumber" (np. do późniejszej edycji lub usunięcia).
				// Znajdziesz go w zwracanych obiektach reguł, ale nie możesz go samodzielnie ustawić.
			}
			...
		],
		"rulesRemove"	: [1,4,7],  // (opcjonalnie) "ruleNumber" reguł do usunięcia
					// To "ruleNumber" otrzymasz z akcji alertGetAll poniżej.
					// UWAGA: Aby usunąć wszystkie reguły, użyj "rules" = [].
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "alertRecipientEdit",
			"ok"	: 3,  // Liczba zmian (zmienne + liczba dodanych/usuniętych reguł)
		},
		...
	]
}

alertRecipientDelete - Usunięcie odbiorcy alertów

Ta operacja jest nieodwracalna. Wszystkie reguły alertów danego odbiorcy i ich historia zostaną natychmiast usunięte bez możliwości przywrócenia.
{ "actions" : [
	...
	{
		"a"		: "alertRecipientDelete",
		"email"		: "john@example.net",  // Bieżący e-mail lub numer telefonu (dokładnie w formacie zwracanym przez alertGetAll)
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "alertRecipientDelete",
			"ok"	: 1,
		},
		...
	]
}

alertRuleEdit - Edycja istniejącej reguły alertu

Pozwala edytować pojedynczą istniejącą regułę alertu zamiast zastępować lub dodawać reguły. Typowe zastosowania to zmiana zmiennej N albo włączenie lub wyłączenie reguły.
Aby usunąć regułę, użyj tablicy "rulesRemove" w akcji alertRecipientEdit, a aby dodać regułę, użyj tam tablicy "rulesAdd".
{ "actions" : [
	...
	{
		"a"		: "alertRuleEdit",
		"email"		: "john@example.net",  // E-mail lub numer telefonu odbiorcy (dokładnie w formacie zwracanym przez alertGetAll)
		"ruleNumber"	: 1,  // Numer referencyjny reguły do edycji, zwracany przez alertGetAll poniżej
		"rule"		: {
			// Zmienne reguły do zastąpienia. Format obiektu reguły opisuje "rulesAdd" w alertRecipientEdit powyżej.
			"disabled"	: 1,  // Na przykład do włączenia/wyłączenia reguły
			"var_n"		: 5,  // Lub dowolna inna zmienna, np. N zależnie od typu reguły
			...
		},
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "alertRuleEdit",
			"ok"	: 1,  // Liczba zmienionych zmiennych
		},
		...
	]
}

alertGetAll - Pobranie odbiorców alertów i ich reguł

{ "actions" : [
	...
	{
		"a"	: "alertGetAll",
		// Ta akcja nie przyjmuje żadnych parametrów.
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"		: "alertGetAll",
			"ok"		: 3,  // Liczba odbiorców (długość tablicy "recipients")
			"recipients"	: [ // Tablica wszystkich odbiorców; każdy obiekt ma format jak w alertRecipientCreate powyżej
				...
				{
					"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"		: [ // Tablica reguł; każdy obiekt ma format opisany w alertRecipientEdit powyżej
						...
						{
							"ruleNumber"	: 4,  // Numer referencyjny do edycji tej reguły przez alertRuleEdit powyżej
							"name"		: "me_cross_avg",
							"disabled"	: 0,
							"var_n"		: "123.00",  // UWAGA: Wszystkie zmienne zwracamy jako ciągi znaków, nawet jeśli są liczbami.
							"var_c"		: "USD",
							"var_h"		: "24",
							"direction"	: "both",
							"categories"	: [],  // Pusta wartość oznacza wszystkie produkty
							"ignoreOos"	: 0,
							"urlInclude"	: "",
							"urlExclude"	: "amazon",
						}
						...
					],
				}
				...
			],
		},
		...
	]
}

Reguły automatycznej zmiany cen

repricingCreate - Utworzenie nowej reguły cenowej

To ta sama funkcja, z której korzysta interfejs: otwórz Repricing i kliknij przycisk New Repricing Rule.
Szczegóły każdego pola znajdziesz po kliknięciu zielonej ikony ze znakiem zapytania na koncie.
Jak przypisać produkty do reguły? Edytując produkty za pomocą akcji productEdit lub productRepricing. Sama reguła nie „zawiera” produktów; to produkty wskazują, z której reguły korzystają.
{ "actions" : [
	...
	{
		"a"	: "repricingCreate",
		"name"	: "The Rule Name",  // Maksymalnie 50 znaków
		"init"	: { // Obiekt reguły początkowej (pierwszy wiersz "Set my price to")
			"target"	: "cheapest_n",  // (zobacz listę poniżej)
			"var_n"		: 3,  // Tylko jeśli cel wymaga zmiennej N
			"plusAmount"	: -2,  // Wartość dodatnia oznacza powyżej, ujemna poniżej
			"plusCurrency"	: "%",  // Waluta (np. "USD") lub "%"
			// Odpowiada ustawieniu „Ustaw moją cenę o 2% poniżej średniej trzech najtańszych konkurentów”.
			// OSTRZEŻENIE: W odróżnieniu od obiektów "never" poniżej reguła początkowa nie ma pola "direction". Kierunek określa znak "plusAmount".
		},
		"never"	: [ // (opcjonalnie) Obiekty warunków „ale nigdy”, wykonywane po kolei (maksymalnie 0–10)
			{
				"target"	: "cheapest_n_in",  // (zobacz listę poniżej)
				"var_n"		: 1,  // Tylko jeśli cel wymaga zmiennej N
				"direction"	: "below",  // Lub "above"
				"plusAmount"	: -10,  // Wartość dodatnia oznacza dodawanie, ujemna odejmowanie (wymagane nawet przy 0)
				"plusCurrency"	: "USD",  // Waluta lub "%" (wymagane nawet przy plusAmount=0)
				// Odpowiada ustawieniu „Ale nigdy poniżej ceny najtańszego konkurenta z towarem na stanie minus 10,00 USD”.
			},
			{
				"target"	: "cost",
				"direction"	: "below",
				"plusAmount"	: 5,
				"plusCurrency"	: "%",
				// Odpowiada ustawieniu „Ale nigdy poniżej mojego kosztu plus 5%”.
			}
		],
		"ignoreDomains"	: "amazon ebay.com MyLabel1",  // (opcjonalnie) Domeny i/lub etykiety konkurentów do ignorowania (wielkość liter bez znaczenia; zobacz interfejs)
		"charm"		: "none|zeros|charm",  // (opcjonalnie, domyślnie "none") Ceny psychologiczne ("", "none" i pominięcie oznaczają to samo)
		"confidence"	: 82,  // (opcjonalnie, domyślnie 70) Minimalny poziom pewności 0–99% (zobacz interfejs)
		"disabled"	: 1,  // (opcjonalnie)
	},
	...
] }
// ========== Wszystkie dostępne wartości "target": ==========
// "average" : Średnia wszystkich konkurentów
// "average_in" : Średnia wszystkich konkurentów mających towar
// "cheapest_n" : Średnia N najtańszych konkurentów (lub „najtańszy”, jeśli N=1)
// "cheapest_n_in" : Średnia N najtańszych konkurentów z dostępnym towarem (lub ...)
// "highest_n" : Średnia N najdroższych konkurentów (lub ...)
// "highest_n_in" : Średnia N najdroższych konkurentów z dostępnym towarem (lub ...)
// "cost" : Mój koszt
// "me_avg_n" : Średnia mojej ceny z ostatnich N godzin (ogranicza szybkość zmian ceny)
// "domain:example.com" : Cena z example.com (najniższa przy wielu adresach tej domeny)
// "domainIn:example.com" : Cena z example.com tylko przy dostępności towaru (...)
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "repricingCreate",
			"ok"	: 3,  // Liczba pomyślnie przetworzonych i zapisanych obiektów (np. init + never[0] + never[1] = 3)
			"name"	: "The Rule Name",  // Ostateczna nazwa w bazie danych (możemy zmienić znaki specjalne)
		},
		...
	]
}

repricingEdit - Edycja istniejącej reguły cenowej

Modyfikuje istniejącą regułę cenową.
Zobacz repricingCreate powyżej, aby dowiedzieć się, jak działają te zmienne.
Zmienia samą regułę, a nie przypisane do niej produkty. Aby przypisać produkty do reguł, użyj akcji productEdit lub productRepricing.
{ "actions" : [
	...
	{
		"a"		: "repricingEdit",
		"name"		: "The Rule Name",  // Wielkość liter bez znaczenia
		"newName"	: "The Rule Renamed",  // (opcjonalnie) Maksymalnie 50 znaków
		"init"		: { // (opcjonalnie) Jeśli podano, zastąpić wybrane zmienne reguły początkowej (zobacz repricingCreate)
			"plusAmount"	: 1,  // Możesz na przykład zastąpić tylko "plusAmount", pozostawiając inne zmienne bez zmian.
			// OSTRZEŻENIE: Jeśli nowy "target" wymaga zmiennej N, pamiętaj o "var_n".
		},
		"never"		: [...], // (opcjonalnie) Możesz zastąpić całą tablicę "never", ale zwykle lepiej użyć never_*.
		// "never":[] usunie wszystkie istniejące warunki. Pominięcie tej zmiennej zachowa je.
		"never_0"	: { // (opcjonalnie) Zastąpić pierwszy obiekt „ale nigdy” (indeks tablicy 0)
			"var_n"		: 2,  // Możesz na przykład zmienić tylko "var_n", pozostawiając pozostałe zmienne bez zmian.
		},
		"never_2"	: {
			"target"	: "",  // To wyłączy trzeci warunek „ale nigdy” (indeks tablicy 2).
			// Jeśli ustawisz "target" na "", pozostałe zmienne obiektu nie mają znaczenia.
			// "never_2":{} działa tak samo.
		},
		"never_6"	: {...}, // Może to być nowy warunek „ale nigdy”, wymagający wszystkich zmiennych tak jak w repricingCreate.
		// "never_9" to maksimum, ponieważ tablica "never" może mieć najwyżej 10 elementów.
		"ignoreDomains"	: "",  // (opcjonalnie) Tak samo jak w repricingCreate
		"charm"		: "zeros",  // (opcjonalnie) ...
		"confidence"	: 82,  // (opcjonalnie) ...
		"disabled"	: 1,  // (opcjonalnie) Ustaw 0, aby włączyć obecnie wyłączoną regułę
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "repricingEdit",
			"ok"	: 3,  // Liczba zmian (np. jedna zmienna w obiekcie never_N + inna w "init" + "charm")
			"name"	: "The Rule Name",  // Ostateczna (nowa) nazwa w bazie danych (możemy zmienić znaki specjalne)
		},
		...
	]
}

repricingDelete - Usunięcie reguły cenowej

Ta operacja jest nieodwracalna. Reguła zostanie natychmiast i nieodwracalnie usunięta z konta. Produkty, które z niej korzystały, pozostaną bez reguły, a ich automatyczna zmiana cen przestanie działać.
{ "actions" : [
	...
	{
		"a"		: "repricingDelete",
		"name"		: "The Rule Name",  // Wielkość liter bez znaczenia
		"onlyIfUnused"	: 1,  // (opcjonalnie) Dla bezpieczeństwa można wywołać błąd, jeśli z reguły korzystają produkty
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"		: "repricingDelete",
			"ok"		: 1,
			"productsCount"	: 10,  // Liczba produktów, które korzystały z tej reguły (a teraz nie mają żadnej)
		},
		...
	]
}

repricingGetAll - Pobranie wszystkich reguł cenowych

Najpierw przeczytaj część repricingCreate powyżej, ponieważ format odpowiedzi jest bardzo podobny do danych wysyłanych w żądaniu repricingCreate.
{ "actions" : [
	...
	{
		"a"	: "repricingGetAll",
		// Ta akcja nie przyjmuje innych parametrów
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "repricingGetAll",
			"ok"	: 10,  // Łączna liczba reguł (długość tablicy "rules")
			"rules"	: [ // Tablica reguł cenowych (alfabetycznie), każda jako obiekt:
				...
				{
					"name"		: "Some Repricing Rule",
					"created"	: 1234567890,  // Czas utworzenia reguły (Unix epoch)
					"createdBy"	: "SOMEUSER",  // Nazwa użytkownika albo "API"
					"edited"	: 1234567890,  // Czas ostatniej edycji (jeśli była; w przeciwnym razie zmienna nie występuje)
					"editedBy"	: "SOMEUSER",  // Nazwa użytkownika lub "API" (może nie występować)
					"disabled"	: 1234567890,  // Jeśli reguła jest wyłączona, czas ostatniego wyłączenia (Unix epoch); w przeciwnym razie brak.
					"disabledBy"	: "SOMEUSER",  // Nazwa użytkownika lub "API" (może nie występować)
					"productsCount"	: 10,  // Liczba produktów obecnie korzystających z tej reguły
					"ignoreDomains"	: "amazon ebay.com MyLabel1",  // Domeny i/lub etykiety konkurentów, które są ignorowane (zobacz interfejs)
					"charm"		: "charm",  // Tryb cen psychologicznych (none|zeros|charm)
					"confidence"	: 82,  // Minimalny procent pewności 0–99 (zobacz interfejs)
					"init"	: { // Obiekt reguły początkowej (pierwszy wiersz "Set my price to")
						"target"	: "cheapest_n",  // (zobacz listę w repricingCreate)
						"var_n"		: 3,  // Jeśli cel wymaga zmiennej N; w przeciwnym razie brak
						"plusAmount"	: -2,  // Wartość dodatnia oznacza powyżej, ujemna poniżej
						"plusCurrency"	: "%",  // Waluta (np. "USD") lub "%"
						// Odpowiada ustawieniu „Ustaw moją cenę o 2% poniżej średniej trzech najtańszych konkurentów”.
						// OSTRZEŻENIE: W odróżnieniu od obiektów "never" poniżej reguła początkowa nie ma pola "direction". Kierunek określa znak "plusAmount".
					},
					"never"	: [ // Obiekty „ale nigdy”, wykonywane po kolei
						{
							"target"	: "cheapest_n_in",
							"var_n"		: 1,
							"direction"	: "below",  // Lub "above"
							"plusAmount"	: -10,  // Dodatnia oznacza dodawanie, ujemna odejmowanie
							"plusCurrency"	: "USD",  // Waluta lub "%"
							// Odpowiada ustawieniu „Ale nigdy poniżej ceny najtańszego konkurenta z towarem na stanie minus 10,00 USD”.
						},
						{},  // Oznacza to, że drugi wiersz warunków „ale nigdy” pozostał pusty.
						{
							"target"	: "cost",
							"direction"	: "below",
							"plusAmount"	: 5,
							"plusCurrency"	: "%",
							// Odpowiada ustawieniu „Ale nigdy poniżej mojego kosztu plus 5%”.
						}
					],
				}
				...
			],
		},
		...
	]
}

Arkusze kalkulacyjne

spreadsheetDownload - Pobranie arkusza kalkulacyjnego

Ta akcja jest WYJĄTKIEM: nie można łączyć jej z innymi akcjami i zamiast obiektu JSON zwraca plik arkusza (chyba że użyjesz poniżej "savePreset" lub "downloadURL")
Odpowiada temu, co możesz zrobić na stronie Export na swoim koncie.
Upewnij się, że ustawienie timeout jest odpowiednio wysoki, ponieważ tworzenie dużego arkusza może trochę potrwać.
UŁATW SOBIE PRACĘ: Kliknij przycisk Show API equivalent na stronie Export, aby wygenerować kompletne wywołanie JSON (i polecenie curl) odpowiadające ustawieniom formularza.
{ "actions" : [
	{
		"a"		: "spreadsheetDownload",
		"preset"	: "Some Preset Name",  // (opcjonalnie) Zamiast podawać wszystkie poniższe ustawienia, możesz użyć własnego lub naszego szablonu
			// W przypadku własnych ustawień podaj pełną nazwę bez nazwy użytkownika na początku i waluty na końcu.
			// Nazwy naszych domyślnych szablonów znajdziesz, rozwijając DIRECT DOWNLOAD na stronie Export i najeżdżając na poszczególne pozycje.
			// Na przykład "pricezag_backup" to specjalny szablon kopii zapasowej (zobacz "Special BACKUP format to re-import" w menu DIRECT DOWNLOAD).
			// Możesz także podać kolejne zmienne, które zastąpią ustawienia szablonu (np. inną walutę, format lub kategorie).
		"savePreset"	: "My New Preset Name",  // (opcjonalnie) Zapisać poniższe ustawienia jako nowy szablon (do użycia w interfejsie i API)
			// WYJĄTEK OD WYJĄTKU: Przy savePreset arkusz nie jest pobierany; zamiast niego zwracany jest zwykły obiekt JSON.
		"savePresetOverwrite"	: 1,  // (opcjonalnie) Zastąpić istniejący szablon podany jako "savePreset" (w przeciwnym razie błąd)
			// OSTRZEŻENIE: Zastąpienie usuwa wszystkie poprzednie ustawienia szablonu; nie próbuj zmieniać tylko jednego pola.
			// Aby zmienić nazwę lub usunąć szablon, użyj akcji spreadsheetPresetEdit poniżej.
		"downloadURL"	: 1,  // (opcjonalnie) WYJĄTEK OD WYJĄTKU: Zamiast pliku arkusza zwraca zwykłą odpowiedź JSON z polem "fileURL",
			// zawierającym publiczny URL pliku (bez logowania ani klucza API). Przez 15 minut każdy może pobrać ten plik.
			// Wartość "ok" oznacza liczbę wierszy; "fileSize" podaje rozmiar w bajtach.
		"format"	: "xlsx|xls|csv|csv-tab",  // (domyślnie csv dla API)
		"currency"	: "USD",  // (WYMAGANE bez szablonu) Waluta, w której będą WSZYSTKIE kwoty
		"categories"	: ["Category 1", "Category 2"],  // Uwzględnić tylko produkty z tych kategorii (w przeciwnym razie wszystkie)
		"historyPeriod"	: "prev_6mo",  // (opcjonalnie, domyślnie "now")
			// Najpierw przeczytaj objaśnienia okresów historycznych pod ikonami (?) na stronie Export.
			// "historyPeriod" określa, jak daleko wstecz pobierane są dane, które "historyRow" dzieli następnie na wiersze arkusza dla każdego produktu.
			// "now": Bez historii, tylko bieżące dane (bez "historyRow")
			// "all": Cała dostępna historia od rejestracji (lub przynajmniej dla danych produktów). MOŻE DZIAŁAĆ WOLNO.
			// "1234500000-1237800000": Niestandardowy okres (znaczniki Unix epoch „od–do”)
			// "123h": Ostatnie 123 godziny; bez wyrównania do pełnych godzin, koniec to teraz, a początek może wypadać w środku godziny.
			// "cur_123(d|wk|mo|yr)": Ostatnie 123 dni/tygodnie/miesiące/lata, w tym bieżący niepełny okres. "cur_2mo" pobrane 10. dnia obejmuje więc 40 dni.
			// "prev_123(d|wk|mo|yr)": Poprzednie 123 zakończone dni/tygodnie/miesiące/lata. "prev_2mo" pobrane 10 lutego obejmuje 62 dni grudnia i stycznia.
			// Początek cur_* i prev_* (oraz koniec prev_*) jest wyrównywany do poprzedniej północy, natomiast cur_* kończy się teraz;
			// dlatego "cur_2d" pobrane w południe obejmuje ostatnie 36 godzin, a "prev_2d" obejmuje 48 godzin zakończonych 12 godzin temu.
		"historyRow"	: "2w",  // (wymagane, jeśli "historyPeriod" nie jest "now")
			// "historyRow" określa okres reprezentowany przez jeden wiersz (średnia za ten okres), więc produkt może mieć wiele wierszy (z wyjątkiem "all").
			// "historyRow" można traktować jako PODZIAŁ "historyPeriod" na osobne wiersze arkusza dla każdego produktu.
			// "all": Uśrednić całe historyPeriod w jednym wierszu dla każdego produktu.
			// "123(d|wk|mo|qt|yr)": Przedział 123 dni/tygodni/miesięcy/kwartałów/lat kalendarzowych wyrównywany do północy. Przy 1 liczbę można pominąć ("wk" zamiast "1wk").
			// Jeśli pobierzesz arkusz w sobotę z historyRow:"7d", każdy wiersz będzie średnią z okresu sobota 00:00 – piątek 23:59.
			// Jeśli użyjesz historyRow:"1wk", wiersze będą średnimi od poniedziałku 00:00 do niedzieli 23:59, a ostatni wiersz obejmie bieżący niepełny tydzień poniedziałek–sobota.
			// ▶ LIMIT 500 000 WIERSZY: Interfejs i API odrzucą parametry historii powodujące utworzenie ponad 500 tys. wierszy.
			// Może do tego dojść np. przy historyRow:"day" dla długiego okresu historyPeriod, np. 365 dni × 1400 produktów.
			// Jeśli potrzebujesz tylu danych, pobieraj osobne arkusze dla kategorii liczących po kilkaset produktów.
		"timezone"	: "America/Los_Angeles",  // (opcjonalnie, domyślnie "UTC") Format ścieżki w Linuksie /usr/share/zoneinfo
			// Spacje zostaną zamienione na podkreślenia.
			// Strefa czasowa jest potrzebna tylko wtedy, gdy opcje history* używają okresów kalendarzowych (aby określić północ).
			// Interfejs korzysta ze strefy czasowej bieżącego użytkownika, ale API nie ma takiego ustawienia, dlatego trzeba podać ją w żądaniu.
		// ========== KOLUMNY: ==========
		// Zmienne column* określają kolumny arkusza (opis każdej znajdziesz w formularzu na stronie Export).
		// Domyślna wartość wszystkich to 0 (kolumna jest pomijana), z wyjątkiem Code.
		"columnCode"		: 1,  // (nie można usunąć; kolumna z REF-CODE produktu zawsze występuje)
		"columnName"		: 1,  // Nazwa produktu
		"columnCategories"	: 1,  // Kategorie produktu ("Category 1; Category 2" w jednej komórce)
		"columnComments"	: 1,  // Komentarze produktu
		"columnCreated"		: 1,  // Data utworzenia produktu YYYY/MM/DD (w naszym systemie)
		"columnCustom"		: 1,  // Pola niestandardowe produktów (jedna kolumna na każdą unikalną zmienną we wszystkich produktach)
		"columnPrice"		: 1,  // Cena produktu w żądanej walucie (NIE w walucie produktu)
		"columnCost"		: 1,  // Koszt produktu (w ...)
		"columnMargin"		: 1,  // Marża produktu w procentach na podstawie ceny i kosztu
		"columnRank"		: 1,  // Moja pozycja
		"columnInRank"		: 1,  // Moja pozycja wśród konkurentów z dostępnym towarem
		"columnMyWebsite"	: 1,  // Adres URL mojego sklepu
		"columnReprice"		: 1,  // Obliczona kwota automatycznej zmiany cen (w ...)
		"columnRepricingRule"	: 1,  // Nazwa reguły cenowej
		"columnRecommended"	: 1,  // Zalecana cena (zobacz pomoc na stronie Export)
		"columnCompUrls"	: 1,  // Adresy URL konkurentów (każdy w osobnej kolumnie)
		"columnCompUrlsJoin"	: 1,  // Adresy URL konkurentów (oddzielone spacjami w jednej komórce)
		"columnCompMinMaxAvg"	: 1,  // Dodaje 3 kolumny: minimum, maksimum i średnią cenę konkurentów
		"columnInCompMinMaxAvg"	: 1,  // Dodaje 3 kolumny: minimum, maksimum i średnią cen konkurentów Z TOWAREM
		"columnCompPrice"	: 1,  // Dodaje kolumnę z ceną każdego konkurenta (w ...)
		"columnCompStock"	: 1,  // Dodaje kolumnę ze stanem magazynowym każdego konkurenta (123|IN|OUT)
		"columnCompSales"	: 1,  // Dodaje kolumnę z tygodniową sprzedażą każdego konkurenta
		"columnCompRank"	: 1,  // Dodaje kolumnę z pozycją każdego konkurenta wśród wszystkich (łącznie z Tobą)
		"columnCompInRank"	: 1,  // Dodaje kolumnę z pozycją każdego konkurenta wśród DOSTĘPNYCH (łącznie z Tobą)
		// ========== UKRYTE ZAAWANSOWANE PARAMETRY: ==========
		// Istnieje też kilka nieoficjalnych, słabiej opisanych opcji, z których część wykorzystuje np. szablon "pricezag_backup".
		"originalCurrencies"	: 1,  // Zamiast przeliczać kwoty na wskazaną walutę i zapisywać liczby, komórki będą tekstem z oryginalną walutą ("123.90 USD").
		"keepUrlLabels"		: 1,  // Zwykle usuwamy etykiety adresów URL konkurentów. Ta opcja je zachowa (przydatne przy kopiach zapasowych).
		"csvSeparator"		: ";",  // Jeśli w CSV chcesz inny separator niż przecinek lub tabulator.
		"csvNoQuote"		: 1,  // Zapobiega używaniu cudzysłowów (") w CSV, co może naruszyć poprawność formatu.
	}
] }
// Prosty sposób pobrania kopii zapasowej w 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 - Zmiana nazwy lub usunięcie ustawienia eksportu

To odpowiednik czynności dostępnych na Twoim koncie na stronie Export po kliknięciu przycisku Edit Presets.
Ta akcja służy WYŁĄCZNIE do ZMIANY NAZWY lub USUNIĘCIA ustawienia. Aby utworzyć nowe lub zmienić istniejące ustawienie, użyj akcji spreadsheetDownload powyżej.
{ "actions" : [
	{
		"a"		: "spreadsheetPresetEdit",
		"preset"	: "Some Preset Name",  // Aktualna nazwa szablonu
		"newName"	: "The Renamed Preset",  // Nowa nazwa tego szablonu
		"delete"	: 1,  // Usunąć ten szablon "preset" z konta
		// UWAGA: Nie można usunąć szablonu używanego przez automatyczny eksport (pojawi się błąd).
		// Najpierw musisz usunąć powiązane zaplanowane eksporty (zobacz stronę Export).
	}
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "spreadsheetPresetEdit",
			"ok"	: 1,
		},
		...
	]
}

spreadsheetAutoCreate - Utworzenie automatycznego eksportu arkuszy

To odpowiednik czynności dostępnych na Twoim koncie na stronie Export po kliknięciu przycisku Add a new Auto-Export.
{ "actions" : [
	{
		"a"			: "spreadsheetAutoCreate",
		"preset"		: "The Preset Name",
		"email"			: "john@example.net",
		"currency"		: "USD",  // (opcjonalnie) Domyślne "preset" oznacza użycie waluty szablonu
		"attach"		: "link",  // (opcjonalnie, domyślnie "attach") "attach" = załącznik, "link" = hostowany bezpośredni link
		"everyMonday"		: 1,  // Wysyłaj arkusz w każdy poniedziałek
		"everyTuesday"		: 1,  // ... (analogicznie dla każdego dnia tygodnia aż do "everySunday")
		"everyMonthDay1"	: 15,  // Wysyłaj 15. dnia miesiąca
		"everyMonthDay2"	: 21,  // ... a także 21. dnia
		"everyMonthDay3"	: "last",  // ... a także ostatniego dnia miesiąca
			// everyMonthDay* może mieć wartości od 0 do 9, maksymalnie 10 dni miesiąca.
		"time"			: "3:59pm",  // Działa też "15.59", przeliczane na "3:59pm". Wartości "0:9", "0.09", "00:09", "0:09am" są równoważne.
		"timezone"		: "America/Los_Angeles",  // (opcjonalnie, domyślnie "UTC") Format ścieżki w Linuksie /usr/share/zoneinfo
			// Spacje w nazwie miasta zostaną zastąpione podkreśleniami.
	}
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "spreadsheetAutoCreate",
			"ok"	: 1,
			"id"	: "5gwi6fqa",  // Identyfikator tego automatycznego eksportu do późniejszej edycji (zobacz spreadsheetAutoEdit poniżej)
		},
		...
	]
}

spreadsheetAutoEdit - Edycja automatycznego eksportu arkuszy

To odpowiednik czynności dostępnych na Twoim koncie na stronie Export, klikając przycisk Edit na liście pod nagłówkiem AUTO-EXPORT TO EMAIL.
{ "actions" : [
	{
		"a"			: "spreadsheetAutoEdit",
		"id"			: "5gwi6fqa",  // Identyfikator automatycznego eksportu do edycji
			// Ten identyfikator znajdziesz w odpowiedzi spreadsheetAutoCreate lub w tytule okna otwartego po kliknięciu Edit przy automatycznym eksporcie.
		"disabled"		: 1,  // (opcjonalnie) Ustaw 0, aby włączyć wyłączony automatyczny eksport
		"delete"		: 1,  // (opcjonalnie) Całkowicie usunąć ten automatyczny eksport
		// ===== Wszystkie poniższe (opcjonalne) parametry są takie same jak w spreadsheetAutoCreate powyżej =====
		"preset"		: "The Preset Name",
		"email"			: "john@example.net",
		"currency"		: "USD",
		"attach"		: "link",
		"everyMonday"		: 1,  // OSTRZEŻENIE: Jeśli podasz choć jedną zmienną every*, wszystkie dotychczasowe zmienne every* zostaną usunięte,
		"everyMonthDay1"	: 15,  // więc ustawienie "everyMonthDay3" usunie poprzednie "everyFriday"=1.
		// ... i tak dalej (wszystkie zmienne every* opisano w spreadsheetAutoCreate)
		"time"			: "3:59pm",
		"timezone"		: "America/Los_Angeles",
	}
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "spreadsheetAutoEdit",
			"ok"	: 3,  // Liczba wprowadzonych zmian
		},
		...
	]
}

Konkurenci i inne funkcje

competitorDeleteAll - Usuwanie konkurenta ze wszystkich produktów lub kategorii

Masowo usuwa adresy URL konkurenta ze wszystkich produktów albo tylko z produktów należących do wybranych kategorii.
OSTRZEŻENIE: Adresy URL konkurenta zostaną natychmiast i nieodwracalnie usunięte z konta.
To ta sama funkcja, z której korzysta interfejs: otwórz stronę konkurenta i kliknij Delete from all Products albo otwórz stronę kategorii i kliknij (X) na liście konkurentów.
{ "actions" : [
	...
	{
		"a"		: "competitorDeleteAll",
		"domain"	: "competitordomain.com",
		"categories"	: ["The Category 1", "The Category 2"],  // (opcjonalnie) Jeśli pominięte, musisz użyć "allProducts" = 1
		"allProducts"	: 1,  // (opcjonalnie) Usunąć ze wszystkich produktów (NIE podawaj "categories")
		// Użyj "categories" albo "allProducts"; nie obu i nie żadnego z nich.
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "competitorDeleteAll",
			"ok"	: 10,  // Liczba usuniętych adresów URL
		},
		...
	]
}

mathEdit - Ustawienie lub edycja obliczeń cen dla domeny konkurenta

To ta sama funkcja, z której korzysta interfejs: otwórz Domains, kliknij domenę konkurenta na liście, a następnie Mathematically alter the price. Wszystkie ustawienia dostępne w tym formularzu można również skonfigurować przez API za pomocą akcji mathEdit.
Szczegóły każdego pola znajdziesz po kliknięciu zielonej ikony ze znakiem zapytania na koncie.
{ "actions" : [
	...
	{
		"a"		: "mathEdit",
		"domain"	: "competitordomain.com",
		"clear"		: 1,  // (opcjonalnie) Wyłączyć wszystkie obliczenia dla domeny (usunie wcześniejsze ustawienia)
		// Przy clear:1 nie wolno podawać niczego poniżej, inaczej wystąpi błąd.
		"math"	: [  // Tablica bloków obliczeniowych do zastosowania
			{  // To obiekt bloku obliczeniowego; wszystkie pola są opcjonalne.
				"categories"		: ["Category 1", "Category 2"],  // Tylko dla produktów z tych kategorii
				"theirPriceMin"		: 1234.90,  // Tylko gdy ich cena jest większa lub równa N
				"theirPriceMinCurrency"	: "USD",  // Waluta (można użyć "original" dla waluty ze strony)
				"theirPriceMax"		: 1234.90,  // ... mniejsza lub równa
				"theirPriceMaxCurrency"	: "USD",  // Waluta (...)
				"themMeMin"		: -20.00,  // Tylko gdy różnica [ich cena - moja cena] jest większa lub równa N (zobacz interfejs)
				"themMeMinCurrency"	: "USD",  // Waluta lub "%" Twojej ceny (tutaj NIE używaj "original")
				"themMeMax"		: -1.5,  // ... mniejsza lub równa
				"themMeMaxCurrency"	: "%",  // Waluta (...)
				"addPre"		: -10.00,  // Kwota dodawana przed mnożeniem (ujemna = odejmowanie)
				"addPreCurrency"	: "USD",  // Waluta (można użyć "original" dla waluty ze strony)
				"multiply"		: 1.1,  // Pomnożyć przez ten współczynnik
				"divide"		: 1.1,  // LUB podzielić (nie podawaj obu)
				"addPost"		: 5.00,  // Kwota dodawana po mnożeniu (ujemna = odejmowanie)
				"addPostCurrency"	: "USD",  // Waluta (...)
				// Wygląda na skomplikowane? Zobacz prosty przykład poniżej odpowiedzi.
			},
			... // Łącznie maksymalnie 10 bloków (obliczenia są wykonywane po kolei)
		],
		// UWAGA: Obecnie nie da się zmienić tylko jednej zmiennej ani bloku obliczeniowego. Podanie tablicy math zastępuje całe ustawienie.
		// UWAGA: Każdy blok bez mnożenia ani dzielenia (nieustawione lub 1), w którym jednocześnie addPre!=0 i addPost!=0 są fałszywe, zostanie pominięty,
		// a jeśli wszystkie zostaną pominięte, efekt będzie taki sam jak usunięcie obliczeń przez clear:1.
		// Innymi słowy, obliczenia muszą rzeczywiście coś zmieniać, aby zostały zapisane.
		// WSKAZÓWKA: Aby tymczasowo wyłączyć obliczenia domeny bez usuwania ustawień,
		// możesz ustawić categories: ["Some Empty Existing Category"]
	},
	...
] }
ODPOWIEDŹ:
{
	...
	"actions" : [
		...
		{
			"a"	: "mathEdit",
			"ok"	: 3,  // Liczba zmienionych bloków obliczeniowych (usunięcie/wyczyszczenie liczy się jako zmiana)
		},
		...
	]
}
PROSTY PRZYKŁAD - Usunięcie 10% podatku ze wszystkich cen na amazon.co.uk:
{ "actions" : [
	{
		"a"		: "mathEdit",
		"domain"	: "amazon.co.uk",
		"math"		: [
			{
				"divide"	: 1.1
			}
		]
	}
] }

Więcej przykładów

Te żądania to POST dane wysyłane do https://pricezag.com/api/v3/MYAPIKEY
▶ PRZYKŁAD 1 - Aktualizacja kosztu produktu
ŻĄDANIE:
{
	"actions" : [
		{
			"a"		: "productEdit",
			"code"		: "SKU-1234",
			"cost"		: 140.50,
			"costCurrency"	: "EUR"
		}
	]
}
ODPOWIEDŹ:
{
	"ok"		: 1,  // Zwróci 0, jeśli SKU-1234 miał już taki koszt
	"errors"	: 0,  // Zwróci 1, jeśli SKU-1234 nie istniał
	"actionsCount"	: 1,
	"actions" : [
		{
			"a"	: "productEdit",
			"ok"	: 1  // Zwróci 0, jeśli SKU-1234 miał już taki koszt, a -1, jeśli nie istniał
		}
	]
}

▶ PRZYKŁAD 2 - Pobranie nieistniejącego produktu
ŻĄDANIE:
{
	"actions" : [
		{
			"a"		: "productGet",
			"code"		: "NON-EXISTING-SKU",
			"currency"	: "USD"
		}
}
ODPOWIEDŹ:
{
	"ok"		: 0,  // Ponieważ żadna akcja nie zwróciła ok>0
	"errors"	: 1,  // Ponieważ jedna akcja zwróciła ok<0
	"actionsCount"	: 1,
	"actions" : [
		{
			"a"	: "productGet",
			"ok"	: -1,  // Po tym poznasz, że akcja zakończyła się błędem
			"error"	: "Sorry, the product #NON-EXISTING-SKU does not exist. Maybe someone else just removed or renamed it?"
		}
	]
}

▶ PRZYKŁAD 3 - Utworzenie kategorii, reguły cenowej i dwóch przypisanych do nich produktów
ŻĄDANIE:
{
	"actions" : [
		{
			"a"		: "categoryCreate",
			"name"		: "My New Category"
		},
		{
			"a"		: "repricingCreate",
			"name"		: "My New Repricing Rule",
			"init"	: {
				"target"	: "cheapest_n",
				"var_n"		: 2,
				"plusAmount"	: 0,
				"plusCurrency"	: "%"
				// Odpowiada ustawieniu „Ustaw moją cenę w połowie między dwoma najtańszymi konkurentami”.
			},
			"never"	: [
				{
					"target"	: "cost",
					"direction"	: "below",
					"plusAmount"	: 5,
					"plusCurrency"	: "%"
					// Odpowiada ustawieniu „Ale nigdy poniżej mojego kosztu plus 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",  // Ta sama nazwa reguły, którą właśnie utworzono
			"categories"	: ["My New Category"],	// Ta sama nazwa kategorii, którą właśnie utworzono
			// ... chociaż productCreate i tak utworzyłby nieistniejące kategorie, więc categoryCreate nie było konieczne.
			"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://..."]
		}
	]
}
ODPOWIEDŹ:
{
	"ok"		: 4,  // Ponieważ wszystkie 4 akcje zwróciły ok>0
	"errors"	: 0,  // Ponieważ żadna akcja nie zwróciła ok<0
	"actionsCount"	: 4,
	"actions" : [
		{
			"a"	: "categoryCreate",
			"ok"	: 1
		},
		{
			"a"	: "repricingCreate",
			"ok"	: 1
		},
		{
			"a"	: "productCreate",
			"ok"	: 1
		},
		{
			"a"	: "productCreate",
			"ok"	: 1
		}
	]
}

▶ PRZYKŁAD 4 - Scalenie dwóch kategorii w inną i usunięcie dwóch pierwotnych kategorii
ŻĄDANIE:
{
	"actions" : [
		{
			"a"			: "categoryCopy",
			"categoriesFrom"	: ["Original Category 1", "Original Category 2"],
			"deleteMode"		: "cat",
			// Uwaga: "removeMode":"cat" jest niepotrzebne, ponieważ deleteMode i tak usunie te dwie kategorie.
			"categoriesTo"		: ["A New Category"]
		}
}
ODPOWIEDŹ:
{
	"ok"		: 1,  // Ponieważ jedna akcja zwróciła ok>0
	"errors"	: 0,  // Ponieważ żadna akcja nie zwróciła ok<0
	"actionsCount"	: 1,
	"actions" : [
		{
			"a"			: "categoryCopy",
			"ok"			: 3,  // Ponieważ zmieniono 3 kategorie: dwie źródłowe usunięto, a jedną docelową utworzono
			"categoriesCreated"	: 1,
			"categoriesDeleted"	: 2,
			"categoriesModified"	: 0,
			"productsCount"		: 123
		}
	]
}

▶ PRZYKŁAD 5 - Zmiana zmiennej N i kierunku reguły alertu
ŻĄDANIE:
{
	"actions" : [
		{
			"a"		: "alertRuleEdit",
			"email"		: "john@example.net",
			"ruleNumber"	: 3,
			"rule"		: {
				"var_n"		: 1.5,
				"direction"	: "drop"
			}
		}
}
ODPOWIEDŹ:
{
	"ok"		: 1,  // Ponieważ jedna akcja zwróciła ok>0
	"errors"	: 0,  // Ponieważ żadna akcja nie zwróciła ok<0
	"actionsCount"	: 1,
	"actions" : [
		{
			"a"	: "alertRuleEdit",
			"ok"	: 2  // Ponieważ pomyślnie zmieniono 2 zmienne
		}
	]
}