Przejdź do treści
Adres bazowyhttps://api.daco-germany.de/v1
Pobierz OpenAPI

API partnerówwersja 1.3.0 · ceny netto, stany, zamówienia i faktury

8 punktów końcowychceny, stany, zamówienia, faktury
60 / minlimit żądań na klucz
500 kodóww jednym żądaniu o ceny
do 5 minutnajstarsze dane w odpowiedzi

Start

pierwsze żądanie w 3 krokach

API podaje ceny netto Twojego konta i stany magazynu DACO. Ceny są takie same jak po zalogowaniu do platformy B2B. Jedno żądanie obsługuje do 500 kodów towarów. Przez API złożysz też zamówienie — trafia do DACO jak zamówienie z platformy — i pobierzesz swoje faktury i korekty.

Adres bazowy
https://api.daco-germany.de/v1
Wersja
1.3.0 — w adresie jako /v1
Stan usługi
sprawdzam
Format
JSON, UTF-8, połączenie HTTPS
Klucz
wydaje opiekun handlowy DACO — jak uzyskać klucz
GET /status działa bez klucza.

Pierwsze żądanie

  1. Poproś o klucz testowy. Zaczyna się od dk_test_ i zwraca prawdziwe ceny i stany Twojego konta.
  2. Sprawdź klucz. GET /me pokaże konto, walutę i tryb klucza.
    bash
    curl https://api.daco-germany.de/v1/me \
      -H "Authorization: Bearer dk_test_XXXXXXXX"
    Windows
    curl.exe https://api.daco-germany.de/v1/me -H "Authorization: Bearer dk_test_XXXXXXXX"
  3. Pobierz ceny i stany. POST /prices przyjmuje listę kodów towarów.
    bash
    curl -X POST https://api.daco-germany.de/v1/prices \
      -H "Authorization: Bearer dk_test_XXXXXXXX" \
      -H "Content-Type: application/json" \
      -d '{"items":["329986","BA0210","XX1"]}'
    Polecenie dla bash (Linux, macOS, Git Bash, WSL).
    Windows
    Zapisz ciało w pliku body.json, w kodowaniu UTF-8:
    {"items":["329986","BA0210","XX1"]}
    Wyślij plik. Użyj curl.exe — w PowerShell samo curl to inne polecenie.
    curl.exe -X POST https://api.daco-germany.de/v1/prices -H "Authorization: Bearer dk_test_XXXXXXXX" -H "Content-Type: application/json" -d "@body.json"

Klucze API

nagłówek Authorization · tryb testowy

Żądania do /me, /prices, /orders i /invoices wymagają klucza w nagłówku Authorization. GET /status działa bez klucza.

  • Klucz ma 40 znaków: dk_test_ albo dk_live_ i 32 litery lub cyfry.
  • Jeden klucz to jedno konto klienta. Ceny, waluta i profil są takie jak po zalogowaniu do B2B.
  • Konto może mieć kilka kluczy. Limit żądań liczymy osobno dla każdego klucza.
  • Innego sposobu uwierzytelnienia nie ma. Basic, klucz bez słowa Bearer i klucz w adresie dają 401.

Klucz testowy i produkcyjny

tryb testowy
CechaTestowyProdukcyjny
Początek kluczadk_test_dk_live_
Ceny i stanyprawdziwe, z Twojego kontate same
Zamówienia POST /orderstylko sprawdzane: 200, status: validated, bez numeruskładane w DACO: 201, numer API-…
Nagłówek odpowiedzix-daco-sandbox: 1brak
Pole account.sandbox w /metruefalse
Limit60 żądań na minutę60 żądań na minutę
Konsola na tej stronietaknie
  • Klucz testowy służy do sprawdzenia połączenia i formatu na prawdziwych danych Twojego konta.
  • Nagłówek x-daco-sandbox: 1 jest przy kodach 200, 400 i 503. Nie ma go przy 401 i 429.
  • Klucz testowy sprawdza zamówienie tak samo jak produkcyjny — ceny, stan, blokadę konta i limit — ale go nie składa. Do DACO nic nie trafia.
  • Nie ma danych testowych, fikcyjnych towarów ani wymuszania błędów.
  • Adres jest ten sam. Limit też: 60 żądań na minutę, liczony osobno dla każdego klucza.
  • Wywołania trafiają do dziennika DACO jak każde inne.

