Dokumentacja REST API systemu Imker
Integruj swój system z rozwiązaniem od Imker. Zarządzaj produktami, kodami rabatowymi i zamówieniami programowo.
Wprowadzenie
API Imker SalesCRM umożliwia integrację Twojego systemu ze sklepem. Możesz zarządzać produktami i kodami rabatowymi (tworzenie, edycja, usuwanie) oraz przeglądać i aktualizować zamówienia.
https://{your-subdomain}.salescrm.pl/api/v1/
Właściciel sklepu może w dowolnym momencie wyłączyć dostęp do API w panelu administracyjnym (Integracje → API). Po wyłączeniu wszystkie żądania będą zwracać błąd 401 Unauthorized.
Autoryzacja
Wszystkie żądania wymagają nagłówka X-API-KEY. Klucz API wygenerujesz w panelu admina: Integracje → API.
curl -H "X-API-KEY: your-api-key" \
https://your-shop.salescrm.pl/api/v1/products
Format odpowiedzi
Wszystkie odpowiedzi są w formacie JSON. Pomyślne odpowiedzi zawierają pole data, listy dodatkowo meta z paginacją.
{
"data": [...],
"meta": {
"page": 1,
"per_page": 25,
"total": 100,
"total_pages": 4
}
}
{
"error": "Unprocessable Entity",
"errors": {
"name": ["can't be blank"]
}
}
Paginacja
| Parameter | Type | Opis |
|---|---|---|
page | integer | Numer strony (domyślnie 1) |
per_page | integer | Elementów na stronę (domyślnie 25, max 100) |
Rate Limiting
| Typ | Limit | Opis |
|---|---|---|
| Ogólny | 100 req/min | Wszystkie endpointy |
| Mutacje | 30 req/min | POST, PATCH, DELETE |
Po przekroczeniu limitu otrzymasz odpowiedź 429 Too Many Requests z nagłówkiem Retry-After.
Lista produktów z paginacją.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
active | string | Nie | "true" / "false" |
category_id | integer | Nie | ID kategorii produktu |
search | string | Nie | Szukaj po nazwie lub SKU |
page | integer | Nie | Numer strony |
per_page | integer | Nie | Elementów na stronę (max 100) |
{
"data": [
{
"id": 1,
"name": "E-book: Marketing",
"sku": "EBOOK1",
"price": "49.99",
"vat_rate": 23,
"active": true,
"electronic": true,
"distribution": "normal",
"description": "<p>Opis produktu...</p>",
"description_for_cart": "Krótki opis w koszyku",
"category": "E-booki",
"category_id": 5,
"ean": null,
"producer": "Imker",
"invoice_item_name": "E-book Marketing",
"pkwiu": null,
"product_link": "https://example.com/product",
"gtu_code": null,
"regular_price_displayed": "69.99",
"allow_price_change": false,
"minimal_price": null,
"allow_zero_minimal_price": false,
"delivery_type_ids": [1, 3],
"payment_type_ids": [2, 5],
"cart_quantity_limit": null,
"lump_code": "8.5",
"product_category_ids": [12, 15],
"feed_category_id": null,
"photo_url": "https://twoj-sklep.salescrm.pl/rails/active_storage/...",
"hide_in_xmls": false,
"no_invoice": false,
"hide_invoice_address_fields": false,
"payment_return_url": null,
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-02-20T14:15:00Z"
}
],
"meta": { "page": 1, "per_page": 25, "total": 1, "total_pages": 1 }
}
Szczegóły pojedynczego produktu.
curl -H "X-API-KEY: your-key" \
https://your-shop.salescrm.pl/api/v1/products/1
Tworzenie nowego produktu.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
name | string | Tak | Nazwa produktu |
price | string | Tak | Cena brutto |
sku | string | Nie | SKU |
vat_rate | string | Nie | Stawka VAT (np. "23") |
active | boolean | Nie | Czy aktywny |
description | string | Nie | Opis produktu (HTML) |
description_for_cart | string | Nie | Opis wyświetlany w koszyku |
electronic_product | boolean | Nie | Produkt elektroniczny |
distribution | string | Nie | normal, audio, video, webinar, course |
producer | string | Nie | Producent |
ean | string | Nie | Kod EAN (13 cyfr) |
invoice_item_name | string | Nie | Nazwa na fakturze |
pkwiu | string | Nie | PKWiU |
product_link | string | Nie | Link do produktu (URL) |
gtu_code | string | Nie | Kod GTU (GTU_01-GTU_13) |
regular_price_displayed | string | Nie | Cena regularna (przekreślona) |
allow_price_change | boolean | Nie | Klient może zmienić cenę |
minimal_price | string | Nie | Minimalna cena (gdy allow_price_change) |
allow_zero_minimal_price | boolean | Nie | Czy cena minimalna może być 0 |
delivery_type_ids | array | Nie | ID metod dostawy |
payment_type_ids | array | Nie | ID metod płatności |
product_category_id | integer | Nie | ID kategorii produktu |
cart_quantity_limit | integer | Nie | Limit ilości w koszyku |
lump_code | decimal | Nie | Stawka ryczałtu (dla płatników na ryczałcie); dozwolone: 17, 15, 14, 12.5, 12, 10, 8.5, 5.5, 3 |
product_category_ids | array | Nie | Kategorie główne produktu (te z panelu, wiele naraz). Uwaga: pole product_category_id to co innego - kategoria dla porównywarek/feedów (w odpowiedzi także jako feed_category_id) |
photo | object | Nie | Zdjęcie produktu: { "filename", "content_type", "data" (base64) }; null usuwa zdjęcie. W odpowiedzi photo_url |
hide_in_xmls | boolean | Nie | Ukryj w plikach XML |
no_invoice | boolean | Nie | Nie generuj faktury |
hide_invoice_address_fields | boolean | Nie | Ukryj pola adresu na fakturze |
payment_return_url | string | Nie | URL powrotu po płatności |
curl -X POST \
-H "X-API-KEY: your-key" \
-H "Content-Type: application/json" \
-d '{"name":"New Product","price":"49.99","vat_rate":"23","active":true}' \
https://your-shop.salescrm.pl/api/v1/products
Aktualizacja produktu. Wysyłasz tylko zmienione pola.
curl -X PATCH \
-H "X-API-KEY: your-key" \
-H "Content-Type: application/json" \
-d '{"price":"59.99","active":false}' \
https://your-shop.salescrm.pl/api/v1/products/1
Usunięcie produktu. Jeśli produkt ma zamówienia, zostanie ukryty zamiast usunięty.
Duplikuje produkt jednym żądaniem - jak przycisk „Duplikuj" w panelu: kopiuje ustawienia, zdjęcie, pliki, sposoby dostawy i płatności oraz kategorie główne. Klon powstaje nieaktywny (chyba że przekażesz active: true) i z nazwą „Kopia: ..." (chyba że przekażesz name) - dokończ konfigurację PATCH-em i aktywuj. Odpowiedź: pełny obiekt produktu, status 201.
{
"data": {
"id": 1,
"deleted": false,
"hidden": true,
"message": "Product has orders and was hidden instead of deleted"
}
}
Lista kodów rabatowych z paginacją i filtrami.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
discount_type | string | Nie | Typ rabatu (percentage_discount, value_discount, free_delivery_discount, free_contents, value_and_free_delivery_discount, percentage_and_free_delivery_discount, value_per_product_discount, value_per_product_and_free_delivery_discount, unit_price_discount) |
active | string | Nie | "true" / "false" |
search | string | Nie | Szukaj po kodzie lub nazwie |
page | integer | Nie | Numer strony |
per_page | integer | Nie | Elementów na stronę (max 100) |
{
"data": [
{
"id": 1,
"code": "LATO20",
"name": "Letnia promocja",
"discount_type": "percentage_discount",
"value": "20.0",
"case_sensitive": false,
"minimum_amount": "50.0",
"usages_limit": 100,
"usages_per_customer_limit": 1,
"usages": 42,
"active": true,
"start_date": "2026-06-01T00:00:00Z",
"end_date": "2026-08-31T23:59:59Z",
"combine_with_other_discount": true,
"relation_with_products": "all_products",
"product_ids": [],
"product_category_ids": [],
"relation_with_delivery_types": "all_delivery_types",
"delivery_type_ids": [],
"created_at": "2026-05-15T10:00:00Z",
"updated_at": "2026-05-15T10:00:00Z"
}
],
"meta": { "page": 1, "per_page": 25, "total": 1, "total_pages": 1 }
}
Szczegóły pojedynczego kodu rabatowego.
curl -H "X-API-KEY: your-key" \
https://your-shop.salescrm.pl/api/v1/discount_codes/1
Tworzenie nowego kodu rabatowego.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
code | string | Tak | Kod rabatowy (unikalny) |
discount_type | string | Tak | percentage_discount, value_discount, free_delivery_discount, free_contents, value_and_free_delivery_discount, percentage_and_free_delivery_discount, value_per_product_discount, value_per_product_and_free_delivery_discount, unit_price_discount |
value | string | Tak* | Wartość rabatu (% lub kwota). *Wymagana dla percentage i value discount. Dla unit_price_discount to nie rabat, tylko cena docelowa jednej sztuki - produkt schodzi do tej kwoty niezależnie od tego, ile kosztował, a tańszy nie drożeje |
name | string | Nie | Nazwa (widoczna tylko w panelu) |
case_sensitive | boolean | Nie | Wielkość liter ma znaczenie (domyślnie true) |
minimum_amount | string | Nie | Minimalna kwota zamówienia |
usages_limit | integer | Nie | Maksymalna liczba użyć |
usages_per_customer_limit | integer | Nie | Maksymalna liczba użyć na klienta |
start_date | string | Nie | Data rozpoczęcia (ISO 8601) |
end_date | string | Nie | Data zakończenia (ISO 8601) |
combine_with_other_discount | boolean | Nie | Łącz z innymi rabatami (domyślnie true) |
relation_with_products | string | Nie | all_products, selected_products, products_except, selected_categories, categories_except |
product_ids | array | Nie | ID produktów |
product_category_ids | array | Nie | ID kategorii |
relation_with_delivery_types | string | Nie | domestic_delivery_types_only, all_delivery_types, selected_delivery_types |
delivery_type_ids | array | Nie | ID metod dostawy |
curl -X POST \
-H "X-API-KEY: your-key" \
-H "Content-Type: application/json" \
-d '{"code":"LATO20","discount_type":"percentage_discount","value":"20","usages_limit":100}' \
https://your-shop.salescrm.pl/api/v1/discount_codes
Aktualizacja kodu rabatowego. Wysyłasz tylko zmienione pola.
curl -X PATCH \
-H "X-API-KEY: your-key" \
-H "Content-Type: application/json" \
-d '{"value":"25","usages_limit":200}' \
https://your-shop.salescrm.pl/api/v1/discount_codes/1
Usunięcie kodu rabatowego.
Zamówienia powiązane z tym kodem zachowują informację o rabacie, ale powiązanie z kodem zostaje usunięte.
{
"data": {
"id": 1,
"deleted": true
}
}
Pliki produktu cyfrowego - e-book, który kupujący pobiera po zakupie, razem z ustawieniami znaku wodnego i limitów pobrań. Do tej pory dało się je dodać wyłącznie w panelu, więc założenie produktu ze skryptu kończyło się na etapie pliku.
Endpointy są zagnieżdżone pod produktem. Plik przesyłasz tak samo jak zdjęcie produktu:
obiektem {filename, content_type, data}, gdzie data to zawartość
zakodowana w base64.
Tą drogą wgrywasz wyłącznie PDF i EPUB, maksymalnie 50 MB.
Format rozpoznajemy z zawartości pliku, a nie z pola content_type -
plik innego typu dostaje 422, nawet jeśli nazwiesz go inaczej. Audio, wideo i webinary
dodajesz w panelu.
Lista plików przypiętych do produktu. Odpowiedź zawiera nazwę, typ i rozmiar pliku, ale nie zawiera linku do pobrania - plik należy się kupującemu i wydawany jest przez kod z zamówienia.
{
"data": [
{
"id": 4412,
"kind": "normal",
"content_title": null,
"days_to_expire": 365,
"usages_to_expire": 5,
"watermark": "Egzemplarz dla {{IMIE}} {{NAZWISKO}}",
"watermark_interval": 1,
"distribute_via_sales_cas": false,
"file": {
"filename": "poradnik.pdf",
"content_type": "application/pdf",
"byte_size": 2481232
},
"created_at": "2026-08-05T22:30:00+02:00"
}
]
}
Dodaje plik do produktu. Wymaga klucza z zakresem write_data.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
file | object | Tak | {filename, content_type, data} - data w base64. Tylko PDF i EPUB, maks. 50 MB |
kind | string | Nie | normal (domyślnie) - plik do pobrania |
days_to_expire | integer | Tak | Ile dni od zakupu działa link do pobrania |
usages_to_expire | integer | Tak | Ile razy kupujący może pobrać plik |
watermark | string | Nie | Treść znaku wodnego, maks. 128 znaków. Puste = brak znaku. Znaczniki: {{IMIE}}, {{NAZWISKO}}, {{EMAIL}} |
watermark_interval | integer | Nie | Co ile stron powtarzać znak wodny (domyślnie 1) |
description | string | Nie | Opis, maks. 30 000 znaków |
curl -X POST "https://twoj-sklep.salescrm.pl/api/v1/products/18245/electronic_contents" \
-H "X-API-KEY: TWOJ_KLUCZ" \
-H "Content-Type: application/json" \
-d '{
"days_to_expire": 365,
"usages_to_expire": 5,
"watermark": "Egzemplarz dla {{IMIE}} {{NAZWISKO}}",
"file": {
"filename": "poradnik.pdf",
"content_type": "application/pdf",
"data": "JVBERi0xLjQK..."
}
}'
Błędy
| Kod | Kiedy |
|---|---|
400 | file nie jest obiektem z polem data |
413 | Plik przekracza 50 MB (sprawdzane przed rozkodowaniem) |
422 | Plik nie jest PDF-em ani EPUB-em, albo brakuje days_to_expire / usages_to_expire |
404 | Produkt nie istnieje w tym sklepie |
Zmiana ustawień pliku - na przykład treści znaku wodnego albo limitów. Przesłanie
file podmienia sam plik.
Usuwa plik z produktu. Kody pobrań wydane wcześniejszym kupującym przestają działać.
Pula to paczka kodów o wspólnej konfiguracji, wygenerowana z góry (np. 1000 sztuk). Pule tworzysz w panelu: Promocje → Kody rabatowe → Nowa pula kodów.
Pula może działać w trybie „ważność liczona od pobrania"
(activate_on_draw). Kody z takiej puli są nieaktywne, dopóki ich nie
pobierzesz - dopiero pobranie nadaje im okno ważności liczone od tamtej chwili.
Dzięki temu możesz wysyłać z dowolnego systemu mailowego wiadomość
„oto Twój kod, wygasa za 48 godzin", a każdy odbiorca dostaje własne 48 godzin.
Lista pul z licznikami kodów.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
search | string | Nie | Fragment nazwy puli |
page | integer | Nie | Numer strony (domyślnie 1) |
per_page | integer | Nie | Wyników na stronę (domyślnie 25, maks. 100) |
{
"data": [
{
"id": 12,
"name": "Pula 48h - newsletter",
"activate_on_draw": true,
"codes_total": 1000,
"codes_drawn": 10,
"codes_remaining": 990,
"created_at": "2026-08-05T14:00:00+02:00"
}
],
"meta": { "page": 1, "per_page": 25, "total": 1, "total_pages": 1 }
}
Pojedyncza pula - ten sam zestaw pól co na liście. Przydatne do sprawdzenia,
ile kodów jeszcze zostało (codes_remaining).
Pobiera paczkę kodów z puli: aktywuje count wolnych kodów
z ważnością validity_hours godzin liczoną od tej chwili
i zwraca je wraz z datą wygaśnięcia.
Endpoint działa wyłącznie na pulach z activate_on_draw: true.
Wymaga klucza z zakresem write_data.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
count | integer | Tak | Ile kodów pobrać (liczba dodatnia) |
validity_hours | integer | Tak | Ile godzin mają być ważne, licząc od pobrania |
curl -X POST "https://twoj-sklep.salescrm.pl/api/v1/discount_code_pools/12/draw" \
-H "X-API-KEY: TWOJ_KLUCZ" \
-H "Content-Type: application/json" \
-d '{"count": 1, "validity_hours": 48}'
{
"data": [
{
"id": 84213,
"code": "K7QM4XPB",
"valid_from": "2026-08-05T14:12:00+02:00",
"valid_until": "2026-08-07T14:12:00+02:00"
}
]
}
Błędy
| Kod | Kiedy |
|---|---|
400 | count lub validity_hours nie jest dodatnią liczbą całkowitą |
422 | Pula nie działa w trybie pobierania albo zostało w niej mniej wolnych kodów, niż zamawiasz (paczka nie jest wtedy wydawana częściowo) |
404 | Pula nie istnieje w tym sklepie |
Rabaty, które naliczają się same - klient niczego nie wpisuje. Wchodzą, kiedy pasuje adres e-mail, domena adresu, zgoda na newsletter albo data. Cztery zasoby, ten sam zestaw pól i te same operacje: GET listy, GET pojedynczego, POST, PATCH, DELETE.
Pola wspólne
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
discount_type | string | Tak | percentage_discount, value_discount, unit_price_discount. W promocjach czasowych dodatkowo percentage_product_discount i value_product_discount (warianty omnibusowe, przeliczają ceny produktów) |
value | string | Tak | Procent, kwota albo - dla unit_price_discount - cena docelowa jednej sztuki |
relation_with_products | string | Tak | all_products, selected_products, products_except, selected_categories, categories_except |
product_ids | array | Nie | ID produktów. Identyfikator spoza Twojego sklepu kończy się odpowiedzią 422, a nie cichym pominięciem |
product_category_ids | array | Nie | ID kategorii |
usages_limit | integer | Nie | Maksymalna liczba użyć (poza promocjami czasowymi) |
Cena docelowa. unit_price_discount nie zdejmuje procentu ani kwoty, tylko sprowadza sztukę do podanej ceny. Przy pozycji z kilkoma sztukami mnoży ją przez ilość. Produkt tańszy od ceny docelowej nie drożeje - rabat schodzi wtedy do zera. Dzięki temu „wszystko po 99 zł" działa na grupie produktów w różnych cenach.
Rabat przypisany do konkretnego adresu e-mail. Wchodzi, gdy klient poda ten adres w koszyku. Pola własne: email (wymagane), start_date, end_date. Listę filtruje parametr ?email=.
curl -X POST \
-H "X-API-KEY: your-key" \
-H "Content-Type: application/json" \
-d '{
"email": "ala@example.com",
"discount_type": "unit_price_discount",
"value": "99",
"relation_with_products": "all_products"
}' \
https://your-shop.salescrm.pl/api/v1/email_address_discounts
{
"data": {
"id": 12,
"discount_type": "unit_price_discount",
"value": "99.0",
"value_description": "99,00 zł / szt.",
"usages_limit": null,
"usages": 0,
"active": true,
"relation_with_products": "all_products",
"product_ids": [],
"product_category_ids": [],
"email": "ala@example.com",
"start_date": null,
"end_date": null,
"created_at": "2026-08-07T09:00:00Z",
"updated_at": "2026-08-07T09:00:00Z"
}
}
To samo, ale dla całej domeny pocztowej - rabat dostaje każdy adres w @firma.pl. Pole własne: email_domain (wymagane). Listę filtruje parametr ?email_domain=.
curl -X POST \
-H "X-API-KEY: your-key" \
-H "Content-Type: application/json" \
-d '{
"email_domain": "firma.pl",
"discount_type": "unit_price_discount",
"value": "99",
"relation_with_products": "all_products"
}' \
https://your-shop.salescrm.pl/api/v1/email_domain_discounts
Rabat za zgodę na newsletter, naliczany w koszyku po zaznaczeniu zgody. Pole własne: minimum_order_value - próg, od którego rabat w ogóle wchodzi.
curl -X POST \
-H "X-API-KEY: your-key" \
-H "Content-Type: application/json" \
-d '{
"discount_type": "value_discount",
"value": "20",
"minimum_order_value": "100",
"relation_with_products": "all_products"
}' \
https://your-shop.salescrm.pl/api/v1/newsletter_discounts
Promocje czasowe. Pola własne: start_date i end_date (oba wymagane, ISO 8601). Data zakończenia musi być późniejsza niż początek, a początek nie może być wcześniejszy niż dzisiaj - dokładnie tak, jak w panelu. Listę zawęża ?active=true. W odpowiedzi dochodzą pola future i past.
Typy percentage_product_discount i value_product_discount przeliczają ceny produktów zgodnie z dyrektywą Omnibus. Przeliczenie planuje się przy zapisie, tak samo jak przy zakładaniu promocji w panelu.
curl -X POST \
-H "X-API-KEY: your-key" \
-H "Content-Type: application/json" \
-d '{
"start_date": "2026-09-01T00:00:00Z",
"end_date": "2026-09-07T23:59:59Z",
"discount_type": "unit_price_discount",
"value": "99",
"relation_with_products": "all_products"
}' \
https://your-shop.salescrm.pl/api/v1/time_limited_discounts
Kody odpowiedzi
| Kod | Kiedy |
|---|---|
422 | Nieznany discount_type albo relation_with_products, produkt lub kategoria spoza Twojego sklepu, błąd walidacji (np. data zakończenia przed początkiem) |
404 | Rabat nie istnieje w tym sklepie |
403 | Klucz bez zakresu write_data przy zapisie lub usuwaniu |
Lista grup upsellingu (rekomendacji produktów w koszyku) z paginacją. Grupa łączy produkty, które wzajemnie się polecają: pozycje z invokes_recommendation wywołują ramkę rekomendacji, pozycje z is_recommended są w niej proponowane. Odpowiednik panelu Produkty → Upselling. Szczegóły pojedynczej grupy: GET /api/v1/product_recommendation_groups/:id.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
active | string | Nie | "true" / "false" |
product_id | integer | Nie | Tylko grupy zawierające dany produkt |
search | string | Nie | Szukaj po nazwie lub tytule |
page, per_page | integer | Nie | Paginacja (max 100) |
{
"data": [
{
"id": 7,
"name": "Upsell e-booków",
"title": "Dobierz do zamówienia",
"subtitle": null,
"active": true,
"items": [
{
"id": 21,
"product_id": 123,
"product_name": "E-book – Metoda X",
"title": null,
"subtitle": null,
"priority": 1,
"invokes_recommendation": true,
"is_recommended": true
}
],
"created_at": "2026-07-21T10:00:00Z",
"updated_at": "2026-07-21T10:00:00Z"
}
],
"meta": { "page": 1, "per_page": 25, "total": 1, "total_pages": 1 }
}
Tworzy grupę upsellingu wraz z pozycjami. Każdy product_id jest walidowany względem Twojego sklepu.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
name | string | Tak | Wewnętrzna nazwa grupy |
title, subtitle | string | Nie | Nagłówek/podtytuł ramki w koszyku |
active | boolean | Nie | Czy grupa aktywna |
items | array | Nie | Pozycje: product_id (wymagane), priority, invokes_recommendation, is_recommended, title, subtitle |
{
"product_recommendation_group": {
"name": "Upsell e-booków",
"title": "Dobierz do zamówienia",
"active": true,
"items": [
{ "product_id": 123, "priority": 1, "invokes_recommendation": true, "is_recommended": true }
]
}
}
Aktualizuje grupę. Pozycje działają w trybie replace: jeśli w payloadzie jest tablica items, staje się ona kompletnym nowym zestawem pozycji; pomiń klucz items, aby zostawić obecne pozycje bez zmian.
Usuwa grupę wraz z pozycjami. Odpowiedź: { "data": { "id": 7, "deleted": true } }.
Lista zestawów produktów (pakietów) z paginacją, posortowana po priorytecie malejąco. Zestaw sprzedaje kilka produktów w jednej cenie; w trybie puli (pool_mode) klient wybiera pool_pick_count produktów spośród pozycji zestawu. Odpowiednik panelu Produkty → Zestawy. Szczegóły pojedynczego zestawu: GET /api/v1/product_sets/:id.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
active | string | Nie | "true" / "false" |
product_id | integer | Nie | Tylko zestawy zawierające dany produkt |
search | string | Nie | Szukaj po nazwie |
page, per_page | integer | Nie | Paginacja (max 100) |
{
"data": [
{
"id": 4,
"name": "Wybierz 3 książki",
"slug": "wybierz-3-ksiazki",
"price": "209.0",
"active": true,
"priority": 40,
"auto_calculate_prices": true,
"link_only_discount": false,
"pool_mode": true,
"pool_pick_count": 3,
"custom_payment_types": false,
"payment_type_ids": [],
"expose_in_feeds": false,
"feed_description": null,
"ean": null,
"google_product_category": null,
"producer": null,
"product_category_id": null,
"items": [
{ "id": 11, "product_id": 123, "product_name": "Książka A", "quantity": 1, "custom_price": null },
{ "id": 12, "product_id": 124, "product_name": "Książka B", "quantity": 1, "custom_price": null }
],
"created_at": "2026-08-04T10:00:00Z",
"updated_at": "2026-08-04T10:00:00Z"
}
],
"meta": { "page": 1, "per_page": 25, "total": 1, "total_pages": 1 }
}
Tworzy zestaw wraz z pozycjami. Każdy product_id, product_category_id i payment_type_ids jest walidowany względem Twojego sklepu. Zestaw musi zawierać co najmniej 2 sztuki produktów (suma quantity), a pula - co najmniej 2 różne produkty. Zdjęcie zestawu wgrasz w panelu.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
name | string | Tak | Nazwa zestawu |
price | decimal | Tak | Cena zestawu |
active | boolean | Nie | Czy zestaw aktywny (domyślnie true) |
priority | integer | Nie | Kolejność na listach (wyższy = wyżej) |
auto_calculate_prices | boolean | Nie | Automatyczny podział ceny na pozycje (domyślnie true). Przy false każda pozycja wymaga custom_price, a suma cen × ilości musi równać się price |
link_only_discount | boolean | Nie | Zestaw dostępny tylko z bezpośredniego linku |
pool_mode | boolean | Nie | Tryb puli: klient wybiera pool_pick_count produktów z pozycji zestawu |
pool_pick_count | integer | Przy puli | Ilu produktów dotyczy wybór (min. 2, nie więcej niż liczba pozycji) |
custom_payment_types | boolean | Nie | Własne formy płatności zestawu; wymaga payment_type_ids |
payment_type_ids | array | Nie | ID form płatności (patrz GET /payment_types) |
expose_in_feeds, feed_description, ean, google_product_category, producer | - | Nie | Dane do porównywarek (feed wymaga opisu) |
product_category_id | integer | Nie | Kategoria produktowa zestawu |
items | array | Tak | Pozycje: product_id (wymagane), quantity (domyślnie 1), custom_price |
{
"product_set": {
"name": "Wybierz 3 książki",
"price": 209,
"priority": 40,
"pool_mode": true,
"pool_pick_count": 3,
"link_only_discount": false,
"items": [
{ "product_id": 123 },
{ "product_id": 124 },
{ "product_id": 125 },
{ "product_id": 126 }
]
}
}
Aktualizuje zestaw. Pozycje działają w trybie replace: jeśli w payloadzie jest tablica items, staje się ona kompletnym nowym składem zestawu; pomiń klucz items, aby zostawić obecny skład bez zmian. Tak samo payment_type_ids - podana tablica zastępuje całą listę.
Usuwa zestaw wraz z pozycjami. Odpowiedź: { "data": { "id": 4, "deleted": true } }.
Lista planów abonamentowych z powiązanymi produktami. Okres subskrypcji (interval, w dniach) i limit odnowień (renewals_limit) są ustawiane na powiązaniu planu z produktem, nie na samym planie. Szczegóły: GET /api/v1/subscription_plans/:id.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
automatic_renewal | string | Nie | "true" / "false" - tylko plany z automatycznym odnawianiem (lub bez) |
search | string | Nie | Szukaj po nazwie |
page, per_page | integer | Nie | Paginacja (max 100) |
{
"data": [
{
"id": 3,
"name": "Klub miesięczny",
"automatic_renewal": true,
"extension_strategy": "continuous",
"free_delivery_minimum_amount": "0.0",
"superseded_subscription_plan_id": null,
"send_email_about_activation": false,
"send_email_about_renewal": false,
"send_email_about_expiration_in_one_day": true,
"send_email_about_expiration_in_one_week": true,
"products": [
{
"product_id": 123,
"product_name": "Klub – dostęp miesięczny",
"interval": 30,
"renewals_limit": 0
}
],
"created_at": "2026-07-21T10:00:00Z",
"updated_at": "2026-07-21T10:00:00Z"
}
],
"meta": { "page": 1, "per_page": 25, "total": 1, "total_pages": 1 }
}
Tworzy plan abonamentowy i wiąże go z produktami. Konfiguracja integracji planu (Circle.so, Discord, Kajabi), szablony maili i darmowe dostawy pozostają w panelu - API ich nie zmienia.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
name | string | Tak | Nazwa planu |
automatic_renewal | boolean | Nie | Automatyczne odnawianie (płatności cykliczne). Produkt może należeć tylko do jednego auto-planu - konflikt zwróci 422. |
extension_strategy | string | Nie | immediate lub continuous |
free_delivery_minimum_amount | decimal | Nie | Minimalna kwota zamówienia dla darmowej dostawy subskrybenta |
superseded_subscription_plan_id | integer | Nie | Plan kończony przy nadaniu tego planu |
send_email_about_activation, ..._renewal, ..._expiration_in_one_day, ..._expiration_in_one_week | boolean | Nie | Przełączniki maili subskrypcyjnych |
products | array | Nie | Powiązania: product_id (wymagane), interval (dni, wymagane, 1-36500), renewals_limit (0 = bez limitu) |
{
"subscription_plan": {
"name": "Klub miesięczny",
"automatic_renewal": true,
"extension_strategy": "continuous",
"products": [
{ "product_id": 123, "interval": 30, "renewals_limit": 12 }
]
}
}
Aktualizuje plan. Powiązania produktów działają w trybie replace: tablica products w payloadzie staje się kompletnym nowym zestawem; pomiń klucz products, aby zostawić obecne powiązania.
Usuwa plan bez subskrybentów. Jeśli plan ma subskrybentów, API odmawia (422) - usunięcie skasowałoby ich subskrypcje; taką operację można wykonać wyłącznie z panelu.
Subskrybenci - kto ma abonament, na jakim planie i do kiedy. Wymaga zawężenia: co najmniej jednego z parametrów email, subscription_plan_id, custom_identifier - bez tego odpowiedź to 400. Do tego active=true/false, zakres daty końca (expires_before/expires_after, liczone z najdalszej daty końca subskrybenta) i paginacja.
Odpowiedź niesie m.in. service_ref (stały klucz usługi, nadawany przez SalesCRM, nie do zapisu), custom_identifier (Twoja etykieta, zapisywalna), renewal_paused, renewal_interval_days oraz renewal_items z ceną i polem price_source (override albo catalogue). GET /subscribers/:id dokłada pełną historię okresów.
Zmiana warunków odnowienia. Wymaga zakresu write_subscriptions - osobnego od write_data: klucz z tym zakresem potrafi wyłącznie subskrypcje i nie ma dostępu do produktów, zamówień ani konfiguracji, a klucz write_data nie dotknie rozliczeń.
Parametry
| Parameter | Type | Opis |
|---|---|---|
renewal_items | array | Pozycje kolejnych odnowień: {product_id, quantity, price}. Lista zastępuje poprzednią w całości. Cena pominięta = cena z cennika. Jawnie pusta lista jest odrzucana (422) - to niemal zawsze błąd klienta, nie zamiar odnawiania niczym. |
renewal_interval_days | integer | Długość kolejnych okresów; puste = z produktu. Nie zmienia trwającego okresu. |
renewal_paused | boolean | Wstrzymanie odnawiania. Karta zostaje zapisana - wznowienie nie wymaga od klienta ponownego podania danych. |
custom_identifier | string | Twoja etykieta usługi (np. nazwa serwera). service_ref nie jest zapisywalny - zmiana odczepiłaby subskrypcję od jej łańcucha odnowień. |
curl -X PATCH "https://twojsklep.salescrm.pl/api/v1/subscribers/123" \
-H "X-API-KEY: your-key" \
-H "Content-Type: application/json" \
-d '{"renewal_items": [{"product_id": 19}]}'
Kwota kolejnego pobrania wynika z pozycji - usunięcie dysku z listy obniża ją samo, bez osobnego pola.
Przesuwa datę końca opłaconego okresu (active_until, ISO 8601). Wymaga zakresu write_subscriptions. Przesunięcie daty przesuwa razem z nią wszystkie próby pobrania. Data przed początkiem okresu albo poza horyzontem 36500 dni jest odrzucana (422).
Lista zamówień z paginacją i filtrami. Odpowiedź zawiera uuid zamówienia - z niego zbudujesz link ?copy_of=<uuid>, który otwiera nowy koszyk z danymi klienta (adres, dostawa, płatność) przeniesionymi z tamtego zamówienia. Traktuj uuid jak sekret - to klucz dostępu do koszyka; buduj linki po stronie serwera.
Parametry
| Parameter | Type | Opis |
|---|---|---|
status | integer | ID statusu zamówienia (order_status_id) |
internal_status | string | placed, canceled, returned |
payment_status | string | paid / unpaid |
date_from | string | YYYY-MM-DD |
date_to | string | YYYY-MM-DD |
customer_email | string | Email klienta |
search | string | Szukaj po numerze zamówienia |
product_id | integer / lista | ID produktu - zwraca tylko zamówienia zawierające ten produkt. Możesz podać kilka ID po przecinku, np. product_id=12,17,33. |
sku | string / lista | SKU produktu - zwraca zamówienia zawierające produkt o tym SKU. Możesz podać kilka SKU po przecinku. |
{
"data": [
{
"id": 42,
"uuid": "9f8a2c1e-...-b7d4",
"ordinal_number": "2026/03/001",
"internal_status": "placed",
"order_status": "Nowe",
"order_status_id": 1,
"email": "jan@example.com",
"total": "149.99",
"currency": "PLN",
"paid": true,
"delivery_method": "Kurier DPD",
"placed_at": "2026-03-01T14:30:00Z",
"created_at": "2026-03-01T14:25:00Z",
"updated_at": "2026-03-01T14:30:00Z"
}
],
"meta": { "page": 1, "per_page": 25, "total": 1, "total_pages": 1 }
}
Szczegóły zamówienia z pozycjami, adresami, kosztami, atrybutami i notatkami.
Pola w odpowiedzi
| Pole | Typ | Opis |
|---|---|---|
order_status_id | integer | Numeryczny ID statusu zamówienia (użyj do zmiany statusu przez PATCH /orders/:id/status) |
invoice_recipient_name | string | Dodatkowe informacje na fakturze (np. nazwa odbiorcy, jeśli inny niż nabywca) |
notes | array | Notatki admina - tablica obiektów z polami content (treść) i created_at (data dodania) |
{
"data": {
"id": 42,
"ordinal_number": "2026/03/001",
"internal_status": "placed",
"order_status": "Nowe",
"order_status_id": 1,
"email": "jan@example.com",
"total": "149.99",
"currency": "PLN",
"paid": true,
"delivery_method": "Kurier DPD",
"placed_at": "2026-03-01T14:30:00Z",
"products_cost": "129.99",
"delivery_cost": "15.00",
"delivery_vat_rate": 23,
"payment_cost": "5.00",
"payment_vat_rate": 23,
"gift_packing_cost": "0.0",
"total_discount": "0.0",
"discount_code": "",
"cash_on_delivery": false,
"comment": "Proszę o szybką wysyłkę",
"delivery_point_code": null,
"tracking_number": "DPD123456",
"tracking_url": "https://tracktrace.dpd.com.pl/parcelDetails?p1=DPD123456",
"items": [
{
"id": 101,
"product_id": 1,
"name": "E-book: Marketing",
"sku": "EBOOK1",
"quantity": 1,
"unit_price": "49.99",
"vat_rate": 23,
"price": "49.99",
"discount": "0.0",
"final_price": "49.99"
}
],
"delivery_address": {
"first_name": "Jan",
"last_name": "Kowalski",
"company": null,
"nip": null,
"address": "ul. Główna 1",
"postcode": "00-001",
"city": "Warszawa",
"country": "PL",
"phone": "+48123456789",
"email": "jan@example.com"
},
"invoice_address": {
"first_name": "Jan",
"last_name": "Kowalski",
"company": "Firma Sp. z o.o.",
"nip": "1234567890",
"address": "ul. Firmowa 10",
"postcode": "00-002",
"city": "Warszawa",
"country": "PL",
"phone": "+48123456789",
"email": "jan@example.com"
},
"invoice_recipient_name": "Szkoła Podstawowa nr 1",
"order_attributes": [
{ "name": "Dedykacja", "value": "Dla Ani" }
],
"notes": [
{ "content": "Klient prosił o fakturę z innym adresem", "created_at": "2026-03-01T15:00:00Z" },
{ "content": "Faktura wysłana mailem", "created_at": "2026-03-02T09:30:00Z" }
]
}
}
Zmiana statusu zamówienia.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
order_status_id | integer | Tak | ID nowego statusu |
Uwaga: Zmiana statusu wywołuje te same efekty uboczne co w panelu admina (eventy, emaile, webhooki).
curl -X PATCH \
-H "X-API-KEY: your-key" \
-H "Content-Type: application/json" \
-d '{"order_status_id": 5}' \
https://your-shop.salescrm.pl/api/v1/orders/42/status
Rozliczenie zamówienia - odpowiednik przycisku "Rozlicz zamówienie" w panelu administracyjnym. Oznacza zamówienie jako opłacone ręcznie i uruchamia cały pipeline automatyzacji.
Co się dzieje po rozliczeniu
Rozliczenie zamówienia to nie tylko zmiana flagi "opłacone". System automatycznie uruchamia następujące procesy (identycznie jak przy kliknięciu "Rozlicz zamówienie" w panelu):
- Generowanie faktury - jeśli automatyczne fakturowanie jest włączone, faktura zostanie wygenerowana w podłączonym programie (wFirma, Fakturownia, iFirma, InFakt)
- Webhooki - wszystkie skonfigurowane webhooki otrzymają event o rozliczeniu zamówienia
- Sekwencje e-mail - automatyczne sekwencje wiadomości powiązane ze statusem "opłacone" zostaną uruchomione
- Tagi w narzędziach marketingowych - tagi produktów i zamówienia opłaconego zostaną przypisane w ConvertKit, ActiveCampaign lub MailerLite (jeśli integracja jest aktywna)
- Subskrypcje - jeśli zamówienie zawiera produkty subskrypcyjne, subskrypcja zostanie aktywowana
- Google Analytics - event purchase zostanie wysłany do GA4
Warunki
| Warunek | Odpowiedź |
|---|---|
| Zamówienie nieopłacone | 200 OK - zamówienie zostaje rozliczone |
| Zamówienie już opłacone (automatycznie lub ręcznie) | 422 - "Zamówienie jest już rozliczone" |
| Zamówienie na kwotę 0 zł | 422 - "Zamówienie na kwotę 0 zł nie wymaga rozliczenia" |
Uwaga: Rozliczenie zamówienia jest operacją nieodwracalną przez API. Cofnięcie rozliczenia jest możliwe tylko z poziomu panelu administracyjnego. Upewnij się, że zamówienie faktycznie zostało opłacone zanim wywołasz ten endpoint.
curl -X PATCH \
-H "X-API-KEY: your-key" \
https://your-shop.salescrm.pl/api/v1/orders/42/clear
{
"data": {
"id": 42,
"ordinal_number": "2026/04/001",
"internal_status": "placed",
"order_status": "Nowe",
"email": "jan@example.com",
"total": "149.99",
"currency": "PLN",
"paid": true,
"cleared_at": "2026-04-22T10:30:00Z",
"delivery_method": "Kurier DPD",
"placed_at": "2026-04-20T14:30:00Z",
"created_at": "2026-04-20T14:25:00Z",
"updated_at": "2026-04-22T10:30:00Z"
}
}
{
"error": "Already Cleared",
"message": "Zamówienie jest już rozliczone."
}
Endpointy referencyjne zwracają listy dostępnych opcji (metody dostawy, płatności, statusy, kategorie). Używaj ich do poznania dostępnych ID przy tworzeniu/aktualizacji produktów i zamówień.
Resetuje limit pobrań plików elektronicznych zamówienia (wszystkich lub jednego kodu, gdy podasz code_id). Zwraca odświeżone kody z linkami do pobrania.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
code_id | integer | Nie | Reset tylko jednego kodu treści elektronicznej |
{
"data": {
"order_id": 1024,
"reset_codes": [
{
"id": 55,
"file_name": "ebook.pdf",
"link": "https://your-shop.salescrm.pl/electronic_contents/download/abc123",
"usages": 0,
"usages_to_expire": 5
}
]
}
}
Raport sprzedaży: liczba i suma zamówień złożonych w wybranym okresie. Tylko zamówienia ze statusem placed - anulowane (canceled) i zwrócone (returned) są pomijane. Pozwala filtrować po produktach, kliencie i statusie płatności, oraz grupować dane po dniu, tygodniu lub miesiącu (do rysowania wykresów).
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
date_from | string | Tak | Data początkowa, YYYY-MM-DD (włącznie) |
date_to | string | Tak | Data końcowa, YYYY-MM-DD (włącznie). Maksymalny zakres: 1830 dni (~5 lat). |
group_by | string | Nie | total (domyślnie - jedna agregacja), day, week lub month |
product_id | integer / lista | Nie | ID produktu - filtr po liniach zamówienia. Lista po przecinku. |
sku | string / lista | Nie | SKU produktu - filtr po liniach zamówienia. Lista po przecinku. |
status | integer | Nie | ID statusu zamówienia (order_status_id) |
payment_status | string | Nie | paid / unpaid |
customer_email | string | Nie | Email klienta |
GET /api/v1/reports/sales?date_from=2026-04-01&date_to=2026-04-30
{
"data": {
"date_from": "2026-04-01",
"date_to": "2026-04-30",
"currency": "PLN",
"total_revenue": "12450.00",
"orders_count": 187,
"paid_revenue": "10300.00",
"paid_orders_count": 154,
"avg_order_value": "66.58"
}
}
GET /api/v1/reports/sales?date_from=2026-04-01&date_to=2026-04-30&group_by=day&product_id=42
{
"data": {
"date_from": "2026-04-01",
"date_to": "2026-04-30",
"currency": "PLN",
"total_revenue": "3200.00",
"orders_count": 64,
"paid_revenue": "2950.00",
"paid_orders_count": 59,
"avg_order_value": "50.00",
"buckets": [
{ "date": "2026-04-01", "orders_count": 3, "total_revenue": "150.00" },
{ "date": "2026-04-02", "orders_count": 5, "total_revenue": "275.00" }
]
}
}
Raport płatności: liczba i suma zamówień opłaconych w wybranym okresie z rozbiciem na metody płatności. Akceptuje te same filtry co /reports/sales.
Parametry
| Parameter | Type | Wymagany | Opis |
|---|---|---|---|
date_from | string | Tak | Data początkowa, YYYY-MM-DD |
date_to | string | Tak | Data końcowa, YYYY-MM-DD. Maks. zakres 1830 dni (~5 lat). |
group_by | string | Nie | total, day, week lub month |
product_id / sku | integer / string | Nie | Filtr po linii zamówienia (lista po przecinku) |
customer_email | string | Nie | Email klienta |
{
"data": {
"date_from": "2026-04-01",
"date_to": "2026-04-30",
"currency": "PLN",
"total_paid": "10300.00",
"count": 154,
"by_payment_type": [
{ "payment_type": "Tpay - BLIK", "count": 92, "amount": "5800.00" },
{ "payment_type": "Tpay - karta", "count": 41, "amount": "3200.00" },
{ "payment_type": "Pobranie", "count": 21, "amount": "1300.00" }
]
}
}
Lista aktywnych metod dostawy.
{
"data": [
{
"id": 1,
"name": "InPost Kurier",
"name_displayed": "Kurier InPost",
"default_price": "14.99",
"vat_rate": 23
}
]
}
Lista aktywnych metod płatności.
{
"data": [
{
"id": 3,
"name": "Tpay",
"name_displayed": "Przelew online",
"default_price": "0.0",
"vat_rate": 23,
"cash_on_delivery": false
}
]
}
Lista widocznych statusów zamówień. Użyj ID przy zmianie statusu zamówienia.
{
"data": [
{ "id": 1, "name": "Nowe" },
{ "id": 2, "name": "W realizacji" },
{ "id": 3, "name": "Wysłane" }
]
}
Lista kategorii produktów. Struktura drzewiasta - parent_id wskazuje na kategorię nadrzędną.
{
"data": [
{ "id": 5, "name": "Elektronika", "parent_id": null },
{ "id": 12, "name": "Smartfony", "parent_id": 5 }
]
}
Kody błędów
| Kod | Opis |
|---|---|
400 | Brak wymaganych parametrów |
401 | Brak lub nieprawidłowy klucz API |
404 | Zasób nie znaleziony |
415 | Content-Type musi być application/json |
422 | Błąd walidacji (szczegóły w polu errors) |
429 | Przekroczono limit requestów |
500 | Wewnętrzny błąd serwera |
Twoi klienci czekają.
Zacznij sprzedawać już teraz!
Załóż konto w 30 sekund. Dodaj produkty w 5 minut. Pierwszą sprzedaż zamknij jeszcze dziś.
Zacznij 7 dni za darmo →Bez karty kredytowej · Pełny dostęp · Rezygnujesz kiedy chcesz
