Skip to content
Base URLhttps://api.daco-germany.de/v1
Download OpenAPI

Partner APIversion 1.3.0 · net prices, stock, orders and invoices

8 endpointsprices, stock, orders, invoices
60 / minrequest limit per key
500 codesin one price request
up to 5 minutesoldest data in a response

Quick start

first request in 3 steps

The API returns your account's net prices and DACO stock levels. Prices are the same as when you sign in to the B2B platform. One request handles up to 500 product codes. You can also place orders through the API — they reach DACO like orders from the platform — and fetch your invoices and corrections.

Base URL
https://api.daco-germany.de/v1
Version
1.3.0 — in the URL as /v1
Service status
checking
Format
JSON, UTF-8, over HTTPS
Key
issued by your DACO account manager — how to get a key
GET /status works without a key.

First request

  1. Ask for a test key. It starts with dk_test_ and returns the real prices and stock of your account.
  2. Check the key. GET /me shows the account, the currency and the key mode.
    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. Get prices and stock. POST /prices takes a list of product codes.
    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"]}'
    A bash command (Linux, macOS, Git Bash, WSL).
    Windows
    Save the request body to a file named body.json, encoded as UTF-8:
    {"items":["329986","BA0210","XX1"]}
    Send the file. Use curl.exe — in PowerShell, plain curl is a different command.
    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"

API keys

Authorization header · test mode

Requests to /me, /prices, /orders and /invoices require a key in the Authorization header. GET /status works without a key.

  • A key is 40 characters long: dk_test_ or dk_live_ followed by 32 letters or digits.
  • One key belongs to one customer account. Prices, currency and profile are the same as when you sign in to B2B.
  • An account can have several keys. The rate limit is counted separately for each key.
  • There is no other way to authenticate. Basic, a key without the word Bearer and a key in the URL all return 401.

Test and live keys

test mode
FeatureTestLive
Key starts withdk_test_dk_live_
Prices and stockreal, from your accountthe same
Orders POST /orderschecked only: 200, status: validated, no numberplaced at DACO: 201, number API-…
Response headerx-daco-sandbox: 1none
account.sandbox field in /metruefalse
Rate limit60 requests per minute60 requests per minute
Console on this pageyesno
  • A test key lets you check the connection and the data format against the real data of your account.
  • The x-daco-sandbox: 1 header is sent with status codes 200, 400 and 503. It is not sent with 401 or 429.
  • A test key checks an order exactly like a live key — prices, stock, account status and credit limit — but does not place it. Nothing reaches DACO.
  • There is no test data, no dummy products and no way to force errors.
  • The URL is the same. So is the rate limit: 60 requests per minute, counted separately for each key.
  • Calls are recorded in the DACO log like any other call.

How to get a key

  • Keys are issued by DACO. You cannot create a key yourself on the B2B platform.
  • Contact your account manager (contact). Include your customer code and a short description of the integration.
  • The full key is shown only once, when it is created. Store it right away.
  • A lost key cannot be recovered. DACO stores only its hash and the first 12 characters. We will issue a new one.
  • Keys are revoked by DACO. Revocation takes effect with the next request, which returns 401.

Keeping your key safe

  • Keep the key on your server. The API is meant for server-to-server calls and sends no CORS headers, so a page on another domain cannot call it.
  • Never paste the key into emails or support requests. The first 12 characters are enough.
  • After a series of failed attempts from one IP address, that address gets 429 until the end of the minute, even with a valid key.

Try it

a real API request

Send a request from this page and see the response. The request is real. /me, /prices and /invoices need a test key. Those requests count toward the rate limit of 60 per minute and are recorded in the DACO log.

Endpoint
This endpoint does not require a key.
No key needed. Does not count toward the rate limit.

Response

The response will appear here.

The same request as curl

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

Endpoints

