Documentation
JSON API
The fmcgProducts API is a JSON web API on each customer instance. Other systems can create and update product master data, check GS1 status, and fetch the same validated data that you send to GS1 and EPD.
GET /api
A GET to the API root is public. It returns the product name, build version, and links to the live OpenAPI description:
{
"status": 200,
"product": "fmcgProducts",
"version": "…",
"documentation": "/api/openapi",
"documentationAsJson": "/api/openapi.json",
"documentationUi": "/swagger/index.html"
}
If you call it while logged in, the response also includes username.
Base URL
Replace {instance} with the company host:
https://{instance}.fmcgproducts.dk/api
Each instance has its own products, views, export profiles, API keys and templates.
What you can do
- Update a product, or several products, as JSON. Send only the fields that changed (a delta) or a fuller set of fields. The same request can create a product when the GTIN and target market do not exist yet.
- Import an
.xls,.xlsx, or.xmlfile withPOST /api/import. The original file name selects the import profile. - Validate a draft in memory (
test: trueorPOST /api/validate) without saving. - Check status after an update: accepted, in progress, rejected, and GS1 validation errors.
- Fetch selected fields, a view, Excel, PDF or HTML product sheets, and the company logo.
- Send a hierarchy to GS1, or withdraw it, when the data is ready.
Field names in JSON are fmcgProducts field ids such as D8165 (GTIN) and D8255 (target market country code, ISO 3166-1 numeric). Identifiers and fields explains the keys. Authentication explains X-Api-Key.
Import an Excel or XML file
POST /api/import
Send the file as the raw body, or as multipart/form-data. The original file name, including the extension, selects the import profile. The name is read from the multipart file part, or from the Content-Disposition filename on a raw body. Pass filename as a query parameter only when the posted file does not include a name. When both are present, the name on the posted file is used.
.xls and .xlsx use the upload page’s default Excel profile when no profile matches. An .xml file is imported only when an XML import profile matches that name. The extension decides the importer. application/octet-stream is accepted for either kind of file.
Accepted content types:
application/vnd.openxmlformats-officedocument.spreadsheetml.sheetfor.xlsxapplication/vnd.ms-excelfor.xlsapplication/xmlortext/xmlfor.xmlapplication/octet-streammultipart/form-data
The call runs in the HTTP request, the same way as the upload page. Image URL checks are paused, the products are imported and recalculated, and the file and the HTML log are stored on an Imported Files document.
An Excel file can keep the file name in the query parameter:
curl -sS -X POST \
-H "X-Api-Key: YOUR_KEY" \
-H "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" \
--data-binary @products.xlsx \
"https://{instance}.fmcgproducts.dk/api/import?filename=products.xlsx"
An XML file can send the name with the file:
curl -sS -X POST \
-H "X-Api-Key: YOUR_KEY" \
-F "file=@products.xml" \
"https://{instance}.fmcgproducts.dk/api/import"
The same XML file can be a raw body when Content-Disposition carries the name:
curl -sS -X POST \
-H "X-Api-Key: YOUR_KEY" \
-H "Content-Type: application/xml" \
-H "Content-Disposition: attachment; filename=\"products.xml\"" \
--data-binary @products.xml \
"https://{instance}.fmcgproducts.dk/api/import"
Requires an API key when keys are enabled. ?language= selects the language of translated messages: da, de, en, fi, no, or sv.
HTTP 200 means importStatus is SUCCESS or WARNINGS. HTTP 400 means the file was rejected or importStatus is FAILED. A missing file name, an empty body, a file that is not .xls, .xlsx, or .xml, and an .xml file with no matching XML import profile are rejected before import. Rows that were accepted are still saved. The JSON body includes filename, profile, importStatus, rows, and records. Each record has id, action (CREATED, UPDATED, SKIPPED, or FAILED), comments, and items.
Live OpenAPI
Each instance serves the OpenAPI document as YAML at /api/openapi and as JSON at /api/openapi.json. The Swagger page is at /swagger/index.html. Use the document when you need the exact description for that build. These pages are the human-readable guide and stay in sync with the source; they do not list hidden or internal endpoints.
Typical flow
- Create or update units with
POST /api. - Read
validationErrorsandfmcgProductsStatus(or callGET /api/status/{productId}). - When the hierarchy is valid,
POST /api/sendToGS1or usePOST /api/update-and-sendToGS1. - Website, webshop or intranet fetch JSON, images and product sheets from the same source.
Need a key or an instance URL? Contact us or use the helpdesk.
