Skapa EU:s digitala produktpass via API

De flesta DPP-guider berättar vad ett pass måste innehålla. Den här visar hur du skapar EU-kompatibla digitala produktpass programmatiskt — med curl, qr3-SDK:n, batch-skapande, validering, GS1 QR-koder och webhooks.

av QR3 Redaktion

Skapa EU:s digitala produktpass via API

De flesta artiklar om EU:s digitala produktpass (DPP) förklarar vad ett pass måste innehålla. Långt färre visar dig hur du skapar ett — och nästan ingen visar hur du gör det för en katalog med 500 eller 50 000 SKU:er utan att klicka dig igenom ett formulär 50 000 gånger.

Den här guiden är utvecklarversionen. Varje steg nedan är ett verkligt, fungerande anrop mot qr3.app-API:et (https://qr3.app/v1). Om du hanterar produktdata i ett affärssystem, ett PIM eller en databas kan du koppla in DPP-genereringen direkt i din befintliga pipeline.

Varför ett API spelar roll för DPP:er

Ett digitalt produktpass är inte ett engångsdokument. Enligt ekodesignförordningen för hållbara produkter (ESPR, EU 2024/1781) och EU:s batteriförordning 2023/1542 behöver varje reglerad enhet ett pass som hålls aktuellt under hela sin livslängd. För en tillverkare innebär det:

  • Skala — hundratals till tiotusentals produkter, var och en med sin egen GTIN/serie.
  • Aktualitet — data (koldioxidavtryck, återvunnet innehåll, reparationsinformation) ändras och måste uppdateras, inte skapas på nytt.
  • Integration — sanningskällan är ditt affärssystem/PIM, inte ett webbformulär.

Det är ett API-problem. Ett manuellt webbverktyg ger dig de första tio passen; ett API ger dig alla.

1. Autentisering

Varje begäran använder en bearer-token (skapa en API-nyckel i instrumentpanelen). Bas-URL:en är https://qr3.app/v1.

curl https://qr3.app/v1/dpp \
  -H "Authorization: Bearer $QR3_API_KEY"

Eller med den officiella SDK:n:

import { QR3 } from "@qr3/sdk";

const client = new QR3({ apiKey: process.env.QR3_API_KEY! });

2. Skapa ett batteripass

Ett DPP skapas med POST /dpp. Fälten på toppnivå är desamma för varje kategori; den kategorispecifika datan läggs i battery_data, textile_data eller general_data.

curl -X POST https://qr3.app/v1/dpp \
  -H "Authorization: Bearer $QR3_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "gtin": "09506000134376",
    "serial": "SN-00012345",
    "product_name": "PowerCell 5 kWh LFP",
    "manufacturer": "ExampleTech GmbH",
    "origin_country": "DE",
    "category": "battery",
    "market_countries": ["DE", "FR", "AT"],
    "status": "live",
    "battery_data": {
      "capacity_kwh": 5,
      "carbon_footprint_kg": 62,
      "carbon_footprint_class": "B",
      "recycled_content_pct": 12,
      "recyclability_pct": 95,
      "manufacturer_warranty_years": 8,
      "lithium_content_pct": 6.5,
      "certifications": ["CE", "UN38.3"]
    }
  }'

Samma anrop med SDK:n:

const passport = await client.dpp.create({
  gtin: "09506000134376",
  serial: "SN-00012345",
  product_name: "PowerCell 5 kWh LFP",
  manufacturer: "ExampleTech GmbH",
  origin_country: "DE",
  category: "battery",
  market_countries: ["DE", "FR", "AT"],
  battery_data: {
    capacity_kwh: 5,
    carbon_footprint_kg: 62,
    recycled_content_pct: 12,
    recyclability_pct: 95,
    manufacturer_warranty_years: 8,
  },
});

console.log(passport.id);      // dpp_xxxxxxxx
console.log(passport.qr.svg);  // print-ready GS1 Digital Link QR

Svaret inkluderar en konsumentvänd landningssida (lokaliserad till 25 EU-språk) och en GS1 Digital Link-QR-kod redo för etikettutskrift — inget separat QR-steg krävs.

3. Validera innan du skapar

Vill du fånga saknade eller ogiltiga fält innan du sparar? POST /dpp/validate kör exakt EU:s valideringsregler utan att skapa något. Idealiskt som en pre-commit-kontroll i CI.

const result = await client.dpp.validate({
  gtin: "09506000134376",
  product_name: "PowerCell 5 kWh LFP",
  manufacturer: "ExampleTech GmbH",
  origin_country: "DE",
  category: "battery",
  battery_data: {
    capacity_kwh: 5,
    carbon_footprint_kg: 62,
    recycled_content_pct: 12,
    recyclability_pct: 95,
    manufacturer_warranty_years: 8,
  },
});