read and order
MethodPathKeyDescriptionResponse codes
GET/statusno keyService status and data age200, 503
GET/mekeyKey check: account, currency, mode200, 401, 403, 429, 500
POST/priceskeyNet prices and stock for a list of codes200, 400, 401, 403, 429, 500, 503
POST/orderskeyPlace an order200, 201, 400, 401, 403, 409, 429, 500, 503
GET/orderskeyList your orders200, 400, 401, 403, 429, 500
GET/orders/{orderNo}keyOrder status and lines200, 401, 403, 404, 429, 500
GET/invoiceskeyInvoices and corrections: a filtered list200, 400, 401, 403, 429, 500, 503
GET/invoices/{id}keyOne document with its lines200, 401, 403, 404, 429, 500, 503
  • Append the path to the base URL. Paths are case-sensitive: /STATUS returns 404.
  • Do not add a trailing slash: /me/ returns 308. Some HTTP clients do not resend a POST after a redirect.
  • Checks run in this order: IP address block (429), key (401), key rate limit (429), account (403) and finally the request itself. The first error is returned.
  • All endpoints except POST /orders are read-only. Such a request can be repeated safely. Each repeat counts toward the rate limit.
  • POST /orders places an order. Retry it only with the same Idempotency-Key — then no second order is created.
Full URLs
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}
Response headers for requests with a key
content-type: application/json
cache-control: no-store
x-daco-api-version: 1.3.0
x-daco-sandbox: 1
x-daco-sandbox is sent only for a test key.

GET/status

no key

Service status and data age. It tells you whether POST /prices will return prices and stock right now. It requires no key and does not count toward the rate limit.

Request body: none.

Response codes200503

200 — status ok. 503 — status degraded. Note: here 503 returns the same status object, not an error object.

Response fields

200 and 503
FieldTypeDescription
statusstringok — /prices will return prices and stock. degraded — the data is older than 5 minutes or its age is unknown.
apiVersionstringAPI version, currently 1.3.0.
dataAgeSecinteger | nullAge of the oldest data set, in seconds. null — the age is unknown.

GET/me

key required

Checks the key. Returns the account, the currency, the key mode and the data age.

Request body: none. The Authorization header is all you need.

Response codes200401403429500

/me responds with 200 even when the data is out of date. Check the data age in dataAgeSec or with /status.

Response fields

200
FieldTypeDescription
apiVersionstringAPI version.
account.customerCodestringYour customer code at DACO.
account.namestringCompany name from the customer record.
account.currencystringAccount currency: PLN or EUR.
account.sandboxbooleantrue for a test key.
account.profilestringCustomer type set by DACO: hurt — wholesaler, sklep — retail shop. These are fixed identifiers.
key.prefixstringThe first 12 characters of the key.
key.labelstring | nullKey description assigned by DACO.
key.createdAtstringWhen the key was created: ISO 8601 in UTC, for example 2026-10-08T17:47:05Z.
dataAgeSecinteger | nullData age, as in /status.

POST/prices

key required

Your account's net price and the stock level for a list of product codes. A code that cannot be priced does not fail the request. The response is still 200, and the item carries an error field.

Response codes200400401403429500503

An invalid request can get 503 as well. Data freshness is checked before the request body.

Request body

JSON
FieldTypeDescription
itemsarray of string · requiredDACO product codes (the “DACO ID” from the catalog). From 1 to 500 different codes.
  • A code is 1 to 40 characters long. Leading and trailing whitespace is ignored. Letter case does not matter: ba0210 is BA0210.
  • Repeated codes are merged and the first occurrence is kept. The limit of 500 is counted after merging. The response then has fewer items than the request.
  • Codes are matched exactly. There is no lookup by EAN, OE number or name.
  • Body: JSON in UTF-8, up to 256 KB. The Content-Type: application/json header is recommended. Other fields in the body are ignored.

Response fields

