Fetch the complete documentation index at: https://eulabel.eu/docs/llms.txt Use this file to discover all available pages before exploring further. Full content: https://eulabel.eu/docs/llms-full.txt Append .md to any page URL for markdown, or send Accept: text/markdown.

Inbound Webhooks

Sync product data from your PIM or CMS to EUlabel via webhooks.

When product data changes in your PIM (e.g., DatoCMS, Salsify, Akeneo), a webhook triggers EUlabel to regenerate the passport automatically.

At a glance

  • Inbound endpoint: POST /v1/webhooks/ingest
  • Always verify HMAC signatures using the raw request body
  • Keep your handler idempotent (retries can deliver duplicates)

Flow

A product record is created or updated in your PIM.

The PIM sends a webhook POST to https://api.eulabel.eu/v1/webhooks/ingest.

EUlabel validates the webhook signature.

The platform maps PIM fields to passport fields.

The passport is regenerated (or created if new).

The QR code URL continues to resolve to the updated passport.

Example payload (DatoCMS)

{
  "event_type": "item.update",
  "entity_type": "item",
  "entity": {
    "id": "Kq7rxxPPS32ErMA8nxxMTA",
    "type": "product",
    "attributes": {
      "product_name": "Quinta dos Carvalhais Alfrocheiro 2019",
      "barcode": [
        {
          "barcode_number": "5601012012200",
          "capacity_value": "750 mL",
          "vintage_year": 2019
        }
      ],
      "list_of_ingredient": [
        { "ingredient_name": "Grapes", "quantity": "99.986%" },
        { "ingredient_name": "Sulphites", "quantity": "0.014%" }
      ],
      "contains_sulfites": true,
      "energy_value_kj": "351 kJ/100mL",
      "alcohol_content_by_volume": "13.5%vol.",
      "product_country": "PT",
      "product_region": "Dao"
    }
  }
}

Signature verification

Every inbound webhook includes a signature header:

X-Webhook-Signature: sha256=<HMAC-SHA256 of request body using shared secret>

Always use a constant-time comparison when verifying HMAC signatures. A naive string comparison is vulnerable to timing attacks.

Verify it by computing the HMAC of the raw request body with your shared secret and comparing to the provided signature. Requests with invalid signatures are rejected with HTTP 401.

Many frameworks parse JSON and change whitespace or key ordering. Signature verification must be computed over the exact raw body bytes received by your server.

Verification example

import { EUlabel } from "@eulabel/sdk";

const client = new EUlabel({ apiKey: "sk_test_..." });

const isValid = client.webhooks.verify(
  requestBody,
  request.headers["x-webhook-signature"],
  process.env.WEBHOOK_SECRET,
);
# Compute HMAC-SHA256 of the raw body
echo -n "$BODY" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET"

Field mapping

EUlabel maps PIM-specific fields to the passport schema. Mapping configurations are stored per tenant, allowing each organization to define their own field correspondence.

PIM FieldEUlabel Passport Field
product_namename
barcode[].barcode_numbergtin
list_of_ingredient[].ingredient_nameingredients[]
contains_sulfites, contains_egg, etc.allergens
energy_value_kj, fat, sugars, etc.nutrition
product_country + product_regionorigin
producer[].namesupplier

Supported platforms

PlatformIntegrationStatus
DatoCMSNative webhooks + GraphQLAvailable
SalsifyWebhooks + REST APIComing soon
AkeneoEvent API + RESTComing soon
ContentfulWebhooks + Content Delivery APIComing soon
Custom PIMGeneric webhook endpointAvailable

For platforms without native webhook support, call the EUlabel API directly using the SDK.

On this page