if (!result.valid) {
  console.error(result.errors);
  // [{ field: "battery_data.recyclability_pct", message: "..." }]
}

4. Batch-skapa en hel katalog

För en produktkatalog skickar du upp till 100 pass per begäran till POST /dpp/batch. Loopa över din affärssystemsexport och du har hela ditt sortiment på några minuter.

const items = products.map((p) => ({
  gtin: p.gtin,
  serial: p.serial,
  product_name: p.name,
  manufacturer: "ExampleTech GmbH",
  origin_country: "DE",
  category: "battery" as const,
  battery_data: {
    capacity_kwh: p.capacityKwh,
    carbon_footprint_kg: p.co2Kg,
    recycled_content_pct: p.recycledPct,
    recyclability_pct: p.recyclablePct,
    manufacturer_warranty_years: p.warrantyYears,
  },
}));

// Chunk into batches of 100
const result = await client.dpp.batch({ items: items.slice(0, 100) });

5. Hämta QR-koden för etikettutskrift

Varje pass exponerar sin GS1 Digital Link-QR i fyra utskriftsformat. Hämta dem via passobjektet eller direkt:

curl https://qr3.app/v1/dpp/dpp_xxxxxxxx/qr.svg \
  -H "Authorization: Bearer $QR3_API_KEY" -o label.svg

qr.svg, qr.png, qr.pdf och qr.eps är alla tillgängliga — SVG/EPS för din etikettskrivare, PNG för webben.

6. Håll datan aktuell (utan att förstöra QR-koden)

GTIN/serie/lot är oföränderliga efter skapandet — det håller den tryckta GS1-URI:n stabil för alltid. Allt annat kan uppdateras med PUT /dpp/{id}:

await client.dpp.update(passport.id, {
  battery_data: {
    capacity_kwh: 5,
    carbon_footprint_kg: 58, // re-measured, lower footprint
    recycled_content_pct: 16, // 2031 target reached early
    recyclability_pct: 95,
    manufacturer_warranty_years: 8,
  },
});

QR-koden på den fysiska produkten ändras aldrig; datan bakom den gör det. Det är hela poängen med ett dynamiskt pass.

7. Skicka in till EU-registret

När EU:s centrala DPP-register är aktuellt för din produkt skickar du in ett pass med ett enda anrop (Business-plan och uppåt):

const reg = await client.dpp.registerForEuRegistry(passport.id);
console.log(reg.data.eu_registry_status);          // "pending"
console.log(reg.data.registry_request_id);

8. Reagera på skanningar med webhooks

DPP-skanningar är händelser. Prenumerera på qr.scanned och du kan strömma dem in i din analys, utlösa ombeställningar eller flagga ett återkallande — i realtid. Nyttolaster är signerade (HMAC-SHA256); verifiera alltid signaturen.

import { verifyWebhook } from "@qr3/sdk";

app.post("/webhooks/qr3", async (req, res) => {
  const event = verifyWebhook(req.body, req.headers["qr3-signature"], secret);
  if (event.type === "qr.scanned") {
    console.log(event.data.country, event.data.dpp_id);
  }
  res.sendStatus(200);
});

Sätt ihop allt: DPP-generering i CI

Det sluttillstånd de flesta tillverkare vill ha: produktdata lever i affärssystemet/PIM:et, och ett schemalagt jobb håller passen synkroniserade.

  1. Exportera ändrade produkter från ditt affärssystem.
  2. client.dpp.validate(...) för var och en — låt bygget misslyckas vid valideringsfel.
  3. client.dpp.batch(...) nya produkter; client.dpp.update(...) ändrade.
  4. Skicka de returnerade qr.svg-URL:erna till ditt etikettutskriftssystem.

Inget webbformulär, ingen kopiera-klistra, ingen avvikelse mellan dina masterdata och dina pass.

Vanliga frågor

Behöver jag ett separat QR-kodverktyg? Nej. Varje DPP returnerar en GS1 Digital Link-QR i SVG/PNG/PDF/EPS. QR-koden är åtkomstpunkten till passet.

Kan jag uppdatera ett pass efter att etiketten är tryckt? Ja — det är kärnidén. GTIN/serie är oföränderliga så den tryckta URI:n förblir giltig; alla datafält är uppdateringsbara via PUT /dpp/{id}.

Hur många pass kan jag skapa på en gång? Upp till 100 per POST /dpp/batch-begäran. Dela upp större kataloger; hastighetsgränser gäller per plan.

Vilka kategorier stöds? battery och textile levereras med fullständig EU-validering idag; general täcker andra produkttyper. Batteri och textil inkluderar en aktiv EU-efterlevnadskontroll (ESPR / AGEC).

Källor

Börja kostnadsfritt och skapa ditt första DPP via API: app.qr3.app/sign-up