Jak uzyskać klucz

  • Klucze wydaje DACO. W platformie B2B klucza nie da się utworzyć samodzielnie.
  • Napisz do opiekuna handlowego (kontakt). Podaj kod klienta i krótki opis integracji.
  • Pełny klucz widać tylko raz, przy utworzeniu. Zapisz go od razu.
  • Zgubionego klucza nie odzyskamy. DACO przechowuje tylko jego skrót i pierwsze 12 znaków. Wydamy nowy.
  • Klucz unieważnia DACO. Działa to od następnego żądania: odpowiedź 401.

Bezpieczeństwo klucza

  • Trzymaj klucz na serwerze. API jest do połączeń serwer–serwer i nie wysyła nagłówków CORS. Strona z innej domeny go nie wywoła.
  • Nie wklejaj klucza do maili ani zgłoszeń. Wystarczy pierwsze 12 znaków.
  • Po serii nieudanych prób z jednego adresu IP ten adres dostaje 429 do końca minuty. Także z dobrym kluczem.

Wypróbuj

prawdziwe żądanie do API

Wyślij żądanie z tej strony i zobacz odpowiedź. Żądanie jest prawdziwe. Do /me, /prices i /invoices potrzebny jest klucz testowy. Takie żądanie liczy się do limitu 60 na minutę i trafia do dziennika DACO.

Punkt końcowy
Ten punkt końcowy nie wymaga klucza.
Bez klucza. Nie liczy się do limitu.

Odpowiedź

Odpowiedź pojawi się tutaj.

To samo jako curl

bash
curl https://api.daco-germany.de/v1/status
Windows
curl.exe https://api.daco-germany.de/v1/status

Punkty końcowe

odczyt i zamówienia
MetodaŚcieżkaKluczOpisKody odpowiedzi
GET/statusbez kluczaStan usługi i wiek danych200, 503
GET/mekluczSprawdzenie klucza: konto, waluta, tryb200, 401, 403, 429, 500
POST/priceskluczCeny netto i stany dla listy kodów200, 400, 401, 403, 429, 500, 503
POST/orderskluczZłożenie zamówienia200, 201, 400, 401, 403, 409, 429, 500, 503
GET/orderskluczLista zamówień konta200, 400, 401, 403, 429, 500
GET/orders/{orderNo}kluczStatus i pozycje zamówienia200, 401, 403, 404, 429, 500
GET/invoiceskluczFaktury i korekty: lista z filtrami200, 400, 401, 403, 429, 500, 503
GET/invoices/{id}kluczJeden dokument z pozycjami200, 401, 403, 404, 429, 500, 503
  • Ścieżkę dopisz do adresu bazowego. Wielkość liter ma znaczenie: /STATUS daje 404.
  • Nie dodawaj ukośnika na końcu: /me/ daje 308. Część klientów HTTP nie powtarza po nim POST.
  • Kolejność sprawdzeń: blokada adresu IP (429), klucz (401), limit klucza (429), konto (403), na końcu samo żądanie. Zwracany jest pierwszy błąd.
  • Wszystkie punkty końcowe poza POST /orders tylko czytają dane. Takie żądanie można bezpiecznie powtórzyć. Liczy się do limitu.
  • POST /orders składa zamówienie. Ponawiaj je tylko z tym samym Idempotency-Key — wtedy nie powstanie drugie zamówienie.
Pełne adresy
GET  https://api.daco-germany.de/v1/status
GET  https://api.daco-germany.de/v1/me
POST https://api.daco-germany.de/v1/prices
POST https://api.daco-germany.de/v1/orders
GET  https://api.daco-germany.de/v1/orders
GET  https://api.daco-germany.de/v1/orders/{orderNo}
GET  https://api.daco-germany.de/v1/invoices
GET  https://api.daco-germany.de/v1/invoices/{id}
Nagłówki odpowiedzi z kluczem
content-type: application/json
cache-control: no-store
x-daco-api-version: 1.3.0
x-daco-sandbox: 1
x-daco-sandbox przychodzi tylko dla klucza testowego.

GET/status

bez klucza

Stan usługi i wiek danych. Mówi, czy POST /prices poda teraz ceny i stany. Nie wymaga klucza i nie liczy się do limitu.

Ciało żądania: brak.

Kody odpowiedzi200503

200 — stan ok. 503 — stan degraded. Uwaga: 503 zwraca tu ten sam obiekt stanu, nie obiekt błędu.

Pola odpowiedzi

200 i 503
PoleTypOpis
statusstringok — /prices poda ceny i stany. degraded — dane starsze niż 5 minut albo wiek nieznany.
apiVersionstringWersja API, dziś 1.3.0.
dataAgeSecinteger | nullWiek najstarszego zestawu danych, w sekundach. null — wiek nieznany.

GET/me

klucz wymagany

Sprawdza klucz. Zwraca konto, walutę, tryb klucza i wiek danych.

