DOKUMENTACJA API

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.

Base URL
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.

Przykład
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ą.

Lista (sukces)
{
  "data": [...],
  "meta": {
    "page": 1,
    "per_page": 25,
    "total": 100,
    "total_pages": 4
  }
}
Błąd walidacji
{
  "error": "Unprocessable Entity",
  "errors": {
    "name": ["can't be blank"]
  }
}

Rate Limiting

TypLimitOpis
Ogólny100 req/minWszystkie endpointy
Mutacje30 req/minPOST, PATCH, DELETE

Po przekroczeniu limitu otrzymasz odpowiedź 429 Too Many Requests z nagłówkiem Retry-After.

Produkty
GET /api/v1/products

Lista produktów z paginacją.

Parametry

ParameterTypeWymaganyOpis
activestringNie"true" / "false"
category_idintegerNieID kategorii produktu
searchstringNieSzukaj po nazwie lub SKU
pageintegerNieNumer strony
per_pageintegerNieElementów na stronę (max 100)
Przykład odpowiedzi
{
  "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 }
}
GET /api/v1/products/:id

Szczegóły pojedynczego produktu.

curl
curl -H "X-API-KEY: your-key" \
  https://your-shop.salescrm.pl/api/v1/products/1
POST /api/v1/products

Tworzenie nowego produktu.

Parametry

ParameterTypeWymaganyOpis
namestringTakNazwa produktu
pricestringTakCena brutto
skustringNieSKU
vat_ratestringNieStawka VAT (np. "23")
activebooleanNieCzy aktywny
descriptionstringNieOpis produktu (HTML)
description_for_cartstringNieOpis wyświetlany w koszyku
electronic_productbooleanNieProdukt elektroniczny
distributionstringNienormal, audio, video, webinar, course
producerstringNieProducent
eanstringNieKod EAN (13 cyfr)
invoice_item_namestringNieNazwa na fakturze
pkwiustringNiePKWiU
product_linkstringNieLink do produktu (URL)
gtu_codestringNieKod GTU (GTU_01-GTU_13)
regular_price_displayedstringNieCena regularna (przekreślona)
allow_price_changebooleanNieKlient może zmienić cenę
minimal_pricestringNieMinimalna cena (gdy allow_price_change)
allow_zero_minimal_pricebooleanNieCzy cena minimalna może być 0
delivery_type_idsarrayNieID metod dostawy
payment_type_idsarrayNieID metod płatności
product_category_idintegerNieID kategorii produktu
cart_quantity_limitintegerNieLimit ilości w koszyku
lump_codedecimalNieStawka ryczałtu (dla płatników na ryczałcie); dozwolone: 17, 15, 14, 12.5, 12, 10, 8.5, 5.5, 3
product_category_idsarrayNieKategorie 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)
photoobjectNieZdjęcie produktu: { "filename", "content_type", "data" (base64) }; null usuwa zdjęcie. W odpowiedzi photo_url
hide_in_xmlsbooleanNieUkryj w plikach XML
no_invoicebooleanNieNie generuj faktury
hide_invoice_address_fieldsbooleanNieUkryj pola adresu na fakturze
payment_return_urlstringNieURL powrotu po płatności
curl
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
PATCH /api/v1/products/:id

Aktualizacja produktu. Wysyłasz tylko zmienione pola.

curl
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
DELETE /api/v1/products/:id

Usunięcie produktu. Jeśli produkt ma zamówienia, zostanie ukryty zamiast usunięty.

Przykład odpowiedzi (ukryty)
POST /api/v1/products/:id/clone

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"
  }
}
Kody rabatowe
GET /api/v1/discount_codes

Lista kodów rabatowych z paginacją i filtrami.

Parametry

ParameterTypeWymaganyOpis
discount_typestringNieTyp 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)
activestringNie"true" / "false"
searchstringNieSzukaj po kodzie lub nazwie
pageintegerNieNumer strony
per_pageintegerNieElementów na stronę (max 100)
Przykład odpowiedzi
{
  "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 }
}
GET /api/v1/discount_codes/:id

Szczegóły pojedynczego kodu rabatowego.

curl
curl -H "X-API-KEY: your-key" \
  https://your-shop.salescrm.pl/api/v1/discount_codes/1
POST /api/v1/discount_codes

Tworzenie nowego kodu rabatowego.

Parametry

ParameterTypeWymaganyOpis
codestringTakKod rabatowy (unikalny)
discount_typestringTakpercentage_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
valuestringTak*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
namestringNieNazwa (widoczna tylko w panelu)
case_sensitivebooleanNieWielkość liter ma znaczenie (domyślnie true)
minimum_amountstringNieMinimalna kwota zamówienia
usages_limitintegerNieMaksymalna liczba użyć
usages_per_customer_limitintegerNieMaksymalna liczba użyć na klienta
start_datestringNieData rozpoczęcia (ISO 8601)
end_datestringNieData zakończenia (ISO 8601)
combine_with_other_discountbooleanNieŁącz z innymi rabatami (domyślnie true)
relation_with_productsstringNieall_products, selected_products, products_except, selected_categories, categories_except
product_idsarrayNieID produktów
product_category_idsarrayNieID kategorii
relation_with_delivery_typesstringNiedomestic_delivery_types_only, all_delivery_types, selected_delivery_types
delivery_type_idsarrayNieID metod dostawy
curl
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
PATCH /api/v1/discount_codes/:id

Aktualizacja kodu rabatowego. Wysyłasz tylko zmienione pola.

curl
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
DELETE /api/v1/discount_codes/:id

Usunięcie kodu rabatowego.

Zamówienia powiązane z tym kodem zachowują informację o rabacie, ale powiązanie z kodem zostaje usunięte.

Przykład odpowiedzi
{
  "data": {
    "id": 1,
    "deleted": true
  }
}
Pliki produktu

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 e-booki: PDF, EPUB i MOBI (także AZW3), 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.

Plik, który już jest w sklepie, podepniesz bez wgrywania. Zamiast file wyślij source_content_id, czyli id pliku innego produktu z listy poniżej. Tak złożysz pakiet z e-booków sprzedawanych osobno, choć API nie wydaje linków do plików. Kopia korzysta z tego samego pliku co źródło, więc nie ma limitu rozmiaru, a usunięcie kopii nie usuwa pliku z produktu źródłowego.

GET /api/v1/products/:product_id/electronic_contents

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.

Odpowiedź
{
  "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"
    }
  ]
}
POST /api/v1/products/:product_id/electronic_contents

Dodaje plik do produktu. Wymaga klucza z zakresem write_data.

Parametry