200
FieldTypeDescription
currencystringCurrency of every price in the response: PLN or EUR. This is the account currency.
dataAgeSecintegerAge, in seconds, of the oldest data set used for the response (prices, discounts, stock). Never more than 300.
itemsarrayOne item per code, in request order.
items[].codestringThe code as sent, without leading or trailing whitespace.
items[].namestringProduct name, always in Polish. Absent for NOT_FOUND.
items[].netPricenumberNet unit price, to 2 decimal places. Absent when error is set.
items[].stockintegerQuantity available in the DACO warehouse. 0 — out of stock. Absent for NOT_FOUND.
items[].cartonobject · optionalPresent only when a carton price applies to your account and this product. qty — pieces in a full carton. netPrice — net unit price for pieces ordered in full cartons.
items[].errorstring · optionalNOT_FOUND — unknown code, or a product of a brand not available on your account; the item has only code and error. NO_PRICE — the product exists, but your account has no net price for it; name and stock are still returned. Field absent — the item is priced.

Good to know

  • Prices are net, per piece. The API returns neither the VAT rate nor a gross price.
  • A price is a JSON number: 20.10 arrives as 20.1, and 335.00 as 335.
  • Stock is counted for the main warehouse only. Other warehouses are not included.
  • Match the response to the request by code, trimmed and case-insensitive. Not by position: once repeated codes are merged, positions shift.
  • The API does not provide a list of codes. Take the codes from the DACO catalog or price list.
  • The API does not return EANs, OE numbers, English names, minimum quantities or delivery dates.
  • There is no pagination. One request takes at most 500 codes.

POST/orders

key required

POST /orders places an order on your account. Prices and stock are worked out exactly as in /prices — we do not take prices from the request. The order reaches DACO the same way as an order from the B2B platform; check its status with GET /orders/{orderNo}.

Response codes200201400401403409429500503

201 — order accepted. 200 — test key: the order was only checked. With partial: true, lines rejected for stock, price or code do not fail the order.

Request body

JSON
FieldTypeDescription
itemsarray · requiredLines: from 1 to 500 different codes. A repeated code is a DUPLICATE_ITEM error.
items[].codestring · requiredDACO product code, as in /prices. Up to 40 characters, case-insensitive.
items[].qtyinteger · requiredQuantity in pieces: a whole number from 1 to 100 000.
partialboolean · optionaltrue (default) — we accept what we can and reject the rest with a reason. false — all or nothing: any rejected line returns 409.
referencestring · optionalYour own order number, up to 50 characters. It is returned in responses and stored with the order at DACO.
notestring · optionalA note for the order, up to 500 characters.

Idempotency key (Idempotency-Key)

  • The Idempotency-Key header is required: 8 to 100 characters, ideally a UUID. A new order needs a new key.
  • The same key with the same body returns the same order: 201 and an idempotent-replayed: true header. No second order is created.
  • The same key with a different body: 409 CONFLICT, details.reason: IDEMPOTENCY_KEY_REUSED.
  • The key applies to your account, also after the API key is replaced. Refusals (400, 403, 409, 503) are not remembered — once the cause is fixed, the same key places the order.

Response fields

201 · 200
FieldTypeDescription
orderNostring | nullDACO order number, for example API-261028-8F2K. null for a test key.
statusstringqueued once accepted. Test key: validated. Later states are listed in the status table below.
sandboxbooleantrue for a test key — the order was not placed.
referencestring | nullYour order number from the request.
currencystringPrice currency: PLN or EUR.
totalNetnumberNet value of the accepted lines.
createdAtstring | nullWhen the order was accepted: ISO 8601 in UTC. null for a test key.
acceptedarrayAccepted lines: code, qty, netPrice. Full cartons may be a separate line at the carton price, with carton: true.
rejectedarrayRejected quantities: code, qty, reason, and for STOCK and NO_PRICE also available — the quantity in stock.

Line rejection reasons