Ciało żądania: brak. Wystarczy nagłówek Authorization.

Kody odpowiedzi200401403429500

/me odpowiada 200 także przy nieaktualnych danych. Ich wiek sprawdzaj w dataAgeSec albo w /status.

Pola odpowiedzi

200
PoleTypOpis
apiVersionstringWersja API.
account.customerCodestringKod klienta w DACO.
account.namestringNazwa firmy z karty klienta.
account.currencystringWaluta konta: PLN albo EUR.
account.sandboxbooleantrue dla klucza testowego.
account.profilestringTyp klienta ustawiony przez DACO: hurt — hurtownia, sklep — sklep detaliczny. To stałe identyfikatory.
key.prefixstringPierwsze 12 znaków klucza.
key.labelstring | nullOpis klucza nadany przez DACO.
key.createdAtstringData utworzenia klucza: ISO 8601, czas UTC, na przykład 2026-10-08T17:47:05Z.
dataAgeSecinteger | nullWiek danych, jak w /status.

POST/prices

klucz wymagany

Cena netto Twojego konta i stan magazynu dla listy kodów towarów. Kod, którego nie da się wycenić, nie psuje żądania. Odpowiedź to nadal 200, a pozycja ma pole error.

Kody odpowiedzi200400401403429500503

503 dostaje także błędne żądanie. Świeżość danych sprawdzamy przed treścią żądania.

Ciało żądania

JSON
PoleTypOpis
itemsarray of string · wymaganeKody towarów DACO (indeks, „DACO ID” z katalogu). Od 1 do 500 różnych kodów.
  • Kod ma od 1 do 40 znaków. Odstępy na brzegach pomijamy. Wielkość liter nie ma znaczenia: ba0210 to BA0210.
  • Powtórzone kody scalamy. Zostaje pierwszy. Limit 500 liczymy po scaleniu. Odpowiedź ma wtedy mniej pozycji niż żądanie.
  • Szukamy dokładnie po kodzie. Nie po EAN, numerze OE ani nazwie.
  • Ciało: JSON w UTF-8, do 256 KB. Zalecany nagłówek Content-Type: application/json. Inne pola ciała pomijamy.

Pola odpowiedzi

200
PoleTypOpis
currencystringWaluta wszystkich cen w odpowiedzi: PLN albo EUR. To waluta konta.
dataAgeSecintegerWiek najstarszego zestawu danych użytego do odpowiedzi (ceny, upusty, stany), w sekundach. Nigdy ponad 300.
itemsarrayJedna pozycja na każdy kod, w kolejności żądania.
items[].codestringKod tak, jak go przysłano, bez odstępów na brzegach.
items[].namestringNazwa towaru, zawsze po polsku. Brak pola przy NOT_FOUND.
items[].netPricenumberCena netto za sztukę, zaokrąglona do 2 miejsc. Brak pola, gdy jest error.
items[].stockintegerIlość dostępna w magazynie DACO. 0 — brak. Brak pola przy NOT_FOUND.
items[].cartonobject · opcjonalneTylko gdy konto ma na ten towar cenę kartonową. qty — sztuk w pełnym kartonie. netPrice — cena netto za sztukę przy zakupie pełnych kartonów.
items[].errorstring · opcjonalneNOT_FOUND — nieznany kod albo towar marki niedostępnej na Twoim koncie; pozycja ma tylko code i error. NO_PRICE — towar istnieje, ale konto nie ma na niego ceny netto; name i stock są. Brak pola — pozycja wyceniona.

Warto wiedzieć

  • Ceny są netto, za sztukę. API nie podaje stawki VAT ani ceny brutto.
  • Cena to liczba JSON: 20.10 przychodzi jako 20.1, a 335.00 jako 335.
  • Stan liczymy tylko z magazynu głównego. Inne magazyny się nie liczą.
  • Odpowiedź dopasuj do żądania po code, bez odstępów na brzegach i bez rozróżniania wielkości liter. Nie po kolejności: po scaleniu powtórzeń pozycje się przesuwają.
  • API nie podaje listy kodów. Kody weź z katalogu albo cennika DACO.
  • API nie zwraca: EAN, numerów OE, nazwy angielskiej, minimalnej ilości, terminu dostawy.
  • Nie ma stronicowania. Jedno żądanie to najwyżej 500 kodów.

POST/orders

klucz wymagany

POST /orders składa zamówienie na Twoje konto. Ceny i stan liczymy tak samo jak w /prices — ceny z żądania nie przyjmujemy. Zamówienie idzie do DACO tą samą drogą co zamówienie z platformy B2B, a status sprawdzisz w GET /orders/{orderNo}.