ParameterTypeWymaganyOpis
fileobjectTak, jeśli brak source_content_id{filename, content_type, data} - data w base64. PDF, EPUB i MOBI (także AZW3), maks. 50 MB. Typ rozpoznajemy z zawartości pliku, nie z pola content_type
source_content_idintegerTak, jeśli brak fileid pliku innego produktu tego sklepu (z GET .../electronic_contents). Podpina ten sam plik bez wgrywania. Ustawienia (limity, znak wodny, opis) przechodzą ze źródła, a pola wysłane w żądaniu je nadpisują. Nie łączy się z file
kindstringNienormal (domyślnie) - plik do pobrania
days_to_expireintegerTak, przy fileIle dni od zakupu działa link do pobrania
usages_to_expireintegerTak, przy fileIle razy kupujący może pobrać plik
watermarkstringNieTreść znaku wodnego, maks. 128 znaków. Puste = brak znaku. Znaczniki: {{IMIE}}, {{NAZWISKO}}, {{EMAIL}}
watermark_intervalintegerNieCo ile stron powtarzać znak wodny (domyślnie 1)
descriptionstringNieOpis, maks. 30 000 znaków
curl
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..."
        }
      }'
curl: plik z innego produktu
curl -X POST "https://twoj-sklep.salescrm.pl/api/v1/products/18246/electronic_contents" \
  -H "X-API-KEY: TWOJ_KLUCZ" \
  -H "Content-Type: application/json" \
  -d '{"source_content_id": 4412}'

Błędy

KodKiedy
400file nie jest obiektem z polem data, albo wysłano naraz file i source_content_id
413Plik przekracza 50 MB (sprawdzane przed rozkodowaniem)
422Plik nie jest PDF-em ani EPUB-em, albo brakuje days_to_expire / usages_to_expire
422source_content_id nie wskazuje pliku produktu z tego sklepu
404Produkt nie istnieje w tym sklepie
PATCH /api/v1/products/:product_id/electronic_contents/:id

Zmiana ustawień pliku - na przykład treści znaku wodnego albo limitów. Przesłanie file podmienia sam plik.

DELETE /api/v1/products/:product_id/electronic_contents/:id

Usuwa plik z produktu. Kody pobrań wydane wcześniejszym kupującym przestają działać.

Pule kodów rabatowych

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.

GET /api/v1/discount_code_pools

Lista pul z licznikami kodów.

Parametry

ParameterTypeWymaganyOpis
searchstringNieFragment nazwy puli
pageintegerNieNumer strony (domyślnie 1)
per_pageintegerNieWyników na stronę (domyślnie 25, maks. 100)
Lista (sukces)
{
  "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 }
}
GET /api/v1/discount_code_pools/:id

Pojedyncza pula - ten sam zestaw pól co na liście. Przydatne do sprawdzenia, ile kodów jeszcze zostało (codes_remaining).

POST /api/v1/discount_code_pools/:id/draw

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

ParameterTypeWymaganyOpis
countintegerTakIle kodów pobrać (liczba dodatnia)
validity_hoursintegerTakIle godzin mają być ważne, licząc od pobrania
curl
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}'
Odpowiedź (201)
{
  "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

KodKiedy
400count lub validity_hours nie jest dodatnią liczbą całkowitą
422Pula nie działa w trybie pobierania albo zostało w niej mniej wolnych kodów, niż zamawiasz (paczka nie jest wtedy wydawana częściowo)
404Pula nie istnieje w tym sklepie
Rabaty bez kodu

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

ParameterTypeWymaganyOpis
discount_typestringTakpercentage_discount, value_discount, unit_price_discount. W promocjach czasowych dodatkowo percentage_product_discount i value_product_discount (warianty omnibusowe, przeliczają ceny produktów)
valuestringTakProcent, kwota albo - dla unit_price_discount - cena docelowa jednej sztuki
relation_with_productsstringTakall_products, selected_products, products_except, selected_categories, categories_except
product_idsarrayNieID produktów. Identyfikator spoza Twojego sklepu kończy się odpowiedzią 422, a nie cichym pominięciem
product_category_idsarrayNieID kategorii
usages_limitintegerNieMaksymalna 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.

GET /api/v1/email_address_discounts

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 - każdy tytuł po 99 zł dla jednego adresu
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
Przykład odpowiedzi
{
  "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"
  }
}
GET /api/v1/email_domain_discounts

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
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
GET /api/v1/newsletter_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
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
GET /api/v1/time_limited_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
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

KodKiedy
422Nieznany discount_type albo relation_with_products, produkt lub kategoria spoza Twojego sklepu, błąd walidacji (np. data zakończenia przed początkiem)
404Rabat nie istnieje w tym sklepie
403Klucz bez zakresu write_data przy zapisie lub usuwaniu
Zamówienia
GET /api/v1/product_recommendation_groups

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

ParameterTypeWymaganyOpis
activestringNie"true" / "false"
product_idintegerNieTylko grupy zawierające dany produkt
searchstringNieSzukaj po nazwie lub tytule
page, per_pageintegerNiePaginacja (max 100)
Przykład odpowiedzi
{
  "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 }
}
POST /api/v1/product_recommendation_groups

Tworzy grupę upsellingu wraz z pozycjami. Każdy product_id jest walidowany względem Twojego sklepu.

Parametry

ParameterTypeWymaganyOpis
namestringTakWewnętrzna nazwa grupy
title, subtitlestringNieNagłówek/podtytuł ramki w koszyku
activebooleanNieCzy grupa aktywna
itemsarrayNiePozycje: product_id (wymagane), priority, invokes_recommendation, is_recommended, title, subtitle
Przykład żądania
{
  "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 }
    ]
  }
}
PATCH /api/v1/product_recommendation_groups/:id

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.

DELETE /api/v1/product_recommendation_groups/:id

Usuwa grupę wraz z pozycjami. Odpowiedź: { "data": { "id": 7, "deleted": true } }.

GET /api/v1/product_sets

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

ParameterTypeWymaganyOpis
activestringNie"true" / "false"
product_idintegerNieTylko zestawy zawierające dany produkt
searchstringNieSzukaj po nazwie
page, per_pageintegerNiePaginacja (max 100)
Przykład odpowiedzi
{
  "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 }
}
POST /api/v1/product_sets

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

