Developer docs

Product webhook

One or more products, batched at 50. Upsert on productNumber.

Request

POSTYour endpoint
X-Ildstedet-Webhook-Signature and X-Ildstedet-Webhook-Version. Verify the signature before you parse the body.

Body

Every text field is a Norwegian string. There is no locale object. The catalog is the WebIldstedet assortment sold in Norway, so the payload has no market list and no channel field.

Envelope

webhookVersionstring
Currently "1". Included in the signature.
eventstring
product_changed or structure_changed.
queue.batchSizenumber
Maximum products per request. Currently 50.
queue.batchIndexnumber
This batch, starting at 1.
queue.batchCountnumber
Total batches in this delivery.
queue.isFirstBatchboolean
True on the first request.
queue.isLastBatchboolean
True on the last request.
queue.totalProductCountnumber
Products across all batches.
queue.currentBatchProductCountnumber
Products in this request.
summary.datetimestring
ISO 8601 time the payload was created.
summary.productCountnumber
Products in this request. Same as queue.currentBatchProductCount.
productsarray
Always iterate this array. Do not assume a single product. The same object is returned by the products API.

Product

productNumberstring
Stable product identifier. Use this as your upsert key.
slugstring
URL slug used on ildstedet.no, derived from the Norwegian title.
updatedAtstring
ISO 8601 time this product was last written. Ignore a delivery older than the copy you already stored.
titlestring
Norwegian product title.
descriptionstring | null
Norwegian description.
subtitlestring | null
Norwegian short line.
bulletsstring | null
Norwegian HTML. Sanitize it before you render it in a browser.
productType.codestring
Product group code, for example wood_stoves. This is the category slug on ildstedet.no.
productType.labelstring
Norwegian name of that group.
imageobject | null
Main image: url, and optionally mediaCode and checksum. Products that share an image share the URL.
transparentProductImageobject | null
Cutout image, same shape as image. One image only. Null when there is none.
technicalSpecificationsarray
Each item has code, a Norwegian label, and value.
brandstring | null
Brand name, for example Jøtul or Scan.
variantsarray
Sellable and unpublished variants. Discontinued variants are omitted.
documentsarray
Norwegian manuals and other files, ordered for display. Empty when there are none.
ecoLabelstring | null
Energy label, for example A+.

Variants

A variant is omitted only when its status is Discontinued. Other statuses are included, including Published, ReadyToPublish, UnderEnrichment, and Unpublished. There is no separate active flag. A variant you can sell is typically Published.

productNumberstring
Variant identifier.
statusstring | null
Variant status. Null when it is not set.
colorstring
Color code, for example B or WH.
colorHexstring
Hex color, for example #000000. Omitted when there is no hex for that code.
descriptionstring | null
Norwegian variant description.
subtitlestring | null
Norwegian variant subtitle.
priceobject
Norwegian price. See Prices below. Omitted when the variant has no list price.
imagesarray
Each image has url, and optionally mediaCode and checksum.
transparentProductImageobject | null
Cutout for this variant, same shape as the product image. Null when there is none.

Prices

currency is always NOK. amount is the Norwegian list price. vatIncluded says whether that amount includes VAT. updatedAt is when the price was last written.

When a campaign applies, the same object also includes campaignAmount, campaignFrom, campaignTo, and campaignSlug. They are always sent together, and omitted together when there is no campaign. campaignAmount is greater than 0. A zero amount is not a free campaign and is not sent. Show the campaign price only when today is on or after campaignFrom and on or before campaignTo. Either date may be null. campaignSlug may be null.

If several campaigns cover the same variant, one is chosen: the latest start date wins.

Documents

Only files with a Norwegian display name are included. The array is ordered for display: lower sortOrder first. Documents with no known type sort last, then by filename. Render them in array order.

filenamestring
File name.
displayNamestring
Norwegian heading.
sortOrdernumber | null
Lower numbers appear first. Null when the document type is unknown.
mediaCodestring
File identifier.
checksumstring
File checksum. The same checksum and mediaCode share one URL.
urlstring
Public HTTPS download link.

Example

Payload
{
  "webhookVersion": "1",
  "event": "product_changed",
  "queue": {
    "batchSize": 50,
    "batchIndex": 1,
    "batchCount": 1,
    "isFirstBatch": true,
    "isLastBatch": true,
    "totalProductCount": 1,
    "currentBatchProductCount": 1
  },
  "summary": {
    "datetime": "2026-10-20T08:00:00.000Z",
    "productCount": 1
  },
  "products": [
    {
      "productNumber": "F500",
      "slug": "peisovn-modell-f500",
      "updatedAt": "2026-10-20T08:00:00.000Z",
      "productType": {
        "code": "wood_stoves",
        "label": "Vedovner"
      },
      "title": "Peisovn modell F500",
      "description": "En peisovn med rentbrennende forbrenning.",
      "subtitle": "Skandinavisk design",
      "bullets": "<ul><li>Rentbrennende</li></ul>",
      "image": {
        "url": "https://cdn.example.com/f500.jpg",
        "mediaCode": "1234",
        "checksum": "567890"
      },
      "transparentProductImage": {
        "url": "https://cdn.example.com/f500.png",
        "mediaCode": "4108",
        "checksum": "1595322388"
      },
      "technicalSpecifications": [
        { "code": "AtrPower", "label": "Effekt", "value": "8 kW" }
      ],
      "brand": "Jøtul",
      "variants": [
        {
          "productNumber": "F500-B",
          "status": "Published",
          "color": "B",
          "colorHex": "#000000",
          "description": "Svart utførelse",
          "subtitle": "Tidløs svart",
          "price": {
            "currency": "NOK",
            "amount": 44990,
            "vatIncluded": true,
            "updatedAt": "2026-04-08T12:32:07.551Z",
            "campaignAmount": 39990,
            "campaignFrom": "2026-10-01",
            "campaignTo": "2026-10-31",
            "campaignSlug": "hostkampanje"
          },
          "images": [
            {
              "url": "https://cdn.example.com/f500-b.jpg",
              "mediaCode": "5678",
              "checksum": "123456"
            }
          ],
          "transparentProductImage": {
            "url": "https://cdn.example.com/f500-b.png",
            "mediaCode": "4109",
            "checksum": "1595322399"
          }
        }
      ],
      "documents": [
        {
          "filename": "F500-manual-no.pdf",
          "displayName": "Monterings- og brukerveiledning",
          "sortOrder": 2,
          "mediaCode": "12108",
          "checksum": "1595322388",
          "url": "https://cdn.example.com/files/f500-manual-no.pdf"
        }
      ],
      "ecoLabel": "A+"
    }
  ]
}

Response

Return any 2xx before slow work, so the delivery does not time out. The JSON above is the body you receive.

Additional

When it is sent

  • product_changed — products that changed during the day, delivered together once per day. The same product can appear again later if it changes again.
  • structure_changed — every product in the catalog. Sent at 00:00 Europe/Oslo, and when the catalog is sent on request. Batches use the same envelope.

Handling

  • Treat missing fields, nulls, and empty arrays as normal.
  • The same product can be delivered again. Upsert on productNumber. Do not insert a second copy.
  • On structure_changed, wait until queue.isLastBatch is true. Then delete any product you store whose productNumber was not in this delivery. That product has left the catalog.
The product object matches List products. See Authentication for the signature check.