rejected[].reason
ReasonWhen
NOT_FOUNDUnknown code, or a product of a brand not available on your account — as in /prices.
NO_PRICEYour account has no net price for this product. We never substitute the catalog price.
STOCKOut of stock or not enough. With partial: true we accept available pieces and reject the rest.

Order of checks

  1. Body and Idempotency-Key (400). A repeat of an earlier order returns it right away.
  2. Data freshness (503), then the price and stock of each line.
  3. Account status and credit limit: the limit minus the balance, minus open orders, minus the gross value of this order (403 CREDIT_BLOCKED). Cash-on-delivery invoices never block.
  4. Acceptance: stock is checked once more at the moment of saving. The pieces of accepted lines are reserved at once — /prices already shows the lower stock.

VALIDATION reasons for orders

details.reason
ReasonWhen
IDEMPOTENCY_KEY_REQUIREDThe Idempotency-Key header is missing in POST /orders.
INVALID_IDEMPOTENCY_KEYThe key is shorter than 8 or longer than 100 characters, or has characters other than letters, digits and . _ : -.
INVALID_ITEMLine details.index: an invalid code, or qty is not a whole number from 1 to 100 000.
DUPLICATE_ITEMLine details.index repeats the code of an earlier line.
INVALID_FIELDInvalid field details.field: partial, reference or note.
INVALID_PARAMGET /orders: invalid parameter details.param — from or limit.

Plus INVALID_JSON, BODY_TOO_LARGE, ITEMS_REQUIRED and TOO_MANY_ITEMS as in /prices — the line limit is 500.

GET/orders

key required

Orders of your account placed through the API and on the B2B platform, newest first. Parameters: from (a YYYY-MM-DD date, the last 30 days by default, at most 180 days) and limit (50 by default, at most 200).

Response codes200400401403429500

GET/orders/{orderNo}

key required

Status and lines of one order: items — as sent to DACO, erp — the order at DACO once it exists. An order of another account returns 404, the same as a number that does not exist.

Response codes200401403404429500

Order statuses

status
StatusMeaning
queuedAccepted, waiting to be passed to the DACO system.
sent_to_erpPassed to the DACO system. The order at DACO is usually created within a few minutes.
acceptedThe order exists at DACO. erp shows its number, fulfilment state and lines — quantities can be lower than sent.
rejectedThe DACO system did not take the order. Contact DACO.
cancelledThe order was cancelled at DACO.

Good to know

  • The status changes asynchronously. Check it again after a few minutes, at most once a minute per order.
  • The order at DACO can have lower quantities than sent — compare items with erp.items.
  • Values are net. DACO purchase costs are never returned.

GET/invoices

key required

Invoices and corrections of your account: headers, amounts, the amount to settle, the KSeF number and orders. The same documents as under Finance on the B2B platform. No files: the original is in KSeF.

Request body: none. Filters go in URL parameters.

Response codes200400401403429500503

An invalid request can get 503 as well. Invoice data freshness is checked before the parameters.

URL parameters

all optional
FieldTypeDescription
fromstring (date) · optionalFirst issue date, YYYY-MM-DD, inclusive.
tostring (date) · optionalLast issue date, YYYY-MM-DD, inclusive. Defaults to today.
openboolean · optionaltrue — only documents with an amount to settle (outstanding other than 0). false — only settled ones.
typestring · optionalDocument types, comma-separated, for example FS,FSK. At most 10.
correctionboolean · optionaltrue — corrections only. false — invoices only, without corrections.
numberstring · optionalThe exact document number, for example D0C/26/10112/FS. Letter case does not matter.
limitinteger · optionalDocuments per page: 1 to 500. Defaults to 100.
offsetinteger · optionalHow many documents to skip. nextOffset points to the next page.
  • Without from and to: the last 90 days. With open=true or number: the whole history available in the API.
  • Only from: up to today. Only to: the 90 days that end on to. The range is at most 366 days.
  • Invoice history in the API: the last 2 years, plus older documents with an amount to settle.
  • Other parameters are ignored.