ParameterTypeWymaganyOpis
namestringTakNazwa zestawu
pricedecimalTakCena zestawu
activebooleanNieCzy zestaw aktywny (domyślnie true)
priorityintegerNieKolejność na listach (wyższy = wyżej)
auto_calculate_pricesbooleanNieAutomatyczny 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_discountbooleanNieZestaw dostępny tylko z bezpośredniego linku
pool_modebooleanNieTryb puli: klient wybiera pool_pick_count produktów z pozycji zestawu
pool_pick_countintegerPrzy puliIlu produktów dotyczy wybór (min. 2, nie więcej niż liczba pozycji)
custom_payment_typesbooleanNieWłasne formy płatności zestawu; wymaga payment_type_ids
payment_type_idsarrayNieID form płatności (patrz GET /payment_types)
expose_in_feeds, feed_description, ean, google_product_category, producer-NieDane do porównywarek (feed wymaga opisu)
product_category_idintegerNieKategoria produktowa zestawu
itemsarrayTakPozycje: product_id (wymagane), quantity (domyślnie 1), custom_price
Przykład żądania - pula „wybierz 3 z listy"
{
  "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 }
    ]
  }
}
PATCH /api/v1/product_sets/:id

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ę.

DELETE /api/v1/product_sets/:id

Usuwa zestaw wraz z pozycjami. Odpowiedź: { "data": { "id": 4, "deleted": true } }.

GET /api/v1/subscription_plans

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

ParameterTypeWymaganyOpis
automatic_renewalstringNie"true" / "false" - tylko plany z automatycznym odnawianiem (lub bez)
searchstringNieSzukaj po nazwie
page, per_pageintegerNiePaginacja (max 100)
Przykład odpowiedzi
{
  "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 }
}
POST /api/v1/subscription_plans

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

ParameterTypeWymaganyOpis
namestringTakNazwa planu
automatic_renewalbooleanNieAutomatyczne odnawianie (płatności cykliczne). Produkt może należeć tylko do jednego auto-planu - konflikt zwróci 422.
extension_strategystringNieimmediate lub continuous
free_delivery_minimum_amountdecimalNieMinimalna kwota zamówienia dla darmowej dostawy subskrybenta
superseded_subscription_plan_idintegerNiePlan kończony przy nadaniu tego planu
send_email_about_activation, ..._renewal, ..._expiration_in_one_day, ..._expiration_in_one_weekbooleanNiePrzełączniki maili subskrypcyjnych
productsarrayNiePowiązania: product_id (wymagane), interval (dni, wymagane, 1-36500), renewals_limit (0 = bez limitu)
Przykład żądania
{
  "subscription_plan": {
    "name": "Klub miesięczny",
    "automatic_renewal": true,
    "extension_strategy": "continuous",
    "products": [
      { "product_id": 123, "interval": 30, "renewals_limit": 12 }
    ]
  }
}
PATCH /api/v1/subscription_plans/:id

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.

DELETE /api/v1/subscription_plans/:id

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.

GET /api/v1/subscribers

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.

PATCH /api/v1/subscribers/:id

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

ParameterTypeOpis
renewal_itemsarrayPozycje 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_daysintegerDługość kolejnych okresów; puste = z produktu. Nie zmienia trwającego okresu.
renewal_pausedbooleanWstrzymanie odnawiania. Karta zostaje zapisana - wznowienie nie wymaga od klienta ponownego podania danych.
custom_identifierstringTwoja etykieta usługi (np. nazwa serwera). service_ref nie jest zapisywalny - zmiana odczepiłaby subskrypcję od jej łańcucha odnowień.
Przykład: klient rezygnuje z dodatkowego dysku
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.

PATCH /api/v1/subscribers/:id/period

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).

GET /api/v1/orders

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

ParameterTypeOpis
statusintegerID statusu zamówienia (order_status_id)
internal_statusstringplaced, canceled, returned
payment_statusstringpaid / unpaid
date_fromstringYYYY-MM-DD
date_tostringYYYY-MM-DD
customer_emailstringEmail klienta
searchstringSzukaj po numerze zamówienia
product_idinteger / listaID produktu - zwraca tylko zamówienia zawierające ten produkt. Możesz podać kilka ID po przecinku, np. product_id=12,17,33.
skustring / listaSKU produktu - zwraca zamówienia zawierające produkt o tym SKU. Możesz podać kilka SKU po przecinku.
Przykład odpowiedzi
{
  "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,
      "invoice_number": "FV/2026/03/017",
      "transaction_id": "TR-9GXK-A1B2C3D",
      "paid_at": "2026-03-01T14:31:00Z",
      "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 }
}
GET /api/v1/orders/:id

Szczegóły zamówienia z pozycjami, adresami, kosztami, atrybutami i notatkami.

Pola w odpowiedzi

PoleTypOpis
order_status_idintegerNumeryczny ID statusu zamówienia (użyj do zmiany statusu przez PATCH /orders/:id/status)
invoice_numberstringNumer dokumentu sprzedaży wystawionego do zamówienia (np. FV/2026/03/017). null, gdy faktury jeszcze nie wystawiono albo wystawiono ją poza systemem. Pole dostępne też na liście zamówień.
transaction_idstringIdentyfikator transakcji w bramce płatniczej - ten sam, który widnieje w panelu operatora (Tpay, PayU, Autopay, Paynow, ZEN, Przelewy24, Stripe). Służy do uzgadniania wpłat z raportem operatora. null przy zamówieniach bez płatności online (pobranie, rozliczenie ręczne). Pole dostępne też na liście zamówień.
paid_atstringData potwierdzenia płatności przez bramkę (ISO 8601). null, gdy płatność nie została potwierdzona. Pole dostępne też na liście zamówień.
refstringKod polecający (ref kod ze sprzedaży afiliacyjnej), z którym klient złożył zamówienie. W panelu widoczny jako Ref. null, gdy zamówienie nie przyszło z polecenia. Pole dostępne też na liście zamówień.
subscriber_identifierstringParametr zamówienia subscriber_identifier (w panelu: Parametr zamówienia - subscriber_identifier). null, gdy go nie przekazano. Pole dostępne też na liście zamówień.
items[].subscriber_identifiersarrayParametry subscriber_identifier przekazane przy dodawaniu produktu do koszyka, po jednym na sztukę (w panelu: Parametr produktu - subscriber_identifier). Pusta tablica, gdy ich nie przekazano.
items[].refstringParametr ref z linku dodającego produkt do koszyka, tak jak w webhooku zamówień. Kilka wartości łączy znak &. null, gdy go nie przekazano.
invoice_recipient_namestringDodatkowe informacje na fakturze (np. nazwa odbiorcy, jeśli inny niż nabywca)
placed_ipstring|nullAdres IP kupującego z chwili złożenia zamówienia w koszyku. null dla zamówień z panelu, odnowień subskrypcji i zamówień sprzed 29.09.2026
notesarrayNotatki admina - tablica obiektów z polami content (treść) i created_at (data dodania)
Przykład odpowiedzi
{
  "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,
    "invoice_number": "FV/2026/03/017",
    "transaction_id": "TR-9GXK-A1B2C3D",
    "paid_at": "2026-03-01T14:31:00Z",
    "delivery_method": "Kurier DPD",
    "ref": "anna-poleca",
    "subscriber_identifier": null,
    "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",
        "subscriber_identifiers": ["konto-1234"],
        "ref": null
      }
    ],
    "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",
    "placed_ip": "85.89.185.181",
    "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" }
    ]
  }
}
PATCH /api/v1/orders/:id/status