Kody odpowiedzi200201400401403409429500503

201 — zamówienie przyjęte. 200 — klucz testowy: zamówienie tylko sprawdzone. Pozycje odrzucone z powodu stanu, ceny albo kodu nie psują zamówienia przy partial: true.

Ciało żądania

JSON
PoleTypOpis
itemsarray · wymaganePozycje: od 1 do 500 różnych kodów. Powtórzony kod to błąd DUPLICATE_ITEM.
items[].codestring · wymaganeKod towaru DACO, jak w /prices. Do 40 znaków, bez rozróżniania wielkości liter.
items[].qtyinteger · wymaganeIlość w sztukach: liczba całkowita od 1 do 100 000.
partialboolean · opcjonalnetrue (domyślnie) — przyjmujemy to, co się da, resztę odrzucamy z powodem. false — wszystko albo nic: każda odrzucona pozycja daje 409.
referencestring · opcjonalneTwój numer zamówienia, do 50 znaków. Wraca w odpowiedziach i trafia do zamówienia w DACO.
notestring · opcjonalneUwaga do zamówienia, do 500 znaków.

Klucz idempotencji (Idempotency-Key)

  • Nagłówek Idempotency-Key jest obowiązkowy: od 8 do 100 znaków, najlepiej UUID. Nowe zamówienie — nowy klucz.
  • Ten sam klucz i ta sama treść zwracają to samo zamówienie: 201 i nagłówek idempotent-replayed: true. Drugie zamówienie nie powstaje.
  • Ten sam klucz z inną treścią: 409 CONFLICT, details.reason: IDEMPOTENCY_KEY_REUSED.
  • Klucz obowiązuje dla konta, także po wymianie klucza API. Odmowy (400, 403, 409, 503) nie są zapamiętywane — po usunięciu przyczyny ten sam klucz złoży zamówienie.

Pola odpowiedzi

201 · 200
PoleTypOpis
orderNostring | nullNumer zamówienia w DACO, na przykład API-261028-8F2K. null dla klucza testowego.
statusstringqueued po przyjęciu. Klucz testowy: validated. Dalsze stany — w tabeli statusów niżej.
sandboxbooleantrue dla klucza testowego — zamówienie nie zostało złożone.
referencestring | nullTwój numer zamówienia z żądania.
currencystringWaluta cen: PLN albo EUR.
totalNetnumberWartość netto przyjętych pozycji.
createdAtstring | nullChwila przyjęcia: ISO 8601, czas UTC. null dla klucza testowego.
acceptedarrayPrzyjęte pozycje: code, qty, netPrice. Pełne kartony mogą być osobną pozycją z ceną kartonową i polem carton: true.
rejectedarrayOdrzucone ilości: code, qty, reason, a przy STOCK i NO_PRICE także available — ile jest w magazynie.

Powody odrzucenia pozycji

rejected[].reason
PowódKiedy
NOT_FOUNDNieznany kod albo towar marki niedostępnej na Twoim koncie — jak w /prices.
NO_PRICEKonto nie ma ceny netto na ten towar. Ceny katalogowej nie podstawiamy.
STOCKBrak w magazynie albo za mało. Przy partial: true przyjmujemy available sztuk, resztę odrzucamy.

Kolejność sprawdzeń

  1. Ciało i Idempotency-Key (400). Powtórzenie wcześniejszego zamówienia zwraca je od razu.
  2. Świeżość danych (503), potem ceny i stan każdej pozycji.
  3. Blokada konta i limit kupiecki: limit minus saldo, minus otwarte zamówienia, minus wartość brutto tego zamówienia (403 CREDIT_BLOCKED). Faktury za pobraniem nie blokują.
  4. Przyjęcie: stan sprawdzamy jeszcze raz w chwili zapisu. Sztuki przyjętych pozycji są od razu zarezerwowane — /prices pokazuje już mniejszy stan.

Powody błędu VALIDATION przy zamówieniach

details.reason
PowódKiedy
IDEMPOTENCY_KEY_REQUIREDBrak nagłówka Idempotency-Key w POST /orders.
INVALID_IDEMPOTENCY_KEYKlucz ma mniej niż 8 albo ponad 100 znaków albo znaki spoza liter, cyfr i . _ : -.
INVALID_ITEMPozycja details.index: zły kod albo qty nie jest liczbą całkowitą od 1 do 100 000.
DUPLICATE_ITEMPozycja details.index powtarza kod z wcześniejszej pozycji.
INVALID_FIELDZłe pole details.field: partial, reference albo note.
INVALID_PARAMGET /orders: zły parametr details.param — from albo limit.

