Dla programistów
REST API do integracji dowolnego sklepu z ReturnBasis — także takiego, który nie ma gotowej integracji (Shoper, WooCommerce, BaseLinker, Allegro). Przyjmujesz zgłoszenie u siebie, a od nas bierzesz przesyłki zwrotne, statusy i obsługę sprawy. Zmiany odbierasz przez API albo webhooki.
Wszystkie adresy są względem bazowego URL. Ciała żądań i odpowiedzi są w formacie JSON (pola w konwencji snake_case). Wszystkie kwoty podajemy i przyjmujemy w groszach — pieniądze nigdy nie przechodzą przez liczby zmiennoprzecinkowe.
Base URL: https://returnbasis.com/api/v1Najkrótsza integracja to jedno wywołanie w chwili, gdy kupujący zgłasza zwrot w Twoim panelu. W odpowiedzi dostajesz tracking_url — link, pod którym on wybierze przewoźnika i odbierze kod nadania:
curl https://returnbasis.com/api/v1/returns \
-H "Authorization: Bearer rtb_TWOJ_KLUCZ" \
-H "Content-Type: application/json" \
-d '{
"kind": "WITHDRAWAL",
"order_ref": "ZAM-1001",
"delivered_at": "2026-08-12T10:00:00Z",
"customer": { "name": "Anna Kowalska", "email": "anna@example.com" },
"items": [
{ "external_id": "SKU-12", "name": "Buty trekkingowe", "quantity": 1,
"unit_price": 29900, "reason": "za-duzy-rozmiar" }
]
}'Każde żądanie (poza openapi.json) wymaga klucza API w nagłówku Authorization. Klucz wygenerujesz w panelu: Ustawienia → API. Pełną wartość widać tylko raz — przechowuj ją bezpiecznie po stronie serwera i nigdy w kodzie front-endu.
Authorization: Bearer rtb_xxxxxxxxxxxxxxxxxxxxxxxxSprawdź, czy klucz działa:
curl https://returnbasis.com/api/v1/me -H "Authorization: Bearer rtb_TWOJ_KLUCZ"{
"organization": { "name": "Buty i Plecaki", "slug": "buty-i-plecaki",
"return_form_url": "/sklep/buty-i-plecaki/zwrot" },
"policy": { "return_days": 30, "refund_days": 14, "shipping_payer": "mixed" },
"plan": { "key": "PRO", "status": "active", "returns_monthly": 3000, "returns_left": 2841 },
"stats": { "returns_total": 159, "returns_open": 12, "shipment_credits": 25 }
}429 z kodem rate_limited.402; odczyt istniejących spraw działa dalej.2026-08-24, zwracana w nagłówku X-ReturnBasis-Api-Version. Zmiany łamiące kompatybilność wprowadzimy jako nową ścieżkę wersji, nie po cichu.Błędy mają stały kształt z maszynowo czytelnym kodem:
{ "error": { "code": "quota_exceeded", "message": "Wyczerpany miesięczny limit zwrotów (3000)." } }| Pole | Typ | Opis |
|---|---|---|
unauthorized / invalid_key | 401 | Brak lub nieprawidłowy klucz API. |
quota_exceeded | 402 | Wyczerpany miesięczny limit zwrotów w planie. |
not_found | 404 | Zasób nie istnieje. |
invalid_body / invalid_param | 400 | Nieprawidłowe dane wejściowe. |
rate_limited | 429 | Za dużo żądań — zwolnij. |
server_error | 500 | Błąd po naszej stronie. |
Zgłoszenie zwrotu przez API zachowuje się dokładnie tak samo jak wypełnienie publicznego formularza: kupujący dostaje maila z potwierdzeniem i linkiem, sprawa trafia do panelu, a przy kind: "WITHDRAWAL" zapisujemy datę oświadczenia o odstąpieniu — od niej biegnie Twój ustawowy termin na zwrot pieniędzy.
/returnswymaga klucza| Pole | Typ | Opis |
|---|---|---|
kind | string | WITHDRAWAL (domyślnie), EXCHANGE albo COMPLAINT. |
order_ref | string | Numer zamówienia w Twoim sklepie. |
delivered_at | date-time | Data doręczenia zamówienia — od niej liczymy termin na odstąpienie. Podawaj, jeśli ją znasz. |
customerwymagane | object | name, email, opcjonalnie phone. |
itemswymagane | array | Pozycje: name, opcjonalnie external_id, sku, quantity, unit_price (grosze), reason. |
{
"id": "cmsn…",
"number": "ZW-2026-000123",
"tracking_url": "https://returnbasis.com/zwrot/…",
"status": "accepted",
"status_label": "Przyjęty",
"shipment": null
}/returnswymaga kluczaStronicowanie kursorem, nie offsetem — lista rośnie w trakcie przeglądania, a offset gubiłby albo dublował rekordy. Parametry: status (kod statusu albo open), order_ref, since, limit (do 100), cursor.
{
"data": [ { "number": "ZW-2026-000123", "status": "in_transit", … } ],
"has_more": true,
"next_cursor": "cmsn…"
}/returns/{number}wymaga kluczaJeden zwrot po numerze widocznym dla kupującego (ZW-2026-000123) — to on figuruje w Twoim systemie i w korespondencji, więc po nim adresujemy.
{
"number": "ZW-2026-000123",
"kind": "withdrawal",
"status": "delivered",
"status_label": "Doręczony",
"withdrawal_at": "2026-08-20T09:12:00.000Z",
"items": [
{ "name": "Buty trekkingowe", "quantity": 1, "unit_price": 29900,
"reason": "za-duzy-rozmiar", "decision": "pending" }
],
"shipment": {
"carrier": "inpost_locker",
"carrier_label": "Paczkomat InPost 24/7",
"status": "delivered",
"payer": "customer",
"price": 1599,
"dispatch_code": "7KP-M42-QX9",
"tracking_number": "6800123456789"
},
"refund": { "method": "original", "amount": null, "shipping_refunded": true }
}Numer konta do zwrotu pieniędzy nie jest częścią API. Leży w bazie zaszyfrowany (AES-256-GCM) i widzi go wyłącznie zespół sklepu w panelu — nie wychodzi też do eksportu CSV.
/summarywymaga kluczaZbiorcze liczby do własnego dashboardu — bez przeciągania całej listy zgłoszeń.
{
"totals": { "returns": 159, "open": 12, "refunded": 131,
"refunded_amount": 4218900, "last_30_days": 24 },
"by_status": [ { "status": "delivered", "label": "Doręczony", "count": 4 } ],
"top_reasons": [ { "reason": "za-duzy-rozmiar", "count": 41 } ]
}Zamiast odpytywać API, zarejestruj adres URL — wyślemy na niego żądanie POST za każdym razem, gdy zajdzie subskrybowane zdarzenie. Zdarzenia: return.created, return.status, return.refunded, shipment.ready i shipment.delivered. Webhooki możesz też dodać w panelu (Ustawienia → API).
/webhookswymaga kluczaURL musi być publiczny i po HTTPS. Pole secret zwracamy tylko w tej odpowiedzi — zapisz je.
curl https://returnbasis.com/api/v1/webhooks \
-H "Authorization: Bearer rtb_TWOJ_KLUCZ" \
-H "Content-Type: application/json" \
-d '{ "url": "https://sklep.pl/hooks/returnbasis",
"events": ["return.created", "return.status"] }'{ "id": "cmsn…", "url": "https://sklep.pl/hooks/returnbasis", "events": ["return.created","return.status"], "enabled": true, "secret": "whsec_…" }Ładunek dostarczany na Twój URL:
{
"id": "evt_…", // stałe dla zdarzenia — obsługuj idempotentnie
"event": "return.status",
"created_at": "2026-08-24T12:00:00.000Z",
"api_version": "2026-08-24",
"data": { /* obiekt zwrotu jak w GET /returns/{number} */ }
}Każda dostawa ma nagłówek X-ReturnBasis-Signature: sha256=… — to HMAC-SHA256 surowego ciała żądania, kluczowany sekretem webhooka. Zweryfikuj go, zanim zaufasz danym:
import crypto from "crypto";
function verify(rawBody, signature, secret) {
const expected = "sha256=" + crypto.createHmac("sha256", secret)
.update(rawBody, "utf8").digest("hex");
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}Dostawa jest best-effort z krótkim timeoutem; odpowiedz kodem 2xx. Ostatni status i licznik błędów widać w panelu i w GET /webhooks. Ze względu na możliwe ponowienia — obsługuj zdarzenia po ich id idempotentnie.
Pełna specyfikacja maszynowa (OpenAPI 3.1) jest dostępna publicznie — zaimportuj ją do Postmana, Insomnii albo wygeneruj z niej klienta SDK:
https://returnbasis.com/api/v1/openapi.jsonZacznij integrację
Załóż konto, wygeneruj klucz w Ustawienia → API i zgłoś pierwszy zwrot. 14 dni bezpłatnie.
Załóż konto