Przejdź do treści
Premium Supply Developer

Błędy

Jeden kształt odpowiedzi, jeden katalog kodów

Każdy błąd Seller API ma stabilne pole code. Ta strona jest jego dokumentacją: adres /errors#kod prowadzi prosto do przyczyny i sposobu naprawy — możesz go wstawić do własnych logów i komunikatów dla zespołu wsparcia.

Kształt odpowiedzi#

Wszystkie zasoby /v1/* zwracają ten sam obiekt — niezależnie od statusu HTTP. Tablica errors może mieć kilka pozycji (walidacja zgłasza wszystkie pola naraz); traceId jest też w nagłówku X-Trace-Id.

400 — dwa błędy walidacji w jednej odpowiedzi
{
  "traceId": "b7f3c2e1-4d9a-4c1e-9f2a-1d3e5f7a9b0c",
  "errors": [
    {
      "code": "validation_error",
      "message": "Integer amount in grosze (>= 0) required.",
      "path": "price.amount"
    },
    {
      "code": "validation_error",
      "message": "Allowed: published, draft.",
      "path": "status"
    }
  ]
}
PoleZawszeZnaczenie
traceIdtakIdentyfikator żądania. Jedyna rzecz, jakiej potrzebujemy w zgłoszeniu.
errors[].codetakStabilny kod z tej strony. Programuj po nim, nie po message.
errors[].messagetakDla programisty, po angielsku. Treść może się zmieniać.
errors[].userMessageniePo polsku, można pokazać sprzedawcy bez tłumaczenia.
errors[].pathnieŚcieżka pola w żądaniu (price.amount, carrier), gdy błąd dotyczy pola.
400 z /oauth/token
{
  "error": "invalid_grant",
  "error_description": "Refresh token is invalid, expired or already used (tokens rotate on every refresh).",
  "traceId": "9f2a1d3e-5f7a-9b0c-b7f3-c2e14d9a4c1e"
}

Wszystkie kody#

Kody wspólne — każdy zasób /v1/*#

Zwracane przez bramkę API przed wykonaniem logiki zasobu (nagłówki, token, zakres, limit) albo przez walidację ciała żądania.

missing_user_agent

HTTP 400
Przyczyna
Brak nagłówka User-Agent albo nie pasuje do wzoru NazwaAplikacji/Wersja. Bramka sprawdza wyrażenie ^[A-Za-z0-9][A-Za-z0-9._-]{0,63}/[A-Za-z0-9][A-Za-z0-9._-]{0,31} — domyślny User-Agent bibliotek HTTP (np. python-requests/2.31) formalnie przechodzi, ale nie identyfikuje Twojej aplikacji i przy problemach nie umiemy się z Tobą skontaktować.
Co zrobić
Ustaw własny nagłówek w formacie NazwaAplikacji/Wersja (+https://adres-dokumentacji). Nazwa bez spacji (zamień na myślnik), zgodna z nazwą zarejestrowaną w panelu. Sprawdź go walidatorem na stronie Limity.

unauthorized

HTTP 401
Przyczyna
Brak nagłówka Authorization: Bearer, token nieznany, wygasły (access token żyje 12 h), odwołany (aplikacja usunięta lub zawieszona) albo to refresh token użyty jako access token. Odpowiedź niesie nagłówek WWW-Authenticate: Bearer realm="premiumsupply", error="invalid_token".
Co zrobić
Pobierz nowy token: client_credentials — kolejny POST /oauth/token; authorization_code — wymiana refresh_token. Nie ponawiaj żądania z tym samym tokenem. Jeśli message brzmi „Application no longer exists”, aplikacja została usunięta w panelu.

insufficient_scope

HTTP 403
Przyczyna
Token jest ważny, ale nie zawiera zakresu wymaganego przez zasób (message podaje który). Zakresy są zamrażane w momencie wydania tokenu — dopisanie zakresu do aplikacji w panelu nie zmienia tokenów już wydanych.
Co zrobić
Dodaj zakres do aplikacji w panelu, a potem: client_credentials — pobierz nowy token; authorization_code — poproś sprzedawcę o ponowną zgodę (nowy /oauth/authorize z pełną listą zakresów). Sprawdź bieżące zakresy przez GET /v1/me.

not_found

HTTP 404
Przyczyna
Zasób nie istnieje ALBO należy do innego sprzedawcy — celowo nie rozróżniamy tych przypadków, żeby nie zdradzać istnienia cudzych ofert i zamówień. Dla zamówień akceptujemy id oraz numer zamówienia.
Co zrobić
Sprawdź identyfikator (oferty: id z GET /v1/offers; zamówienia: id albo order_number). Jeśli zasób został usunięty po Twojej stronie synchronizacji, potraktuj 404 jako sygnał do usunięcia lokalnej kopii.
Gdzie
GET /v1/offers/{id}PATCH /v1/offers/{id}GET /v1/orders/{id}POST /v1/orders/{id}/shipments

validation_error

HTTP 400
Przyczyna
Pole żądania ma zły typ, format albo wartość poza dozwolonymi. Pole path wskazuje, które (np. price.amount, stock, status, carrier, tracking_number, limit, after, Idempotency-Key). W jednej odpowiedzi może być kilka wpisów errors[] — po jednym na pole.
Co zrobić
Popraw wskazane pola i wyślij ponownie. Typowe przyczyny: cena jako liczba dziesiętna zamiast groszy (integer), status poza published/draft, kursor after skopiowany z innego zasobu, klucz idempotencji dłuższy niż 128 znaków.

rate_limited

HTTP 429
Przyczyna
Aplikacja przekroczyła 600 żądań w bieżącym oknie 60 s (limit liczony na client_id, nie na adres IP; wliczają się także żądania zakończone błędem). Nagłówek Retry-After podaje liczbę sekund do końca okna.
Co zrobić
Odczekaj Retry-After sekund i wznów. Nie ponawiaj natychmiast — kolejne żądania w tym oknie też dostaną 429 i liczą się do limitu. Śledź X-RateLimit-Remaining i zwalniaj zanim spadnie do zera. Potrzebujesz więcej? Napisz na api@premiumsupply.pl.

internal_error

HTTP 500
Przyczyna
Nieoczekiwany błąd po naszej stronie. Treść wyjątku nie jest zwracana — jedyną informacją jest traceId (także w nagłówku X-Trace-Id).
Co zrobić
Ponów z wykładniczym odstępem (najwyżej 3 próby). Jeśli błąd się powtarza, wyślij zgłoszenie z X-Trace-Id, metodą, ścieżką i czasem UTC — patrz Kontakt.

Oferty#

Kody domenowe z PATCH /v1/offers/{id}. Status 422: żądanie poprawne składniowo, ale oferta nie ma czego zaktualizować.

no_price_row

HTTP 422
Przyczyna
PATCH z polem price trafił na ofertę, której wariant nie ma ceny w PLN (brak wiersza ceny bez listy cenowej). API zmienia istniejącą cenę, nie tworzy nowej.
Co zrobić
Uzupełnij cenę oferty w panelu sprzedawcy, potem powtórz PATCH. Jeśli w GET /v1/offers/{id} pole price jest null, PATCH ceny zakończy się tym błędem.
Gdzie
PATCH /v1/offers/{id}

no_inventory_row

HTTP 422
Przyczyna
PATCH z polem stock trafił na ofertę bez poziomu magazynowego (wariant nie ma powiązanej pozycji inventory). Analogicznie do ceny — API nie zakłada stanów, tylko je zmienia.
Co zrobić
Ustaw stan w panelu sprzedawcy raz, ręcznie; od tej chwili PATCH stock działa. W GET /v1/offers/{id} taka oferta ma stock: null.
Gdzie
PATCH /v1/offers/{id}

Zamówienia i przesyłki#

Kody z POST /v1/orders/{id}/shipments. Status 409 oznacza konflikt ze stanem zamówienia — powtórzenie tego samego żądania nic nie zmieni.

order_unpaid

HTTP 409
Przyczyna
Zgłoszenie wysyłki do zamówienia, które nie jest opłacone (status API pending). Wysyłka przed płatnością jest zablokowana po obu stronach — w panelu i w API.
Co zrobić
Wysyłaj dopiero, gdy status zamówienia to processing (payment_status: paid). Odpytuj GET /v1/orders?status=processing albo — po uruchomieniu webhooków — reaguj na order.paid.
Gdzie
POST /v1/orders/{id}/shipments

order_cancelled

HTTP 409
Przyczyna
Zamówienie zostało anulowane; nie da się do niego zgłosić wysyłki.
Co zrobić
Zsynchronizuj status po swojej stronie (GET /v1/orders/{id}) i nie wysyłaj towaru. Jeśli paczka już poszła, skontaktuj się z obsługą.
Gdzie
POST /v1/orders/{id}/shipments

already_shipped

HTTP 409
Przyczyna
Zamówienie ma już zapisaną przesyłkę (numer w message). Operacja jest jednorazowa, bo wysyła kupującemu powiadomienie „paczka w drodze”.
Co zrobić
Jeśli to Twoja ponowiona próba po utracie odpowiedzi — powtórz żądanie z TYM SAMYM Idempotency-Key: dostaniesz zapamiętane 201 (nagłówek Idempotent-Replayed: true) zamiast 409. Numer przesyłki odczytasz z pola shipment w GET /v1/orders/{id}. Zmiana numeru po fakcie — tylko przez obsługę.
Gdzie
POST /v1/orders/{id}/shipments

OAuth 2.0 — /oauth/token i /oauth/authorize#

Ten jeden obszar ma INNY kształt odpowiedzi, narzucony przez RFC 6749: { error, error_description, traceId }. Pole error odpowiada kodowi z tej listy.

invalid_client

HTTP 401
Przyczyna
Nieznany client_id, zły client_secret, brak uwierzytelnienia klienta przy client_credentials (ani Basic, ani client_id/client_secret w ciele) albo aplikacja zawieszona. Na /oauth/authorize: nieznany client_id — odpowiedź 400 w JSON, bez przekierowania (RFC 6749 zabrania odsyłać na niezweryfikowany adres).
Co zrobić
Sprawdź parę client_id/client_secret w panelu. Po rotacji sekretu stary przestaje działać natychmiast. Nagłówek Basic to base64(client_id:client_secret) — bez znaków nowej linii. Sekret zaczyna się od pss_, client_id od psa_.
Gdzie
POST /oauth/tokenGET /oauth/authorize

invalid_grant

HTTP 400
Przyczyna
authorization_code: kod nieznany, wygasły (10 min), już użyty, wystawiony dla innego redirect_uri albo code_verifier nie zgadza się z code_challenge. refresh_token: token nieznany, wygasły (90 dni) albo już użyty — każde odświeżenie odwołuje stary refresh token (rotacja).
Co zrobić
Kod: rozpocznij autoryzację od nowa (/oauth/authorize). Refresh: jeśli zgubiłeś odpowiedź z nowym refresh_token, sesji nie da się odzyskać — sprzedawca musi ponownie wyrazić zgodę. Zapisuj nową parę tokenów atomowo, zanim użyjesz nowego access tokenu.
Gdzie
POST /oauth/token

invalid_scope

HTTP 400także jako ?error= na redirect_uri
Przyczyna
Żądany zakres nie istnieje albo nie został przyznany aplikacji w panelu (error_description wymienia które). Na /oauth/authorize dodatkowo: pusty parametr scope.
Co zrobić
Proś wyłącznie o podzbiór zakresów aplikacji; pełna lista na stronie Uwierzytelnianie. Pominięcie parametru scope przy client_credentials daje token ze wszystkimi zakresami aplikacji.
Gdzie
POST /oauth/tokenGET /oauth/authorize

unsupported_grant_type

HTTP 400
Przyczyna
grant_type inny niż client_credentials, authorization_code albo refresh_token (brak parametru też).
Co zrobić
Wysyłaj ciało jako application/x-www-form-urlencoded z poprawnym grant_type. Nie obsługujemy password, device_code ani implicit.
Gdzie
POST /oauth/token

invalid_request

HTTP 400także jako ?error= na redirect_uri
Przyczyna
/oauth/token: brak code, redirect_uri lub code_verifier (authorization_code); code_verifier poza 43–128 znakami [A-Za-z0-9-._~]; brak refresh_token. /oauth/authorize: redirect_uri niezarejestrowany (400 JSON, bez przekierowania), state krótszy niż 8 znaków, brak lub zły PKCE (code_challenge musi mieć 43 znaki base64url, metoda S256).
Co zrobić
Porównaj żądanie z przykładami na stronie Uwierzytelnianie. redirect_uri musi być identyczny znak w znak z zarejestrowanym (łącznie ze slashem na końcu i wielkością liter hosta).
Gdzie
POST /oauth/tokenGET /oauth/authorize

unsupported_response_type

302 → redirect_uri
Przyczyna
response_type inny niż code. Błąd wraca na redirect_uri z parametrami error, error_description i state.
Co zrobić
Używaj wyłącznie response_type=code — flow implicit nie jest i nie będzie wspierany.
Gdzie
GET /oauth/authorize

access_denied

302 → redirect_uri
Przyczyna
Sprzedawca odrzucił zgodę na ekranie premiumsupply.pl albo aplikacja ma status pending (cel „dla innych sprzedawców” czeka na akceptację) i nie może jeszcze prosić o dostęp do obcych kont. Wraca na redirect_uri jako ?error=access_denied&state=…
Co zrobić
Pokaż użytkownikowi czytelny komunikat i pozwól spróbować później. Status aplikacji sprawdzisz w panelu; na własne konto (client_credentials) aplikacja pending działa od razu.
Gdzie
GET /oauth/authorize

server_error

HTTP 500
Przyczyna
Nieoczekiwany błąd serwera tokenów. Odpowiedź zawiera traceId.
Co zrobić
Ponów po chwili; jeśli problem trwa, zgłoś z traceId na api@premiumsupply.pl.
Gdzie
POST /oauth/token

Statusy HTTP#

Kiedy dokładnie który status. Klient generowany z kontraktu widzi je przy każdej operacji — w tym 429, które dotyczy wszystkich.

StatusKiedy
200 OKUdane GET oraz PATCH (zwraca zaktualizowany zasób).
201 CreatedUdane POST tworzące zasób: przesyłka, subskrypcja webhooka.
204 No ContentUdane DELETE (subskrypcja webhooka).
302 FoundWyłącznie /oauth/authorize — przekierowanie na ekran zgody albo powrót na redirect_uri (z code albo error).
400 Bad Requestmissing_user_agent, validation_error, błędy OAuth invalid_request / invalid_grant / invalid_scope / unsupported_grant_type.
401 Unauthorizedunauthorized (zasoby /v1), invalid_client (OAuth).
403 Forbiddeninsufficient_scope — token ważny, brak zakresu.
404 Not Foundnot_found — zasób nie istnieje albo należy do innego sprzedawcy.
409 Conflictalready_shipped, order_unpaid, order_cancelled — stan zasobu wyklucza operację.
422 Unprocessable Contentno_price_row, no_inventory_row — dane poprawne, oferta nie ma czego zaktualizować.
429 Too Many Requestsrate_limited — patrz Retry-After.
500 Internal Server Errorinternal_error / server_error — zgłoś z X-Trace-Id.

Brakuje kodu, który dostałeś? Napisz na Kontakt z X-Trace-Id — nieudokumentowany kod traktujemy jako błąd dokumentacji.