Do tego INVALID_JSON, BODY_TOO_LARGE, ITEMS_REQUIRED i TOO_MANY_ITEMS jak w /prices — limit pozycji to 500.

GET/orders

klucz wymagany

Zamówienia Twojego konta złożone przez API i na platformie B2B, najnowsze pierwsze. Parametry: from (data YYYY-MM-DD, domyślnie ostatnie 30 dni, najdalej 180 dni) i limit (domyślnie 50, najwyżej 200).

Kody odpowiedzi200400401403429500

GET/orders/{orderNo}

klucz wymagany

Status i pozycje jednego zamówienia: items — wysłane do DACO, erp — zamówienie w DACO, gdy już powstało. Zamówienie innego konta daje 404, tak samo jak numer, którego nie ma.

Kody odpowiedzi200401403404429500

Statusy zamówienia

status
StanZnaczenie
queuedPrzyjęte, czeka na przekazanie do systemu DACO.
sent_to_erpPrzekazane do systemu DACO. Zamówienie w DACO powstaje zwykle w ciągu kilku minut.
acceptedZamówienie jest w DACO. erp pokazuje numer, stan realizacji i pozycje — ilości mogą być mniejsze niż wysłane.
rejectedSystem DACO nie przyjął zamówienia. Napisz do DACO.
cancelledZamówienie anulowane w DACO.

Warto wiedzieć

  • Status zmienia się asynchronicznie. Sprawdzaj go po kilku minutach, nie częściej niż raz na minutę na zamówienie.
  • Zamówienie w DACO może mieć mniejsze ilości niż wysłane — porównaj items z erp.items.
  • Wartości są netto. Koszty zakupu DACO nie są nigdy podawane.

GET/invoices

klucz wymagany

Faktury i korekty Twojego konta: nagłówki, kwoty, kwota do rozliczenia, numer KSeF i zamówienia. Te same dokumenty co w Finansach platformy B2B. Bez plików: oryginał jest w KSeF.

Ciało żądania: brak. Filtry w parametrach adresu.

Kody odpowiedzi200400401403429500503

503 dostaje także błędne żądanie. Świeżość danych faktur sprawdzamy przed parametrami.

Parametry adresu

wszystkie opcjonalne
PoleTypOpis
fromstring (date) · opcjonalnePierwszy dzień wystawienia, YYYY-MM-DD, włącznie.
tostring (date) · opcjonalneOstatni dzień wystawienia, YYYY-MM-DD, włącznie. Domyślnie dziś.
openboolean · opcjonalnetrue — tylko dokumenty z kwotą do rozliczenia (outstanding różne od 0). false — tylko rozliczone.
typestring · opcjonalneRodzaje dokumentów po przecinku, np. FS,FSK. Najwyżej 10.
correctionboolean · opcjonalnetrue — tylko korekty. false — tylko faktury, bez korekt.
numberstring · opcjonalneDokładny numer dokumentu, np. D0C/26/10112/FS. Wielkość liter nie ma znaczenia.
limitinteger · opcjonalneDokumentów na stronę: od 1 do 500. Domyślnie 100.
offsetinteger · opcjonalneIle dokumentów pominąć. Następną stronę wskazuje nextOffset.
  • Bez from i to: ostatnie 90 dni. Z open=true albo number: cała historia dostępna w API.
  • Sam from: do dziś. Samo to: 90 dni, które kończą się na to. Zakres to najwyżej 366 dni.
  • Historia faktur w API: ostatnie 2 lata, a dokumenty z kwotą do rozliczenia także starsze.
  • Inne parametry pomijamy.
Przykłady parametrów
?from=2026-10-01&to=2026-10-31
?open=true
?type=FSK&from=2026-01-01
?number=D0C/26/10112/FS
?limit=500&offset=500

Pola odpowiedzi