Example parameters
?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

Response fields

200
FieldTypeDescription
dataAgeSecintegerAge, in seconds, of the oldest invoice data set. Never more than 3000.
fromstring | nullThe first day applied. null — no limit.
tostring | nullThe last day applied. null — no limit.
totalintegerNumber of all documents that match.
limitintegerPage size.
offsetintegerDocuments skipped.
nextOffsetinteger | nullThe offset of the next page. null — this is the last page.
itemsarrayDocuments from the oldest, by issue date.
items[].idstringDocument identifier. Use it to fetch the details.
items[].numberstringDocument number, for example D0C/26/10112/FS.
items[].typestringType: FS — invoice, FSK — correction, FE / FEK — export invoice and its correction. Other types are possible.
items[].issueDatestring (date)Issue date.
items[].dueDatestring (date) | nullPayment due date.
items[].currencystringDocument currency: PLN or EUR.
items[].exchangeRatenumber | nullExchange rate from the document. null — the document has none.
items[].netnumberNet amount in the document currency. Negative in a correction that reduces the amount.
items[].vatnumberVAT amount.
items[].grossnumberGross amount.
items[].outstandingnumberAmount to settle. 0 — settled. Negative — an unsettled credit from a correction.
items[].paymentMethodstring | nulltransfer, cash, card, cash_on_delivery or other.
items[].ksefNumberstring | nullThe document number in KSeF. null — the document has no KSeF number.
items[].customerobjectBuyer: code — customer code, name — name. A head office also sees its branches here.
items[].isCorrectionbooleantrue — the document is a correction.
items[].correctionReasonstring | nullCorrections only: the reason for the correction from the document, for example Zwrot towaru (goods returned). The same text is in KSeF. It may be in Polish or English.
items[].correctedInvoiceobject | nullCorrections only: the document corrected directly (id, number).
items[].originalInvoiceobject | nullCorrections only: the first document in the chain of corrections (id, number).
items[].ordersarrayOrders on this document: orderNo — the order number on the platform, reference — your order reference, erpNumber — the order number in the ERP. A correction has an empty list.

VALIDATION error reasons

details.reason
ReasonWhenExtra field
INVALID_PARAMA parameter is malformed, for example a date that does not exist or a limit out of range.param — the parameter name
RANGE_INVALIDfrom is after to.none
RANGE_TOO_LONGThe range is longer than 366 days.maxDays: 366
FROM_TOO_OLDfrom is earlier than the invoice history in the API.minFrom — the earliest allowed date

Good to know

  • Corrections are separate documents on the list. The correction=true filter shows corrections only, and correctedInvoice points to the corrected document.
  • A head office sees its own documents and those of its branches. A branch sees only its own.
  • Amounts are in the document currency, to 2 decimal places. An amount is a JSON number: 20.10 arrives as 20.1.
  • The order is fixed: from the oldest. New documents are added at the end, so pages counted from the start do not shift.
  • A new document appears in the API a few minutes after it is issued in the ERP.
  • The API returns neither PDF nor XML. Download the document from KSeF using ksefNumber.

GET/invoices/{id}

key required

One document with its lines. Take the id from the GET /invoices list. A document number contains slashes — look it up on the list with the number parameter.

Request body: none.

Response codes200401403404429500503

404 — there is no such document, or it belongs to another account. The response is the same in both cases.

Response fields

200

The document fields are the same as in GET /invoices, plus dataAgeSec and items:

FieldTypeDescription
items[].lineintegerLine number, from 1.
items[].codestring | nullDACO product code.
items[].namestring | nullProduct name, in Polish.
items[].qtynumberQuantity. In a correction: the change in quantity, usually negative.
items[].unitstring | nullUnit from the document, for example SZT (piece) or KPL (set).
items[].netPricenumberNet unit price.
items[].netValuenumberNet line value from the document. In a correction: the change in value.
items[].vatRatenumber | nullVAT rate in percent, for example 23.
items[].correctionobject | nullCorrections only: before and after — quantity, price and value before and after the correction. difference — the change in quantity, price and value. null in an invoice.