Zmiana statusu zamówienia.

Parametry

ParameterTypeWymaganyOpis
order_status_idintegerTakID nowego statusu

Uwaga: Zmiana statusu wywołuje te same efekty uboczne co w panelu admina (eventy, emaile, webhooki).

curl
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
PATCH /api/v1/orders/:id/clear

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

WarunekOdpowiedź
Zamówienie nieopłacone200 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
curl -X PATCH \
  -H "X-API-KEY: your-key" \
  https://your-shop.salescrm.pl/api/v1/orders/42/clear
Przykład odpowiedzi (sukces)
{
  "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"
  }
}
Przykład błędu (już rozliczone)
{
  "error": "Already Cleared",
  "message": "Zamówienie jest już rozliczone."
}
Dane referencyjne

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ń.

POST /api/v1/orders/:id/reset_download_limit

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

ParameterTypeWymaganyOpis
code_idintegerNieReset tylko jednego kodu treści elektronicznej
Przykład odpowiedzi
{
  "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
      }
    ]
  }
}
GET /api/v1/reports/sales

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

ParameterTypeWymaganyOpis
date_fromstringTakData początkowa, YYYY-MM-DD (włącznie)
date_tostringTakData końcowa, YYYY-MM-DD (włącznie). Maksymalny zakres: 1830 dni (~5 lat).
group_bystringNietotal (domyślnie - jedna agregacja), day, week lub month
product_idinteger / listaNieID produktu - filtr po liniach zamówienia. Lista po przecinku.
skustring / listaNieSKU produktu - filtr po liniach zamówienia. Lista po przecinku.
statusintegerNieID statusu zamówienia (order_status_id)
payment_statusstringNiepaid / unpaid
customer_emailstringNieEmail klienta
Przykład: total w miesiącu
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"
  }
}
Przykład: dziennie + filtr po produkcie
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" }
    ]
  }
}
GET /api/v1/reports/payments

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

ParameterTypeWymaganyOpis
date_fromstringTakData początkowa, YYYY-MM-DD
date_tostringTakData końcowa, YYYY-MM-DD. Maks. zakres 1830 dni (~5 lat).
group_bystringNietotal, day, week lub month
product_id / skuinteger / stringNieFiltr po linii zamówienia (lista po przecinku)
customer_emailstringNieEmail klienta
Przykład odpowiedzi
{
  "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" }
    ]
  }
}
GET /api/v1/delivery_types

Lista aktywnych metod dostawy.

Przykład odpowiedzi
{
  "data": [
    {
      "id": 1,
      "name": "InPost Kurier",
      "name_displayed": "Kurier InPost",
      "default_price": "14.99",
      "vat_rate": 23
    }
  ]
}
GET /api/v1/payment_types

Lista aktywnych metod płatności.

Przykład odpowiedzi
{
  "data": [
    {
      "id": 3,
      "name": "Tpay",
      "name_displayed": "Przelew online",
      "default_price": "0.0",
      "vat_rate": 23,
      "cash_on_delivery": false
    }
  ]
}
GET /api/v1/order_statuses

Lista widocznych statusów zamówień. Użyj ID przy zmianie statusu zamówienia.

Przykład odpowiedzi
{
  "data": [
    { "id": 1, "name": "Nowe" },
    { "id": 2, "name": "W realizacji" },
    { "id": 3, "name": "Wysłane" }
  ]
}
GET /api/v1/product_categories

Lista kategorii produktów. Struktura drzewiasta - parent_id wskazuje na kategorię nadrzędną.

Przykład odpowiedzi
{
  "data": [
    { "id": 5, "name": "Elektronika", "parent_id": null },
    { "id": 12, "name": "Smartfony", "parent_id": 5 }
  ]
}
Integracja ImkerClub

Konfiguracja z panelu Integracje → Kursy → ImkerClub. Odczyt wymaga zakresu read, każdy zapis zakresu write_config. Adres webhooka i klucz działają tylko w jedną stronę: platformy ImkerClub uwierzytelniają się tokenem w adresie, więc API zwraca samą domenę i flagi *_configured. Pusta lista produktów oznacza wysyłkę przy każdym zamówieniu w wybranym statusie, o czym mówi pole fires_for_all_products.

GET /api/v1/configuration/imker_club

Aktualne ustawienia integracji. Dopóki integracja nie jest założona, configured ma wartość false, a pozostałe pola pokazują wartości domyślne.

Przykład odpowiedzi
{
  "data": {
    "configured": true,
    "active": true,
    "webhook_url_configured": true,
    "webhook_host": "strefa.twojadomena.pl",
    "webhook_secret_key_configured": false,
    "order_status_id": 12,
    "product_ids": [101, 102],
    "products": [
      { "id": 101, "name": "Kurs wideo" },
      { "id": 102, "name": "E-book" }
    ],
    "fires_for_all_products": false
  }
}
PATCH /api/v1/configuration/imker_club

Zmienia tylko przesłane pola. Gdy integracji jeszcze nie ma, zakłada ją, a wtedy webhook_url jest wymagany. Błąd walidacji cofa cały zapis, łącznie z listą produktów. Odpowiedź ma ten sam kształt co GET.

Parametry

ParameterTypeWymaganyOpis
activebooleanNieCzy integracja wysyła webhooki
order_status_idintegerNieStatus zamówienia, przy którym idzie webhook. Domyślnie status opłacenia
webhook_urlstringPrzy zakładaniuAdres z panelu platformy ImkerClub. Pusty napis zostawia obecny adres, null go czyści, co kończy się błędem 422
webhook_secret_keystringNieKlucz podpisu. Pusty napis zostawia obecny, null czyści
product_idsarrayNieZastępuje całą listę. Produkt innego sklepu albo nieistniejący zwraca 422 i nic się nie zapisuje
Przykład żądania
{
  "active": true,
  "webhook_url": "https://strefa.twojadomena.pl/api/webhook/register/TOKEN",
  "product_ids": [101, 102]
}
POST /api/v1/configuration/imker_club/products

Dopisuje produkty do listy i nie rusza pozostałych. Produkty, które już są na liście, zostają pominięte. Zwraca pełną konfigurację. Gdy integracja nie jest założona, zwraca 404. Nieznany produkt zwraca 422.