200
PoleTypOpis
dataAgeSecintegerWiek najstarszego zestawu danych faktur, w sekundach. Nigdy ponad 3000.
fromstring | nullZastosowany pierwszy dzień. null — bez ograniczenia.
tostring | nullZastosowany ostatni dzień. null — bez ograniczenia.
totalintegerLiczba wszystkich dokumentów spełniających warunki.
limitintegerRozmiar strony.
offsetintegerPominięte dokumenty.
nextOffsetinteger | nulloffset następnej strony. null — to ostatnia strona.
itemsarrayDokumenty od najstarszego, wg daty wystawienia.
items[].idstringIdentyfikator dokumentu. Służy do pobrania szczegółów.
items[].numberstringNumer dokumentu, np. D0C/26/10112/FS.
items[].typestringRodzaj: FS — faktura, FSK — korekta, FE / FEK — faktura eksportowa i jej korekta. Inne rodzaje są możliwe.
items[].issueDatestring (date)Data wystawienia.
items[].dueDatestring (date) | nullTermin płatności.
items[].currencystringWaluta dokumentu: PLN albo EUR.
items[].exchangeRatenumber | nullKurs waluty z dokumentu. null — dokument bez kursu.
items[].netnumberWartość netto w walucie dokumentu. Ujemna w korekcie zmniejszającej.
items[].vatnumberKwota VAT.
items[].grossnumberWartość brutto.
items[].outstandingnumberKwota do rozliczenia. 0 — rozliczony. Ujemna — nierozliczone uznanie z korekty.
items[].paymentMethodstring | nulltransfer, cash, card, cash_on_delivery albo other.
items[].ksefNumberstring | nullNumer dokumentu w KSeF. null — dokument bez numeru KSeF.
items[].customerobjectNabywca: code — kod klienta, name — nazwa. Centrala widzi tu także swoje oddziały.
items[].isCorrectionbooleantrue — dokument jest korektą.
items[].correctionReasonstring | nullTylko w korekcie: przyczyna korekty z dokumentu, np. Zwrot towaru. Ten sam tekst jest w KSeF. Bywa po polsku albo po angielsku.
items[].correctedInvoiceobject | nullTylko w korekcie: dokument korygowany wprost (id, number).
items[].originalInvoiceobject | nullTylko w korekcie: pierwszy dokument łańcucha korekt (id, number).
items[].ordersarrayZamówienia z tego dokumentu: orderNo — numer zamówienia w platformie, reference — Twój numer zamówienia, erpNumber — numer zamówienia w ERP. Korekta ma pustą listę.

Powody błędu VALIDATION

details.reason
PowódKiedyDodatkowe pole
INVALID_PARAMParametr ma złą postać, np. data spoza kalendarza albo limit poza zakresem.param — nazwa parametru
RANGE_INVALIDfrom jest po to.brak
RANGE_TOO_LONGZakres dłuższy niż 366 dni.maxDays: 366
FROM_TOO_OLDfrom jest wcześniejsze niż historia faktur w API.minFrom — najwcześniejsza dozwolona data

Warto wiedzieć

  • Korekty są osobnymi dokumentami na liście. Filtr correction=true pokazuje same korekty, a correctedInvoice wskazuje korygowany dokument.
  • Centrala widzi dokumenty swoje i swoich oddziałów. Oddział widzi tylko własne.
  • Kwoty są w walucie dokumentu, zaokrąglone do 2 miejsc. Kwota to liczba JSON: 20.10 przychodzi jako 20.1.
  • Kolejność jest stała: od najstarszego. Nowe dokumenty dochodzą na końcu, więc strony liczone od początku się nie przesuwają.
  • Nowy dokument pojawia się w API kilka minut po wystawieniu w ERP.
  • API nie zwraca PDF ani XML. Dokument pobierzesz z KSeF po ksefNumber.

GET/invoices/{id}

klucz wymagany

Jeden dokument z pozycjami. id weź z listy GET /invoices. Numer dokumentu ma ukośniki — szukaj go na liście parametrem number.

Ciało żądania: brak.

Kody odpowiedzi200401403404429500503

404 — nie ma takiego dokumentu albo należy do innego konta. Odpowiedź jest w obu przypadkach taka sama.

Pola odpowiedzi

200

Pola dokumentu jak w GET /invoices, plus dataAgeSec i items:

PoleTypOpis
items[].lineintegerNumer pozycji, od 1.
items[].codestring | nullKod towaru DACO.
items[].namestring | nullNazwa towaru, po polsku.
items[].qtynumberIlość. W korekcie: zmiana ilości, zwykle ujemna.
items[].unitstring | nullJednostka z dokumentu, np. SZT, KPL.
items[].netPricenumberCena netto za jednostkę.
items[].netValuenumberWartość netto pozycji z dokumentu. W korekcie: różnica wartości.
items[].vatRatenumber | nullStawka VAT w procentach, np. 23.
items[].correctionobject | nullTylko w korekcie: before i after — ilość, cena i wartość przed i po korekcie. difference — zmiana ilości, ceny i wartości. null w fakturze.

Warto wiedzieć

  • Pozycja korekty: qty i netValue to zmiana, netPrice to cena po korekcie. Pełny obraz jest w correction.
  • Korekta ceny ma qty równe 0 i różnicę wartości w netValue.
  • Wartości przed i po to ilość × cena, zaokrąglone do 2 miejsc. Różnica wartości pochodzi z dokumentu.
  • correction bywa null w korekcie z czasu przed udostępnieniem tych danych w API. Wtedy są tylko pola zmiany.
  • Dokument sprzed 2 lat może nie mieć pozycji. Wtedy items jest puste.
  • API nie podaje kosztu, marży ani danych magazynowych dokumentu.