Good to know

  • A correction line: qty and netValue are the change, netPrice is the price after the correction. The full picture is in correction.
  • A price correction has a qty of 0 and the change in value in netValue.
  • The values before and after are quantity × price, to 2 decimal places. The change in value comes from the document.
  • correction may be null in a correction from before this data was available in the API. Only the change fields are present then.
  • A document older than 2 years may have no lines. In that case items is empty.
  • The API returns no cost, margin or warehouse data for a document.

Errors

one format · 9 codes

An error always has the same shape: an error object with code, message and sometimes details. Identify errors by error.code — the codes are stable.

error.message is meant for people. It is in Polish when the Accept-Language header starts with pl, and in English otherwise. Codes and field names are the same in both languages.

Error codes

error.code
CodeHTTPWhenWhat to do
VALIDATION400Invalid request. The reason is in details.reason.Fix the request. Do not retry it unchanged.
UNAUTHORIZED401Missing, invalid or revoked key.Check the key and the header. Do not retry.
FORBIDDEN403The key is valid, but the customer account is not available.Contact DACO.
CREDIT_BLOCKED403POST /orders: order dispatch is on hold — the account is blocked or invoices are overdue (details.reason: BLOCKED), or the order exceeds your credit limit (CREDIT_LIMIT).Settle your invoices or reduce the order. Questions go to your DACO account manager.
NOT_FOUND404GET /orders/{orderNo}: there is no such order on your account. GET /invoices/{id}: there is no such document, or it belongs to another account.Check the order number, or the document id on the GET /invoices list. Do not retry it unchanged.
CONFLICT409POST /orders: the same Idempotency-Key with a different body (IDEMPOTENCY_KEY_REUSED), rejected lines with partial: false (ITEMS_REJECTED), or nothing to accept (NO_ACCEPTED_ITEMS).Fix the order. A new body needs a new Idempotency-Key.
RATE_LIMIT429More than 60 requests per minute for one key: details.limitPerMinute. Or an IP address blocked after a series of invalid keys: no details.Wait the number of seconds given in the Retry-After header.
INTERNAL500Unexpected server error.Retry later. If it keeps happening, contact DACO.
UNAVAILABLE503/prices and POST /orders: the data is older than 5 minutes. /invoices: the invoice data is older than 50 minutes. Or the age is unknown. details.dataAgeSec is present when the age is known. For an order, also when the account status cannot be checked.Retry in a few minutes. Check GET /status. There is no Retry-After header.

503 is permanent when the account currency is neither PLN nor EUR. In that case, contact DACO.

VALIDATION error reasons

details.reason
ReasonWhenExtra field
INVALID_JSONThe body is empty or is not valid JSON.none
BODY_TOO_LARGEThe body is larger than 256 KB.maxBytes: 262144
ITEMS_REQUIREDitems is missing, is not an array or is empty.none
TOO_MANY_ITEMSMore than 500 different codes.max: 500
INVALID_ITEMAn element is not a string, is empty or is longer than 40 characters. The first one found is reported.index — position in the array, counted from 0

Item errors and special cases

  • NOT_FOUND and NO_PRICE in items[].error are not request errors. The response status is 200.
  • Lines rejected by POST /orders (rejected[].reason) are not request errors either. The response status is 201.
  • GET /status with 503 returns the status object, not an error object.
  • Wrong method, for example GET /prices: status 405 and an empty body.
  • Unknown path: status 404 and an HTML page instead of JSON.

Limits