Parametry

ParameterTypeWymaganyOpis
product_idsarrayTakID produktów do dopisania
DELETE /api/v1/configuration/imker_club/products/:product_id

Usuwa jeden produkt z listy i zwraca pełną konfigurację. Produkt spoza listy zwraca 404. Usunięcie ostatniego produktu przełącza integrację na wysyłkę przy każdym zamówieniu (fires_for_all_products: true).

Statusy zamówień

Ustawienia z panelu Konfiguracja → Statusy zamówień razem z treścią maila, który wychodzi po nadaniu statusu. Odczyt wymaga zakresu read, zapis zakresu write_storefront. Statusów nie zakładasz ani nie kasujesz przez API — to zostaje w panelu. Załączniki do maila i podmianki treści per produkt, płatność czy kod rabatowy również zmieniasz tylko w panelu. Wyjątek to treści per sposób dostawy (znaczniki {{DOSTAWA_...}}, np. przycisk śledzenia przesyłki) — te ustawisz przez API.

GET /api/v1/configuration/order_statuses

Lista widocznych statusów z ustawieniami i treścią maila. Pojedynczy status pobierzesz spod /api/v1/configuration/order_statuses/:id.

Pola w odpowiedzi

PoleTypOpis
kindstringTylko do odczytu. Klasa statusu wbudowanego, np. NewDefaultOrderStatus, PaidDefaultOrderStatus, albo UserOrderStatus dla statusu dodanego ręcznie. Po niej rozpoznasz status niezależnie od nazwy, którą sprzedawca może zmienić.
name_editablebooleanTylko do odczytu. false przy statusach wbudowanych — ich nazwy nie da się zmienić.
emailobjectsubject, content (HTML), electronic_order_substitution_content i delivery_type_substitutions. null, gdy status nie ma jeszcze szablonu wiadomości.
email.delivery_type_substitutions[]arrayTreści per sposób dostawy: name (np. DOSTAWA_1851_1), tag (znacznik do wklejenia w content, np. {{DOSTAWA_1851_1}}), delivery_type_id i content. Znacznik zamienia się na content tylko wtedy, gdy klient wybrał tę dostawę. Przy innej znika.
send_email_on_status_changebooleanCzy nadanie statusu wysyła maila.
sender_idintegerNadawca wiadomości z Konfiguracja → Nadawcy wiadomości.
bcc_email_addressstringAdres w kopii ukrytej.
treat_order_as_handledbooleanCzy zamówienie w tym statusie liczy się jako obsłużone.
automatically_setbooleanAutomatyczne nadawanie statusu, razem z automatically_set_offset_days, automatically_set_offset_hours, automatically_set_if_total_zero i automatically_set_only_for_salescrm_origin_orders.
Przykład odpowiedzi
{
  "data": [
    {
      "id": 12,
      "name": "Opłacone",
      "kind": "PaidDefaultOrderStatus",
      "name_editable": false,
      "send_email_on_status_change": true,
      "sender_id": 3,
      "bcc_email_address": null,
      "treat_order_as_handled": false,
      "automatically_set": null,
      "email": {
        "subject": "Płatność przyjęta",
        "content": "<p>Dziękujemy za zakup.</p>",
        "electronic_order_substitution_content": null,
        "delivery_type_substitutions": []
      }
    }
  ]
}
PATCH /api/v1/configuration/order_statuses/:id

Zmienia ustawienia statusu i treść jego maila. Przesyłasz tylko te pola, które zmieniasz.

Pierwszy zapis maila przy statusie bez szablonu musi zawierać subject i content razem — oba są wymagane, samo subject zwróci 422. Szablon powstaje wtedy automatycznie, tak jak w panelu po wejściu w edycję wiadomości.

Nazwy statusu wbudowanego nie zmienisz — próba kończy się kodem 422, zamiast po cichu nic nie zrobić. Nadawca z innego sklepu to 422, status z innego sklepu to 404.

curl
curl -X PATCH \
  -H "X-API-KEY: your-key" \
  -H "Content-Type: application/json" \
  -d '{"send_email_on_status_change": true, "email": {"subject": "Zamówienie wysłane", "content": "<p>Paczka w drodze.</p>"}}' \
  https://your-shop.salescrm.pl/api/v1/configuration/order_statuses/12

Treści per sposób dostawy

W email.delivery_type_substitutions wysyłasz pełną nową listę bloków, tak jak w panelu w Znaczniki powiązane z rodzajami dostawy. Bez tego klucza bloki zostają bez zmian.

PoleTypOpis
namestringNazwa istniejącego bloku z odczytu. Z nią zmieniasz treść tego bloku. Bez niej powstaje nowy blok z nazwą DOSTAWA_<delivery_type_id>_<n>, gdzie n to kolejny wolny numer dla tej dostawy, tak samo jak w panelu.
delivery_type_idintegerSposób dostawy z GET /api/v1/delivery_types. Wymagany przy nowym bloku.
contentstringHTML bloku. Działa w nim m.in. {{NUMER_PACZKI}}.

Blok pominięty na liście jest usuwany, a jego znacznik znika z treści maila, tak jak po kliknięciu „Usuń” w panelu. Żeby dodać blok, pobierz status, dołóż pozycję do listy i wyślij całość. Nieznana nazwa, dostawa spoza sklepu, przeniesienie bloku na inną dostawę albo wartość, która nie jest tablicą, to 422, a status zostaje bez zmian. Nowy znacznik wklej do content maila w tym samym albo kolejnym żądaniu.

curl
curl -X PATCH \
  -H "X-API-KEY: your-key" \
  -H "Content-Type: application/json" \
  -d '{"email": {"delivery_type_substitutions": [
        {"name": "DOSTAWA_1851_1", "content": "<a href=\"https://tracktrace.dpd.com.pl/parcelDetails?typ=1&p1={{NUMER_PACZKI}}\">Śledź przesyłkę</a>"},
        {"delivery_type_id": 2398, "content": "<a href=\"https://emonitoring.poczta-polska.pl/?numer={{NUMER_PACZKI}}\">Śledź przesyłkę</a>"}
      ]}}' \
  https://your-shop.salescrm.pl/api/v1/configuration/order_statuses/12
POST /api/v1/configuration/order_statuses/:id/test_email

Wysyła od razu zapisany mail statusu na podany adres. Treść, załączniki, nadawca i znaczniki są takie same jak przy zmianie statusu. Klient nic nie dostaje, a zamówienie i jego historia zostają bez zmian. Wymaga zakresu write_storefront.