Błędy

jeden format · 9 kodów

Błąd ma zawsze ten sam kształt: obiekt error z polami code, message i czasem details. Rozpoznawaj go po error.code — kody są stałe.

error.message jest dla człowieka. Po polsku, gdy nagłówek Accept-Language zaczyna się od pl. W innym razie po angielsku. Kody i nazwy pól są takie same w obu językach.

Kody błędów

error.code
KodHTTPKiedyCo zrobić
VALIDATION400Złe żądanie. Powód jest w details.reason.Popraw żądanie. Nie ponawiaj bez zmian.
UNAUTHORIZED401Brak klucza, zły albo unieważniony klucz.Sprawdź klucz i nagłówek. Nie ponawiaj.
FORBIDDEN403Klucz jest dobry, ale konto klienta jest niedostępne.Napisz do DACO.
CREDIT_BLOCKED403POST /orders: wysyłka zamówień wstrzymana — konto zablokowane, faktury po terminie (details.reason: BLOCKED) albo zamówienie nie mieści się w limicie kupieckim (CREDIT_LIMIT).Ureguluj płatności albo zmniejsz zamówienie. Pytania — do opiekuna DACO.
NOT_FOUND404GET /orders/{orderNo}: na Twoim koncie nie ma takiego zamówienia. GET /invoices/{id}: nie ma takiego dokumentu albo należy do innego konta.Sprawdź numer zamówienia albo id dokumentu na liście GET /invoices. Nie ponawiaj bez zmian.
CONFLICT409POST /orders: ten sam Idempotency-Key z inną treścią (IDEMPOTENCY_KEY_REUSED), odrzucone pozycje przy partial: false (ITEMS_REJECTED) albo nic do przyjęcia (NO_ACCEPTED_ITEMS).Popraw zamówienie. Nowa treść — nowy Idempotency-Key.
RATE_LIMIT429Ponad 60 żądań na minutę na klucz: details.limitPerMinute. Albo adres IP zablokowany po serii złych kluczy: bez details.Odczekaj tyle sekund, ile podaje nagłówek Retry-After.
INTERNAL500Nieprzewidziany błąd serwera.Ponów później. Jeśli wraca, napisz do DACO.
UNAVAILABLE503/prices i POST /orders: dane starsze niż 5 minut. /invoices: dane faktur starsze niż 50 minut. Albo wiek nieznany. details.dataAgeSec, gdy wiek jest znany. Przy zamówieniu także wtedy, gdy nie da się sprawdzić blokady konta.Ponów za kilka minut. Sprawdzaj GET /status. Nagłówka Retry-After nie ma.

503 jest stałe, gdy konto ma walutę inną niż PLN i EUR. Wtedy napisz do DACO.

Powody błędu VALIDATION

details.reason
PowódKiedyDodatkowe pole
INVALID_JSONCiało jest puste albo nie jest poprawnym JSON-em.brak
BODY_TOO_LARGECiało jest większe niż 256 KB.maxBytes: 262144
ITEMS_REQUIREDBrak items, items nie jest tablicą albo jest pusta.brak
TOO_MANY_ITEMSPonad 500 różnych kodów.max: 500
INVALID_ITEMElement nie jest napisem, jest pusty albo ma ponad 40 znaków. Zgłaszany jest pierwszy napotkany.index — pozycja w tablicy, liczona od 0

Błędy pozycji i wyjątki

  • NOT_FOUND i NO_PRICE w polu items[].error to nie błędy żądania. Odpowiedź ma kod 200.
  • Pozycje odrzucone w POST /orders (rejected[].reason) też nie są błędem żądania. Odpowiedź ma kod 201.
  • GET /status z kodem 503 zwraca obiekt stanu, nie obiekt błędu.
  • Zła metoda, np. GET /prices: kod 405 i puste ciało.
  • Nieznana ścieżka: kod 404 i strona HTML zamiast JSON.

Limity