counted per key
LimitValueWhen exceeded
Requests60 per minute per key429 RATE_LIMIT and a Retry-After header
Codes in one /prices request500 unique codes400 TOO_MANY_ITEMS
Code length40 characters400 INVALID_ITEM
Request body256 KB (262,144 bytes)400 BODY_TOO_LARGE
  • The minute starts with the first request. All 60 requests can be used at once.
  • Every request to /me, /prices, /orders and /invoices with a recognized key counts, including requests that end with 400, 403, 404, 409 or 503.
  • Not counted: GET /status and requests that end with 401.
  • Retry-After gives the number of seconds until the end of the minute, from 1 to 60. There are no headers reporting the remaining quota.
  • The full catalog, about 8,000 codes, takes 16–17 requests of 500 codes each. That fits within one minute.
  • After a series of failed key attempts from one IP address, that address gets 429 until the end of the minute, with a Retry-After: 60 header.

Data freshness

5-minute threshold

The API answers from a copy of the ERP data kept on the B2B server. It does not query the ERP on every request. When the data is older than 5 minutes, the API responds with 503 instead of returning outdated figures.

How often the data is refreshed

DataRefresh interval
Stockabout every 30 seconds
Prices and discountsabout every 60 seconds
Product namesevery 5 minutes. A new product appears in the API up to 5 minutes after it is created. Until then its code returns NOT_FOUND.
Carton quantitiesevery 60 minutes
Invoicesevery 5 minutes, invoice lines every 10 minutes
  • dataAgeSec is the age, in seconds, of the oldest data set used for the response. /prices, /status and /me report the same number. It is usually no more than about 65.
  • Above 300 seconds, or when the age is unknown: /prices responds with 503 UNAVAILABLE, and /status with 503 and status degraded. /me still responds with 200.
  • /invoices has its own threshold: 50 minutes. Its dataAgeSec is the age of the oldest invoice data set. /status covers prices and stock only.
  • Data does not age just because nothing changed in the ERP. The age is counted from the last successful refresh.
  • Short periods of 503 are possible, for example at night around 02:10–03:40 Polish time. Retry after a moment.

Versions and OpenAPI

currently 1.3.0
  • The version is part of the URL (/v1) and is also given as a three-part number (1.3.0).
  • You will find the number in the x-daco-api-version header of /me, /prices and /invoices responses, in the apiVersion field (/me, /status) and in the OpenAPI file.
  • Ignore response fields you do not recognize.

OpenAPI specification OpenAPI 3.0.3

A machine-readable description of the API: https://api.daco-germany.de/v1/openapi.json.

Import the file into Postman, Insomnia or a code generator. The server URL is already in the file.

Changelog

DateVersionChanges
2026-10-281.3.0New endpoints GET /invoices and GET /invoices/{id}: invoices and corrections with their lines, the KSeF number and related orders. Error code NOT_FOUND also for documents.
2026-10-281.2.0Orders: POST /orders with the Idempotency-Key header, GET /orders and GET /orders/{orderNo}. Error codes CREDIT_BLOCKED, NOT_FOUND and CONFLICT.
2026-10-081.1.0New endpoint POST /prices: net price and stock for up to 500 codes. Error codes VALIDATION and UNAVAILABLE. The dataAgeSec field now covers all data sets. Request body limit of 256 KB.
2026-10-011.0.0Keys and the Authorization: Bearer header. Limit of 60 requests per minute. Error format. GET /status and GET /me. Documentation and the OpenAPI file. Test mode.

Contact

keys and questions

Your DACO account manager issues keys and answers questions.

Email
api@daco-germany.de
Phone
+48 883 115 115
Company
Wojciech Rzepka DACO Group Sp. k., ul. Centralna 55, 31-586 Kraków, Poland

What to include in a support request

  • the first 12 characters of the key (the key.prefix field from /me) — never the full key,
  • the date and time of the request,
  • the method and path, the HTTP status and error.code.

DACO keeps a log of API calls: key identifier, account, time, method, path, response status, duration, number of codes, IP address and error code. Request and response bodies are not logged. Entries are kept for 90 days.

© 2026 DACO Germany
Partner API · DACO B2B