Documentation

Authentication

Most product endpoints require an API key when keys are enabled on the instance. A logged-in fmcgProducts user with the login role can also call the API. PDF, HTML product sheets, Excel downloads and the company logo are public. Product views can be public or restricted, depending on the instance.

The instance can also allow HTTP Basic, lock the API to selected IP addresses, or use OIDC. For new integrations, send X-Api-Key.

API key

Send the key in the HTTP header:

X-Api-Key: YOUR_KEY

Keys are created in system settings on the instance (title, key, enabled). If API keys are in use and the header is missing or wrong, the API responds with HTTP 401:

{
  "status": 401
}

Typical server-side call:

curl -sS -H "X-Api-Key: YOUR_KEY" \
  "https://{instance}.fmcgproducts.dk/api/status/01234567890123.208"

Call the API from your server. Browser CORS is enabled for GET, POST, OPTIONS and HEAD. The preflight allow-list includes authorization, content-type, accept and If-None-Match. It does not include X-Api-Key, so a browser app should proxy keyed requests through your backend.

Language

Add ?language= to set the language of validation error messages and other translated strings for that request only. Supported codes are the languages configured on the instance (the OpenAPI description lists da, de, en, fi, no, sv as the usual set). If you omit it, the instance default is used (English if unset).

An unsupported value returns HTTP 400 with a list of allowed codes. Successful responses may include Content-Language.

Caching

Cacheable GET responses send ETag and Last-Modified as HTTP headers. Repeat the ETag in If-None-Match on the next request to get HTTP 304 when nothing changed. Language is part of the ETag, so translated validationErrors are not reused for the wrong language.

Errors

HTTP status tells you whether the request could be processed:

Code Meaning
200 The request was accepted. The product may still have validationErrors.
400 Invalid input, such as an unknown field or a bad product id.
401 Authentication failed.
404 Product not found. Body includes status and response.
429 Request limit exceeded (about 90 requests per minute per IP).

JSON error bodies include a status number and usually response (a message) or errors (field-level problems):

{
  "status": 400,
  "errors": {
    "D8165": "D8165 must contain GTIN of the product"
  }
}

If you sent customRequestId on an update, failed responses echo it.

CORS

OPTIONS on /api and subpaths returns 204 with CORS headers when the request has an Origin. Allowed methods: GET, POST, OPTIONS, HEAD. Credentials are allowed. ETag is exposed to the browser.