liczone na klucz
LimitWartośćPo przekroczeniu
Żądania60 na minutę na klucz429 RATE_LIMIT i nagłówek Retry-After
Kody w jednym żądaniu /prices500 różnych400 TOO_MANY_ITEMS
Długość kodu40 znaków400 INVALID_ITEM
Ciało żądania256 KB (262 144 bajty)400 BODY_TOO_LARGE
  • Minuta zaczyna się od pierwszego żądania. Całe 60 żądań można zużyć naraz.
  • Liczy się każde żądanie z rozpoznanym kluczem do /me, /prices, /orders i /invoices, także zakończone kodem 400, 403, 404, 409 lub 503.
  • Nie liczą się: GET /status i żądania zakończone kodem 401.
  • Retry-After podaje liczbę sekund do końca minuty, od 1 do 60. Nagłówków z licznikiem pozostałych żądań nie ma.
  • Pełny katalog, ok. 8 tys. kodów, to 16–17 żądań po 500 kodów. Mieści się w jednej minucie.
  • Po serii nieudanych prób klucza z jednego adresu IP ten adres dostaje 429 do końca minuty, z nagłówkiem Retry-After: 60.

Świeżość danych

próg 5 minut

API odpowiada z kopii danych ERP na serwerze B2B. Nie pyta ERP przy każdym żądaniu. Gdy dane są starsze niż 5 minut, API odpowiada 503 zamiast podawać nieaktualne liczby.

Jak często odświeżamy

DaneOdświeżanie
Stanyco ok. 30 sekund
Ceny i upustyco ok. 60 sekund
Nazwy towarówco 5 minut. Nowy towar pojawia się w API do 5 minut po założeniu. Do tego czasu NOT_FOUND.
Ilości w kartonieco 60 minut
Fakturyco 5 minut, pozycje faktur co 10 minut
  • dataAgeSec to wiek najstarszego zestawu danych użytego do odpowiedzi, w sekundach. Ta sama liczba jest w /prices, /status i /me. Zwykle do ok. 65.
  • Ponad 300 sekund albo wiek nieznany: /prices odpowiada 503 UNAVAILABLE, a /status — 503 ze stanem degraded. /me nadal odpowiada 200.
  • /invoices ma własny próg: 50 minut. Jego dataAgeSec to wiek najstarszego zestawu danych faktur. /status mówi tylko o cenach i stanach.
  • Brak zmian w ERP nie postarza danych. Wiek liczymy od ostatniego udanego odświeżenia.
  • Krótkie 503 są możliwe, na przykład w nocy ok. 02:10–03:40 czasu polskiego. Ponów po chwili.

Wersje i OpenAPI

obecnie 1.3.0
  • Wersja jest w adresie (/v1) i w numerze z trzech liczb (1.3.0).
  • Numer znajdziesz w nagłówku x-daco-api-version odpowiedzi /me, /prices i /invoices, w polu apiVersion (/me, /status) i w pliku OpenAPI.
  • Pola odpowiedzi, których nie znasz, pomijaj.

Specyfikacja OpenAPI OpenAPI 3.0.3

Opis API dla programów: https://api.daco-germany.de/v1/openapi.json.

Plik zaimportujesz do Postmana, Insomnii albo generatora kodu. Adres serwera jest już w pliku.

Historia zmian

DataWersjaZmiany
2026-10-281.3.0Nowe punkty końcowe GET /invoices i GET /invoices/{id}: faktury i korekty z pozycjami, numer KSeF, powiązane zamówienia. Kod błędu NOT_FOUND także dla dokumentów.
2026-10-281.2.0Zamówienia: POST /orders z nagłówkiem Idempotency-Key, GET /orders i GET /orders/{orderNo}. Kody błędów CREDIT_BLOCKED, NOT_FOUND i CONFLICT.
2026-10-081.1.0Nowy punkt końcowy POST /prices: cena netto i stan, do 500 kodów. Kody błędów VALIDATION i UNAVAILABLE. Pole dataAgeSec liczone po wszystkich zestawach danych. Limit ciała żądania 256 KB.
2026-10-011.0.0Klucze i nagłówek Authorization: Bearer. Limit 60 żądań na minutę. Format błędów. GET /status i GET /me. Dokumentacja i plik OpenAPI. Tryb testowy.

Kontakt

klucze i pytania

Klucze wydaje i na pytania odpowiada opiekun handlowy DACO.

E-mail
api@daco-germany.de
Telefon
+48 883 115 115
Firma
Wojciech Rzepka DACO Group Sp. k., ul. Centralna 55, 31-586 Kraków

W zgłoszeniu podaj

  • pierwsze 12 znaków klucza (pole key.prefix z /me) — nigdy cały klucz,
  • datę i godzinę żądania,
  • metodę i ścieżkę, kod HTTP i error.code.

DACO zapisuje dziennik wywołań: identyfikator klucza, konto, czas, metodę, ścieżkę, kod odpowiedzi, czas trwania, liczbę kodów, adres IP i kod błędu. Bez treści żądań i odpowiedzi. Wpisy trzymamy 90 dni.

© 2026 DACO Germany