PoleTypOpis
emailstringAdres, na który idzie test. Wymagany.
order_numberstringOpcjonalny numer zamówienia, np. 1234 albo #1234. Znaczniki wypełnią się danymi tego zamówienia, łącznie z blokami per produkt, dostawa i płatność. Bez numeru znaczniki zamówienia są puste.

Z numerem zamówienia linki do pobrania plików są prawdziwe. Otwarcie ich w teście zużywa limit pobrań klienta. Brak lub błędny adres, nieznany numer zamówienia albo status bez maila to 422, status z innego sklepu to 404.

curl
curl -X POST \
  -H "X-API-KEY: your-key" \
  -H "Content-Type: application/json" \
  -d '{"email": "admin@twojsklep.pl", "order_number": "1234"}' \
  https://your-shop.salescrm.pl/api/v1/configuration/order_statuses/12/test_email
POST /api/v1/configuration/order_statuses/test_emails

Wysyła testowo maile wszystkich statusów naraz, po jednym na każdy status z zapisanym mailem. Pola email i order_number działają jak wyżej. Opcjonalna tablica ids zawęża wysyłkę do wskazanych statusów.

W odpowiedzi sent to wysłane statusy (id, name, send_email_on_status_change), a skipped to statusy bez maila z powodem no_email. send_email_on_status_change: false oznacza, że mail istnieje, ale przy prawdziwej zmianie statusu nie wychodzi. Adres i numer zamówienia są sprawdzane przed wysyłką, więc 422 oznacza, że nic nie poszło.

curl
curl -X POST \
  -H "X-API-KEY: your-key" \
  -H "Content-Type: application/json" \
  -d '{"email": "admin@twojsklep.pl"}' \
  https://your-shop.salescrm.pl/api/v1/configuration/order_statuses/test_emails
Sekwencje wiadomości

Treści i harmonogram sekwencji z panelu Wiadomości → Sekwencje wiadomości. Odczyt wymaga zakresu read, zapis zakresu write_storefront. Przez API ustawisz też automatyzację, czyli to, kiedy sekwencja rusza: status, produkty, kod rabatowy, plan abonamentowy, zapis na newsletter i indywidualny kod rabatowy dla odbiorcy. Całe sekwencje zakładasz i kasujesz w panelu.

GET /api/v1/configuration/email_sequences

Lista sekwencji z wiadomościami. Pojedynczą sekwencję pobierzesz spod /api/v1/configuration/email_sequences/:id.

Pola w odpowiedzi

PoleTypOpis
name, sender_idstring, integerNazwa sekwencji i nadawca z Konfiguracja → Nadawcy wiadomości.
sending_timestringGodzina wysyłek w formacie HH:MM. Dotyczy wiadomości liczonych w dniach.
only_first_purchasebooleanCzy sekwencja rusza tylko przy pierwszym zakupie klienta.
items[]arrayWiadomości po kolei: id, email (subject, content), offset_amount i offset_unit, a do odczytu także days_offset, offset_hours i schedule — zdanie, które panel pokazuje pod polami harmonogramu.
triggersobjectstatus_id, products_dependent (czy sekwencja rusza tylko przy wybranych produktach), product_ids, discount_code_id, subscription_plan_id, newsletter_subscription, first_subscription_entry. Zapis: automatyzacja sekwencji.
recipient_discount_codeobjectenabled, type, value, validity_days, product_ids (produkty objęte kodem).
PATCH /api/v1/configuration/email_sequences/:id

Zmienia name, sender_id, sending_time i only_first_purchase, a w tym samym żądaniu także automatyzację. Wyzwalacze, których nie wysyłasz, zostają nietknięte, także wtedy, gdy zmieniasz samą nazwę. Nadawca z innego sklepu to 422, sekwencja z innego sklepu to 404.

curl
curl -X PATCH \
  -H "X-API-KEY: your-key" \
  -H "Content-Type: application/json" \
  -d '{"name": "Wysyłka e-booka", "sending_time": "09:00"}' \
  https://your-shop.salescrm.pl/api/v1/configuration/email_sequences/8
PATCH /api/v1/configuration/email_sequences/:id

Automatyzacja sekwencji, czyli ekran Automatyzacja w panelu. Wysyłasz obiekt triggers i opcjonalnie recipient_discount_code. Każde pole jest opcjonalne: czego nie wyślesz, to się nie zmieni.

Pola triggers

PoleTypOpis
status_idinteger lub nullStatus zamówienia, który uruchamia sekwencję (lista: statusy zamówień). null wyłącza wysyłkę po statusie razem z zawężeniem do produktów i kodu, tak jak odznaczenie „Zaplanuj wysyłkę” w panelu.
products_dependentbooleanSekwencja rusza tylko wtedy, gdy zamówienie zawiera jeden z produktów z product_ids. Wymaga statusu. false czyści listę produktów.
product_idsarrayPełna nowa lista, nie dopisek. Żeby dodać produkt, pobierz sekwencję, dołóż id i wyślij całą listę. Działa przy products_dependent: true, inaczej produkty nic by nie uruchamiały i dostaniesz 422. Pusta lista też daje 422.
discount_code_idinteger lub nullSekwencja rusza tylko przy zamówieniu z tym kodem. Tylko kody rodzaju „dodatkowe treści”, jak w panelu. Wymaga statusu. null wyłącza zawężenie.
first_subscription_entrybooleanSekwencja rusza, gdy u klienta pojawi się pierwszy wpis w planie subskrypcji. Wymaga subscription_plan_id.
subscription_plan_idinteger lub nullPlan z planów abonamentowych.
newsletter_subscriptionbooleanSekwencja rusza, gdy klient zapisze się na newsletter.

Pola recipient_discount_code

Indywidualny, jednorazowy kod rabatowy dla każdego odbiorcy. Wstawiasz go do treści znacznikami {{KOD_RABATOWY}} i {{LINK_Z_KODEM}}.

PoleTypOpis
enabledbooleanCzy generować kod. Przy true wymagane są wszystkie pola poniżej.
typestringpercentage_discount, value_discount albo unit_price_discount.
valuenumberProcent, kwota albo cena docelowa, zależnie od rodzaju.
validity_daysintegerWażność kodu w dniach od uruchomienia sekwencji u danego klienta.
product_idsarrayProdukty objęte kodem, pełna nowa lista.

Zły typ wartości, identyfikator spoza Twojego sklepu albo połączenie bez sensu (produkty bez statusu, pierwszy wpis w planie bez planu) kończy się kodem 422 z kluczem pola, np. triggers.status_id. Nic się wtedy nie zapisuje.

curl
curl -X PATCH \
  -H "X-API-KEY: your-key" \
  -H "Content-Type: application/json" \
  -d '{"triggers": {"status_id": 12, "products_dependent": true, "product_ids": [17475, 22803, 22804]}}' \
  https://your-shop.salescrm.pl/api/v1/configuration/email_sequences/8
