API partnerówwersja 1.3.0 · ceny netto, stany, zamówienia i faktury
Start
pierwsze żądanie w 3 krokachAPI 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- Format
- JSON, UTF-8, połączenie HTTPS
- Klucz
- wydaje opiekun handlowy DACO — jak uzyskać klucz
Pierwsze żądanie
- Poproś o klucz testowy. Zaczyna się od
dk_test_i zwraca prawdziwe ceny i stany Twojego konta. - Sprawdź klucz.
GET /mepokaże konto, walutę i tryb klucza.bashcurl https://api.daco-germany.de/v1/me \ -H "Authorization: Bearer dk_test_XXXXXXXX"
Windowscurl.exe https://api.daco-germany.de/v1/me -H "Authorization: Bearer dk_test_XXXXXXXX"
- Pobierz ceny i stany.
POST /pricesprzyjmuje listę kodów towarów.bashcurl -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).WindowsZapisz ciało w plikubody.json, w kodowaniu UTF-8:{"items":["329986","BA0210","XX1"]}Wyślij plik. Użyjcurl.exe— w PowerShell samocurlto 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_albodk_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łowaBeareri klucz w adresie dają401.
Klucz testowy i produkcyjny
tryb testowy| Cecha | Testowy | Produkcyjny |
|---|---|---|
| Początek klucza | dk_test_ | dk_live_ |
| Ceny i stany | prawdziwe, z Twojego konta | te same |
Zamówienia POST /orders | tylko sprawdzane: 200, status: validated, bez numeru | składane w DACO: 201, numer API-… |
| Nagłówek odpowiedzi | x-daco-sandbox: 1 | brak |
Pole account.sandbox w /me | true | false |
| Limit | 60 żądań na minutę | 60 żądań na minutę |
| Konsola na tej stronie | tak | nie |
- Klucz testowy służy do sprawdzenia połączenia i formatu na prawdziwych danych Twojego konta.
- Nagłówek
x-daco-sandbox: 1jest 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
429do końca minuty. Także z dobrym kluczem.
Wypróbuj
prawdziwe żądanie do APIWyś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.
Odpowiedź
To samo jako curl
curl https://api.daco-germany.de/v1/status
curl.exe https://api.daco-germany.de/v1/status
Punkty końcowe
odczyt i zamówienia| Metoda | Ścieżka | Klucz | Opis | Kody odpowiedzi |
|---|---|---|---|---|
| GET | /status | bez klucza | Stan usługi i wiek danych | 200, 503 |
| GET | /me | klucz | Sprawdzenie klucza: konto, waluta, tryb | 200, 401, 403, 429, 500 |
| POST | /prices | klucz | Ceny netto i stany dla listy kodów | 200, 400, 401, 403, 429, 500, 503 |
| POST | /orders | klucz | Złożenie zamówienia | 200, 201, 400, 401, 403, 409, 429, 500, 503 |
| GET | /orders | klucz | Lista zamówień konta | 200, 400, 401, 403, 429, 500 |
| GET | /orders/{orderNo} | klucz | Status i pozycje zamówienia | 200, 401, 403, 404, 429, 500 |
| GET | /invoices | klucz | Faktury i korekty: lista z filtrami | 200, 400, 401, 403, 429, 500, 503 |
| GET | /invoices/{id} | klucz | Jeden dokument z pozycjami | 200, 401, 403, 404, 429, 500, 503 |
- Ścieżkę dopisz do adresu bazowego. Wielkość liter ma znaczenie:
/STATUSdaje404. - Nie dodawaj ukośnika na końcu:
/me/daje308. Część klientów HTTP nie powtarza po nimPOST. - 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 /orderstylko czytają dane. Takie żądanie można bezpiecznie powtórzyć. Liczy się do limitu. POST /ordersskłada zamówienie. Ponawiaj je tylko z tym samymIdempotency-Key— wtedy nie powstanie drugie zamówienie.
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}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 kluczaStan 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.
200 — stan ok. 503 — stan degraded. Uwaga: 503 zwraca tu ten sam obiekt stanu, nie obiekt błędu.
Pola odpowiedzi
200 i 503| Pole | Typ | Opis |
|---|---|---|
status | string | ok — /prices poda ceny i stany. degraded — dane starsze niż 5 minut albo wiek nieznany. |
apiVersion | string | Wersja API, dziś 1.3.0. |
dataAgeSec | integer | null | Wiek najstarszego zestawu danych, w sekundach. null — wiek nieznany. |
GET/me
klucz wymaganySprawdza klucz. Zwraca konto, walutę, tryb klucza i wiek danych.
Ciało żądania: brak. Wystarczy nagłówek Authorization.
/me odpowiada 200 także przy nieaktualnych danych. Ich wiek sprawdzaj w dataAgeSec albo w /status.
Pola odpowiedzi
200| Pole | Typ | Opis |
|---|---|---|
apiVersion | string | Wersja API. |
account.customerCode | string | Kod klienta w DACO. |
account.name | string | Nazwa firmy z karty klienta. |
account.currency | string | Waluta konta: PLN albo EUR. |
account.sandbox | boolean | true dla klucza testowego. |
account.profile | string | Typ klienta ustawiony przez DACO: hurt — hurtownia, sklep — sklep detaliczny. To stałe identyfikatory. |
key.prefix | string | Pierwsze 12 znaków klucza. |
key.label | string | null | Opis klucza nadany przez DACO. |
key.createdAt | string | Data utworzenia klucza: ISO 8601, czas UTC, na przykład 2026-10-08T17:47:05Z. |
dataAgeSec | integer | null | Wiek danych, jak w /status. |
POST/prices
klucz wymaganyCena 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.
503 dostaje także błędne żądanie. Świeżość danych sprawdzamy przed treścią żądania.
Ciało żądania
JSON| Pole | Typ | Opis |
|---|---|---|
items | array of string · wymagane | Kody 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:
ba0210toBA0210. - 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| Pole | Typ | Opis |
|---|---|---|
currency | string | Waluta wszystkich cen w odpowiedzi: PLN albo EUR. To waluta konta. |
dataAgeSec | integer | Wiek najstarszego zestawu danych użytego do odpowiedzi (ceny, upusty, stany), w sekundach. Nigdy ponad 300. |
items | array | Jedna pozycja na każdy kod, w kolejności żądania. |
items[].code | string | Kod tak, jak go przysłano, bez odstępów na brzegach. |
items[].name | string | Nazwa towaru, zawsze po polsku. Brak pola przy NOT_FOUND. |
items[].netPrice | number | Cena netto za sztukę, zaokrąglona do 2 miejsc. Brak pola, gdy jest error. |
items[].stock | integer | Ilość dostępna w magazynie DACO. 0 — brak. Brak pola przy NOT_FOUND. |
items[].carton | object · opcjonalne | Tylko 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[].error | string · opcjonalne | NOT_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.10przychodzi jako20.1, a335.00jako335. - 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 wymaganyPOST /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}.
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| Pole | Typ | Opis |
|---|---|---|
items | array · wymagane | Pozycje: od 1 do 500 różnych kodów. Powtórzony kod to błąd DUPLICATE_ITEM. |
items[].code | string · wymagane | Kod towaru DACO, jak w /prices. Do 40 znaków, bez rozróżniania wielkości liter. |
items[].qty | integer · wymagane | Ilość w sztukach: liczba całkowita od 1 do 100 000. |
partial | boolean · opcjonalne | true (domyślnie) — przyjmujemy to, co się da, resztę odrzucamy z powodem. false — wszystko albo nic: każda odrzucona pozycja daje 409. |
reference | string · opcjonalne | Twój numer zamówienia, do 50 znaków. Wraca w odpowiedziach i trafia do zamówienia w DACO. |
note | string · opcjonalne | Uwaga do zamówienia, do 500 znaków. |
Klucz idempotencji (Idempotency-Key)
- Nagłówek
Idempotency-Keyjest 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:
201i nagłówekidempotent-replayed: true. Drugie zamówienie nie powstaje. - Ten sam klucz z inną treścią:
409CONFLICT,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| Pole | Typ | Opis |
|---|---|---|
orderNo | string | null | Numer zamówienia w DACO, na przykład API-261028-8F2K. null dla klucza testowego. |
status | string | queued po przyjęciu. Klucz testowy: validated. Dalsze stany — w tabeli statusów niżej. |
sandbox | boolean | true dla klucza testowego — zamówienie nie zostało złożone. |
reference | string | null | Twój numer zamówienia z żądania. |
currency | string | Waluta cen: PLN albo EUR. |
totalNet | number | Wartość netto przyjętych pozycji. |
createdAt | string | null | Chwila przyjęcia: ISO 8601, czas UTC. null dla klucza testowego. |
accepted | array | Przyjęte pozycje: code, qty, netPrice. Pełne kartony mogą być osobną pozycją z ceną kartonową i polem carton: true. |
rejected | array | Odrzucone ilości: code, qty, reason, a przy STOCK i NO_PRICE także available — ile jest w magazynie. |
Powody odrzucenia pozycji
rejected[].reason| Powód | Kiedy |
|---|---|
NOT_FOUND | Nieznany kod albo towar marki niedostępnej na Twoim koncie — jak w /prices. |
NO_PRICE | Konto nie ma ceny netto na ten towar. Ceny katalogowej nie podstawiamy. |
STOCK | Brak w magazynie albo za mało. Przy partial: true przyjmujemy available sztuk, resztę odrzucamy. |
Kolejność sprawdzeń
- Ciało i
Idempotency-Key(400). Powtórzenie wcześniejszego zamówienia zwraca je od razu. - Świeżość danych (
503), potem ceny i stan każdej pozycji. - Blokada konta i limit kupiecki: limit minus saldo, minus otwarte zamówienia, minus wartość brutto tego zamówienia (
403CREDIT_BLOCKED). Faktury za pobraniem nie blokują. - Przyjęcie: stan sprawdzamy jeszcze raz w chwili zapisu. Sztuki przyjętych pozycji są od razu zarezerwowane —
/pricespokazuje już mniejszy stan.
Powody błędu VALIDATION przy zamówieniach
details.reason| Powód | Kiedy |
|---|---|
IDEMPOTENCY_KEY_REQUIRED | Brak nagłówka Idempotency-Key w POST /orders. |
INVALID_IDEMPOTENCY_KEY | Klucz ma mniej niż 8 albo ponad 100 znaków albo znaki spoza liter, cyfr i . _ : -. |
INVALID_ITEM | Pozycja details.index: zły kod albo qty nie jest liczbą całkowitą od 1 do 100 000. |
DUPLICATE_ITEM | Pozycja details.index powtarza kod z wcześniejszej pozycji. |
INVALID_FIELD | Złe pole details.field: partial, reference albo note. |
INVALID_PARAM | GET /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/{orderNo}
klucz wymaganyStatus 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.
Statusy zamówienia
status| Stan | Znaczenie |
|---|---|
queued | Przyjęte, czeka na przekazanie do systemu DACO. |
sent_to_erp | Przekazane do systemu DACO. Zamówienie w DACO powstaje zwykle w ciągu kilku minut. |
accepted | Zamówienie jest w DACO. erp pokazuje numer, stan realizacji i pozycje — ilości mogą być mniejsze niż wysłane. |
rejected | System DACO nie przyjął zamówienia. Napisz do DACO. |
cancelled | Zamó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
itemszerp.items. - Wartości są netto. Koszty zakupu DACO nie są nigdy podawane.
GET/invoices
klucz wymaganyFaktury 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.
503 dostaje także błędne żądanie. Świeżość danych faktur sprawdzamy przed parametrami.
Parametry adresu
wszystkie opcjonalne| Pole | Typ | Opis |
|---|---|---|
from | string (date) · opcjonalne | Pierwszy dzień wystawienia, YYYY-MM-DD, włącznie. |
to | string (date) · opcjonalne | Ostatni dzień wystawienia, YYYY-MM-DD, włącznie. Domyślnie dziś. |
open | boolean · opcjonalne | true — tylko dokumenty z kwotą do rozliczenia (outstanding różne od 0). false — tylko rozliczone. |
type | string · opcjonalne | Rodzaje dokumentów po przecinku, np. FS,FSK. Najwyżej 10. |
correction | boolean · opcjonalne | true — tylko korekty. false — tylko faktury, bez korekt. |
number | string · opcjonalne | Dokładny numer dokumentu, np. D0C/26/10112/FS. Wielkość liter nie ma znaczenia. |
limit | integer · opcjonalne | Dokumentów na stronę: od 1 do 500. Domyślnie 100. |
offset | integer · opcjonalne | Ile dokumentów pominąć. Następną stronę wskazuje nextOffset. |
- Bez
fromito: ostatnie 90 dni. Zopen=truealbonumber: cała historia dostępna w API. - Sam
from: do dziś. Samoto: 90 dni, które kończą się nato. 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.
?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| Pole | Typ | Opis |
|---|---|---|
dataAgeSec | integer | Wiek najstarszego zestawu danych faktur, w sekundach. Nigdy ponad 3000. |
from | string | null | Zastosowany pierwszy dzień. null — bez ograniczenia. |
to | string | null | Zastosowany ostatni dzień. null — bez ograniczenia. |
total | integer | Liczba wszystkich dokumentów spełniających warunki. |
limit | integer | Rozmiar strony. |
offset | integer | Pominięte dokumenty. |
nextOffset | integer | null | offset następnej strony. null — to ostatnia strona. |
items | array | Dokumenty od najstarszego, wg daty wystawienia. |
items[].id | string | Identyfikator dokumentu. Służy do pobrania szczegółów. |
items[].number | string | Numer dokumentu, np. D0C/26/10112/FS. |
items[].type | string | Rodzaj: FS — faktura, FSK — korekta, FE / FEK — faktura eksportowa i jej korekta. Inne rodzaje są możliwe. |
items[].issueDate | string (date) | Data wystawienia. |
items[].dueDate | string (date) | null | Termin płatności. |
items[].currency | string | Waluta dokumentu: PLN albo EUR. |
items[].exchangeRate | number | null | Kurs waluty z dokumentu. null — dokument bez kursu. |
items[].net | number | Wartość netto w walucie dokumentu. Ujemna w korekcie zmniejszającej. |
items[].vat | number | Kwota VAT. |
items[].gross | number | Wartość brutto. |
items[].outstanding | number | Kwota do rozliczenia. 0 — rozliczony. Ujemna — nierozliczone uznanie z korekty. |
items[].paymentMethod | string | null | transfer, cash, card, cash_on_delivery albo other. |
items[].ksefNumber | string | null | Numer dokumentu w KSeF. null — dokument bez numeru KSeF. |
items[].customer | object | Nabywca: code — kod klienta, name — nazwa. Centrala widzi tu także swoje oddziały. |
items[].isCorrection | boolean | true — dokument jest korektą. |
items[].correctionReason | string | null | Tylko w korekcie: przyczyna korekty z dokumentu, np. Zwrot towaru. Ten sam tekst jest w KSeF. Bywa po polsku albo po angielsku. |
items[].correctedInvoice | object | null | Tylko w korekcie: dokument korygowany wprost (id, number). |
items[].originalInvoice | object | null | Tylko w korekcie: pierwszy dokument łańcucha korekt (id, number). |
items[].orders | array | Zamó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ód | Kiedy | Dodatkowe pole |
|---|---|---|
INVALID_PARAM | Parametr ma złą postać, np. data spoza kalendarza albo limit poza zakresem. | param — nazwa parametru |
RANGE_INVALID | from jest po to. | brak |
RANGE_TOO_LONG | Zakres dłuższy niż 366 dni. | maxDays: 366 |
FROM_TOO_OLD | from jest wcześniejsze niż historia faktur w API. | minFrom — najwcześniejsza dozwolona data |
Warto wiedzieć
- Korekty są osobnymi dokumentami na liście. Filtr
correction=truepokazuje same korekty, acorrectedInvoicewskazuje 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.10przychodzi jako20.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 wymaganyJeden 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.
404 — nie ma takiego dokumentu albo należy do innego konta. Odpowiedź jest w obu przypadkach taka sama.
Pola odpowiedzi
200Pola dokumentu jak w GET /invoices, plus dataAgeSec i items:
| Pole | Typ | Opis |
|---|---|---|
items[].line | integer | Numer pozycji, od 1. |
items[].code | string | null | Kod towaru DACO. |
items[].name | string | null | Nazwa towaru, po polsku. |
items[].qty | number | Ilość. W korekcie: zmiana ilości, zwykle ujemna. |
items[].unit | string | null | Jednostka z dokumentu, np. SZT, KPL. |
items[].netPrice | number | Cena netto za jednostkę. |
items[].netValue | number | Wartość netto pozycji z dokumentu. W korekcie: różnica wartości. |
items[].vatRate | number | null | Stawka VAT w procentach, np. 23. |
items[].correction | object | null | Tylko 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:
qtyinetValueto zmiana,netPriceto cena po korekcie. Pełny obraz jest wcorrection. - Korekta ceny ma
qtyrówne 0 i różnicę wartości wnetValue. - Wartości przed i po to ilość × cena, zaokrąglone do 2 miejsc. Różnica wartości pochodzi z dokumentu.
correctionbywanullw 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
itemsjest puste. - API nie podaje kosztu, marży ani danych magazynowych dokumentu.
Błędy
jeden format · 9 kodówBłą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| Kod | HTTP | Kiedy | Co zrobić |
|---|---|---|---|
VALIDATION | 400 | Złe żądanie. Powód jest w details.reason. | Popraw żądanie. Nie ponawiaj bez zmian. |
UNAUTHORIZED | 401 | Brak klucza, zły albo unieważniony klucz. | Sprawdź klucz i nagłówek. Nie ponawiaj. |
FORBIDDEN | 403 | Klucz jest dobry, ale konto klienta jest niedostępne. | Napisz do DACO. |
CREDIT_BLOCKED | 403 | POST /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_FOUND | 404 | GET /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. |
CONFLICT | 409 | POST /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_LIMIT | 429 | Ponad 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. |
INTERNAL | 500 | Nieprzewidziany błąd serwera. | Ponów później. Jeśli wraca, napisz do DACO. |
UNAVAILABLE | 503 | /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ód | Kiedy | Dodatkowe pole |
|---|---|---|
INVALID_JSON | Ciało jest puste albo nie jest poprawnym JSON-em. | brak |
BODY_TOO_LARGE | Ciało jest większe niż 256 KB. | maxBytes: 262144 |
ITEMS_REQUIRED | Brak items, items nie jest tablicą albo jest pusta. | brak |
TOO_MANY_ITEMS | Ponad 500 różnych kodów. | max: 500 |
INVALID_ITEM | Element 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_FOUNDiNO_PRICEw poluitems[].errorto nie błędy żądania. Odpowiedź ma kod200.- Pozycje odrzucone w
POST /orders(rejected[].reason) też nie są błędem żądania. Odpowiedź ma kod201. GET /statusz kodem503zwraca obiekt stanu, nie obiekt błędu.- Zła metoda, np.
GET /prices: kod405i puste ciało. - Nieznana ścieżka: kod
404i strona HTML zamiast JSON.
Limity
liczone na klucz| Limit | Wartość | Po przekroczeniu |
|---|---|---|
| Żądania | 60 na minutę na klucz | 429 RATE_LIMIT i nagłówek Retry-After |
Kody w jednym żądaniu /prices | 500 różnych | 400 TOO_MANY_ITEMS |
| Długość kodu | 40 znaków | 400 INVALID_ITEM |
| Ciało żądania | 256 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,/ordersi/invoices, także zakończone kodem 400, 403, 404, 409 lub 503. - Nie liczą się:
GET /statusi żądania zakończone kodem401. Retry-Afterpodaje 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
429do końca minuty, z nagłówkiemRetry-After: 60.
Świeżość danych
próg 5 minutAPI 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
| Dane | Odświeżanie |
|---|---|
| Stany | co ok. 30 sekund |
| Ceny i upusty | co ok. 60 sekund |
| Nazwy towarów | co 5 minut. Nowy towar pojawia się w API do 5 minut po założeniu. Do tego czasu NOT_FOUND. |
| Ilości w kartonie | co 60 minut |
| Faktury | co 5 minut, pozycje faktur co 10 minut |
dataAgeSecto wiek najstarszego zestawu danych użytego do odpowiedzi, w sekundach. Ta sama liczba jest w/prices,/statusi/me. Zwykle do ok. 65.- Ponad 300 sekund albo wiek nieznany:
/pricesodpowiada503UNAVAILABLE, a/status—503ze stanemdegraded./menadal odpowiada200. /invoicesma własny próg: 50 minut. JegodataAgeSecto wiek najstarszego zestawu danych faktur./statusmówi tylko o cenach i stanach.- Brak zmian w ERP nie postarza danych. Wiek liczymy od ostatniego udanego odświeżenia.
- Krótkie
503są 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-versionodpowiedzi/me,/pricesi/invoices, w poluapiVersion(/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
| Data | Wersja | Zmiany |
|---|---|---|
| 2026-10-28 | 1.3.0 | Nowe 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-28 | 1.2.0 | Zamó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-08 | 1.1.0 | Nowy 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-01 | 1.0.0 | Klucze 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 pytaniaKlucze wydaje i na pytania odpowiada opiekun handlowy DACO.
- 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.prefixz/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.