POST /api/v1/configuration/email_sequences/:id/items

Dodaje wiadomość do sekwencji. Odstęp podajesz jako offset_amount i offset_unit (hours albo days) — ta sama para co w panelu. Zero wysyła natychmiast w obu jednostkach; dni liczą się o godzinie z pola sending_time. Odpowiedź: cała sekwencja, status 201.

Zmiana wiadomości to PATCH /api/v1/configuration/email_sequences/:id/items/:item_id z tymi samymi polami, a usunięcie to DELETE pod tym samym adresem. Ostatniej wiadomości nie usuniesz — sekwencja bez wiadomości nie przechodzi walidacji, więc próba kończy się kodem 422.

curl
curl -X POST \
  -H "X-API-KEY: your-key" \
  -H "Content-Type: application/json" \
  -d '{"offset_amount": 48, "offset_unit": "hours", "email": {"subject": "Jak idzie?", "content": "<p>Wracamy z pytaniem.</p>"}}' \
  https://your-shop.salescrm.pl/api/v1/configuration/email_sequences/8/items
Rodzaje dostaw i płatności

Te same pola, które edytujesz w panelu w Konfiguracja → Rodzaje dostaw i Rodzaje płatności: nazwa widoczna w koszyku, koszt, VAT, aktywność, próg darmowej dostawy. Odczyt wymaga zakresu read, zapis zakresu write_storefront. Dane bramek płatności (klucze Tpay, PayU) nie są tu dostępne. Nowe sposoby dostawy i płatności zakładasz w panelu. W odróżnieniu od GET /api/v1/delivery_types, który zwraca tylko aktywne metody, tu widzisz także wyłączone.

GET /api/v1/configuration/delivery_methods

Lista sposobów dostawy z ustawieniami. Pojedynczy sposób pobierzesz spod /api/v1/configuration/delivery_methods/:id.

Pola w odpowiedzi

PoleTypOpis
kindstringTylko do odczytu. Klasa przewoźnika, np. CourierInpostDeliveryType, LockerInpostDeliveryType, albo UserDeliveryType dla dostawy dodanej ręcznie.
namestringNazwa w panelu. Przy przewoźnikach wbudowanych tylko do odczytu (name_editable: false).
name_displayedstringNazwa, którą widzi klient w koszyku. null = taka sama jak name.
activebooleanCzy sposób dostawy jest dostępny w koszyku.
priorityintegerKolejność na liście w koszyku.
default_pricestringKoszt dostawy w PLN, np. "14.99".
vat_rateintegerStawka VAT dostawy.
text_on_freestringCo pokazać, gdy dostawa jest darmowa: hide (ukryj cenę), show_zero (0,00 zł), show_free („darmowa dostawa”).
free_delivery_amountstringWartość koszyka, od której dostawa jest darmowa. null = brak progu.
next_item_chargestringDopłata za każdy kolejny produkt, razem z next_item_charge_from (od którego produktu liczyć, min. 2).
max_packagesintegerMaksymalna liczba paczek. null = bez limitu.
international_delivery, electronic_shippingbooleanTylko do odczytu. Cenniki zagraniczne i flagę wysyłki elektronicznej ustawisz w panelu.
Przykład odpowiedzi
{
  "data": [
    {
      "id": 1851,
      "kind": "CourierInpostDeliveryType",
      "name_editable": false,
      "active": true,
      "name": "CourierInpostDeliveryType",
      "name_displayed": "Kurier InPost",
      "priority": 10,
      "default_price": "14.99",
      "vat_rate": 23,
      "text_on_free": "show_free",
      "free_delivery_amount": "199.0",
      "next_item_charge": "0.0",
      "next_item_charge_from": 2,
      "max_packages": null,
      "international_delivery": false,
      "electronic_shipping": false
    }
  ]
}
PATCH /api/v1/configuration/delivery_methods/:id

Zmienia ustawienia sposobu dostawy. Przesyłasz tylko te pola, które zmieniasz: active, name, name_displayed, priority, default_price, vat_rate, text_on_free, free_delivery_amount, next_item_charge, next_item_charge_from, max_packages. name_displayed: null wraca do nazwy z panelu.

Nazwy przewoźnika wbudowanego nie zmienisz — próba kończy się kodem 422, zamiast po cichu nic nie zrobić. Nazwę w koszyku (name_displayed) zmienisz przy każdym. Aktywna dostawa musi mieć cenę i stawkę VAT, nazwa musi być unikalna w sklepie, nieznana wartość text_on_free to 422. Dostawa z innego sklepu to 404.

curl
curl -X PATCH \
  -H "X-API-KEY: your-key" \
  -H "Content-Type: application/json" \
  -d '{"name_displayed": "Kurier InPost (1-2 dni robocze)", "default_price": 14.99, "free_delivery_amount": 199, "text_on_free": "show_free"}' \
  https://your-shop.salescrm.pl/api/v1/configuration/delivery_methods/1851
GET /api/v1/configuration/payment_methods

Lista sposobów płatności z ustawieniami. Pojedynczy sposób pobierzesz spod /api/v1/configuration/payment_methods/:id.

Pola w odpowiedzi

PoleTypOpis
kindstringTylko do odczytu. Klasa bramki, np. TpayPaymentType, PayuPaymentType, albo UserPaymentType dla płatności dodanej ręcznie (przelew, gotówka).
namestringNazwa w panelu.
name_displayedstringNazwa, którą widzi klient w koszyku. null = taka sama jak name.
activebooleanCzy sposób płatności jest dostępny w koszyku.
priorityintegerKolejność na liście w koszyku.
default_pricestringKoszt płatności w PLN. Może być ujemny — wtedy to rabat za wybór tej metody.
vat_rateintegerStawka VAT kosztu płatności.
text_on_freestringhide, show_zero albo show_free („darmowa płatność”).
cash_on_deliverybooleanCzy to płatność za pobraniem. Do zmiany tylko przy UserPaymentType (cash_on_delivery_editable: true).
Przykład odpowiedzi
{
  "data": [
    {
      "id": 902,
      "kind": "TpayPaymentType",
      "cash_on_delivery_editable": false,
      "active": true,
      "name": "Tpay",
      "name_displayed": "BLIK, e-przelewy, karta",
      "priority": 10,
      "default_price": "0.0",
      "vat_rate": 5,
      "text_on_free": "show_free",
      "cash_on_delivery": false
    }
  ]
}
PATCH /api/v1/configuration/payment_methods/:id

Zmienia ustawienia sposobu płatności. Przesyłasz tylko te pola, które zmieniasz: active, name, name_displayed, priority, default_price, vat_rate, text_on_free, cash_on_delivery.

Walidacja jest ta sama co w panelu: nazwa, koszt i stawka VAT są wymagane, nazwa musi być unikalna w sklepie. Pobranie włączysz tylko przy własnej metodzie płatności — przy bramce zmiana cash_on_delivery to 422. Płatność z innego sklepu to 404.

curl
curl -X PATCH \
  -H "X-API-KEY: your-key" \
  -H "Content-Type: application/json" \
  -d '{"name_displayed": "BLIK, e-przelewy, karta - wybierz poniżej", "vat_rate": 5, "text_on_free": "show_free"}' \
  https://your-shop.salescrm.pl/api/v1/configuration/payment_methods/902
Wygląd koszyka i sklepu

Dwie zakładki panelu: Proces zakupowy → Wygląd koszyka (logo, favicon, ikona mobile, kolory i własny CSS koszyka) oraz Wygląd sklepu → Strony sprzedażowe (kolory, pasek na górze i własny CSS sklepu). Odczyt wymaga zakresu read, zapis zakresu write_storefront. To dwa osobne arkusze: CSS koszyka działa w koszyku, CSS sklepu na stronach sprzedażowych i kartach produktów.

GET /api/v1/configuration/cart_layout

Ustawienia wyglądu koszyka. Obrazki wracają jako adresy (logo_url, favicon_url, app_icon_url) albo null.

Pola w odpowiedzi

PoleTypOpis
cart_stylestringcart, cart_new albo cart_v2.
cart_colorstringKolor przewodni koszyka (hex). Wymagany.
custom_cssstringWłasne style CSS koszyka, wklejane 1:1 jako arkusz. null usuwa.
cart_default_descriptionstringDomyślny opis produktu w koszyku (HTML).
post_purchase_button_color, post_purchase_button_text_colorstringKolory przycisku „Pobierz” po zakupie (hex). Puste = kolor koszyka i biały.
cart_inverted, cart_process_inverted, cart_hide_steps_numbers, cart_hide_remove_buttonsbooleanOdwrócenie kolumn i sekcji (tylko cart_v2), ukrycie numerów kroków i przycisków usuwania.
blik_inline_enabled, blik_inline_providerboolean, stringPłatność kodem BLIK w koszyku i bramka, która ją obsługuje.
cart_trust_block_enabled, cart_trust_seal_enabled, cart_trust_seal_title, cart_trust_seal_text, cart_trust_items[]mixedBlok zaufania. Pozycje: id, title, description, icon (check, lock, shield, dot), position, products_mode (all_products, only_selected, except_selected), product_ids.
logo_url, favicon_url, app_icon_urlstringTylko do odczytu. Adresy wgranych plików.
PATCH /api/v1/configuration/cart_layout

Zmienia wygląd koszyka. Przesyłasz tylko te pola, które zmieniasz. Pozycje bloku zaufania działają jak w innych listach: z id aktualizujesz, bez id dodajesz, z "_destroy": true usuwasz.

Logo, favicon i ikona mobile

Każdy z trzech obrazków wysyłasz jako obiekt {"filename", "content_type", "data"}, gdzie data to plik w base64. null usuwa obrazek. Zły format albo plik powyżej 5 MB to 422 i nic nie zostaje zapisane.

PoleFormatGdzie się pokazuje
logoPNG, JPEG, do 5 MBNagłówek koszyka i maile.
faviconPNG, JPEG, GIF, WebP, ICO, do 5 MB (bez SVG)Karta przeglądarki w koszyku.
app_iconPNG, JPEG, do 5 MB, kwadrat (najlepiej 512×512 px)Ikona zainstalowanej aplikacji i powiadomień o sprzedaży. Bez niej skalujemy faviconę.
curl
curl -X PATCH \
  -H "X-API-KEY: your-key" \
  -H "Content-Type: application/json" \
  -d '{"cart_color": "#ce0037",
       "custom_css": ".border-wrapper.step-four { margin-bottom: 10px; }",
       "logo": {"filename": "logo.png", "content_type": "image/png", "data": "'"$(base64 -i logo.png)"'"},
       "app_icon": {"filename": "icon.png", "content_type": "image/png", "data": "'"$(base64 -i icon.png)"'"}}' \
  https://your-shop.salescrm.pl/api/v1/configuration/cart_layout
GET /api/v1/configuration/sales_pages

Wygląd stron sprzedażowych i sklepu. Pozycje menu sklepu zostają w panelu.

Pola w odpowiedzi

PoleTypOpis
sales_page_custom_cssstringWłasne style CSS sklepu, podpinane na stronach sprzedażowych jako osobny arkusz. null usuwa.
sales_pages_style_versionstringWersja wyglądu sklepu: v1 albo v3.
sales_page_*_colorstringKolory (hex): primary, frames, buttons (+_text, _hover, _text_hover), cart_background, cart_text (+_hover), existing_cart_background, existing_cart_text, footer_background, footer_text (+_hover), menu, menu_hover, menu_text, menu_text_hover.
sales_page_top_bar_*stringPasek na górze strony: text, button_text, button_link, color, text_color, button_color, button_text_color.
v3_delivery_infostringInformacja o dostawie na froncie v3: free_all, free_digital, from_zero, hidden.
v3_delivery_badge_enabled, v3_delivery_badge_text, v3_stat_products_value, v3_stat_products_label, v3_delivery_stat_value, v3_delivery_stat_label, v3_badge1..4_title, v3_badge1..4_textmixedTeksty hero i kafelków „Dlaczego warto” na froncie v3. Pusty tytuł kafelka = kafelek ukryty.
PATCH /api/v1/configuration/sales_pages

Zmienia wygląd stron sprzedażowych. Przesyłasz tylko te pola, które zmieniasz. Kolory nie są walidowane poza tym, co robi panel — wysyłaj hex.

curl
curl -X PATCH \
  -H "X-API-KEY: your-key" \
  -H "Content-Type: application/json" \
  -d '{"sales_page_custom_css": ".product-card { border-radius: 0; }", "sales_page_top_bar_text": "Darmowa dostawa od 199 zł"}' \
  https://your-shop.salescrm.pl/api/v1/configuration/sales_pages
Referencja

Kody błędów

KodOpis
400Brak wymaganych parametrów
401Brak lub nieprawidłowy klucz API
404Zasób nie znaleziony
415Content-Type musi być application/json
422Błąd walidacji (szczegóły w polu errors)
429Przekroczono limit requestów
500Wewnę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

1 710+
Twórców
500,68M
PLN przychodów
2,99M+
Zamówień
7 lat
Na rynku