On top of the battery lane, qr3.app now ships a second complete DPP category: textiles under France's Loi AGEC (Décret 2022-748) with fields prepared for the expected, not yet adopted ESPR delegated act. At the same time we have baked in a live EU validator that runs inside the dashboard — before you save a passport and before you list a product in a new market.
TL;DR, three things you do not get on typical QR platforms:
- A complete textile DPP schema including AGEC mandatory chain and ESPR opt-in.
- A live preview inside the create form that flags AGEC violations and greenwashing instantly.
- A compliance simulator on the detail page that answers: "what happens if I add France to my markets tomorrow?"
Why the textile DPP matters today
The ESPR textile delegated act has not been adopted yet — the Commission's working plan provisionally schedules its adoption for 2027, and its requirements generally apply no earlier than 18 months after entry into force. You cannot wait until then, because a slice of the regulation is already legally binding today:
- Loi AGEC (France, since 2023-01-01): mandatory origin chain, microplastics warning, REACH SVHC transparency, ban on vague environmental claims.
- Since 2025 AGEC applies to producers, importers and other operators placing textiles on the French market with more than €10M annual turnover from the covered products and at least 10,000 units a year (from 2023: €50M and 25,000 units; from 2024: €20M and 10,000 units).
- Greenwashing cease-and-desist letters hit a record volume in France in 2024 — "natural", "biodegradable" or "écologique" without proof is more expensive than a docs sprint.
If you are shipping textiles into the EU (or even just France), setting up your DPP stack now is cheaper than panic-migrating once the ESPR delegated act applies.
The textile schema at a glance
We build directly on the AGEC mandatory field catalog:
{
"category": "textile",
"gtin": "04012345678901",
"product_name": "Organic Cotton T-Shirt",
"manufacturer": "EcoWear GmbH",
"origin_country": "PT",
"market_countries": ["DE", "AT", "FR"],
"textile_data": {
"fiber_composition": [
{ "material": "cotton", "percentage": 95, "origin_country": "TR", "recycled_pct": 0 },
{ "material": "elastane", "percentage": 5, "origin_country": "IT", "recycled_pct": 0 }
],
"country_weaving_knitting": "PT",
"country_dyeing_printing": "PT",
"country_assembly": "PT",
"contains_microplastics": false
}
}
The mandatory fields cover the four AGEC rules French authorities enforce most often:
| Internal check ID | Field | What the validator does |
|---|---|---|
| A1 | fiber_composition[].recycled_pct |
All fiber percentages must total 100% |
| A2–A4 | country_weaving_knitting / dyeing_printing / assembly |
Three countries required whenever FR is in market |
| A5 | contains_microplastics |
Forced to true when synthetic fibers exceed 50% |
| A6 | svhc_substances[] |
CAS number + concentration required from 0.1% |
On top of that we support optional ESPR fields (durability, PEF CO₂, repair URL, spare-part deadline, recyclability class). When all of them are set, the dashboard surfaces an ESPR-ready badge — perfect for manufacturers who invest time now to be ready without a migration once the ESPR delegated act applies.
Live preview: see errors before you save
The typical flow used to be: fill the form → save → jump to the detail page → read compliance errors → go back to the form. That hurts the moment you're creating a batch.
Since this release, the EU validator runs stateless inside the create form:
POST /v1/dpp/validatenow returns an extraeu_compliancefield withcompliant,espr_ready,issues[]and a summary grouped by severity, in addition to the Zod validation.- The dashboard renders the issues directly below the validation panel, grouped by error / warning / info.
- A save-guard banner appears above the submit buttons ("2 errors and 1 warning — save anyway?") whenever issues remain. The save is not blocked, but you see in black and white what you are accepting.
For you as a developer this means: you can ship the validator anywhere — inside your own import flow, in a CI check, in a Cursor agent hook.
curl -X POST https://qr3.app/v1/dpp/validate \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @textile-payload.json | jq '.data.eu_compliance.summary'
The compliance simulator: "what if I add France?"
The feature I personally wanted most is the compliance simulator on an existing DPP's detail page. Typical scenario:
You have 500 textile passports in the system, all for the German market. Sales walks in: "We are expanding to France next month." Question: which of your passports suddenly break AGEC?
Open a passport in the dashboard and a new card appears under the EU compliance section: Compliance simulator.
- Click the chip FR (next to presets DE/AT/FR/IT/ES/NL) or type a custom ISO code.
- Optional: flip the status from
drafttolive. - Button Preview EU impact.
The UI instantly shows you, without saving the passport:
- New error cards (e.g.
TEXTILE_AGEC_REQUIREDon the field pathtextile_data.country_weaving_knitting). - A greenwashing warning that escalates from
warningtoerrorbecause FR is in market. - A
preview.changed_fieldstag pinpointing exactly which fields would change.
When you're happy, Save changes pushes the delta via PUT /v1/dpp/:id. If not — Reset, and nothing happened.
Under the hood this is one new endpoint:
curl -X POST https://qr3.app/v1/dpp/$DPP_ID/validate-update \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "market_countries": ["DE", "FR"], "status": "live" }'
The worker merges the patch in memory with the existing DPP and runs the EU validator over the result — no write access. An empty body is allowed and returns the current verdict.
Why this is more than a "nice to have"
Three reasons the simulator is not a gimmick:
- Pre-sales check for market expansion. Sales can answer in 60 seconds which products are FR-ready and how expensive a rollout would be.
- Decouple data ops from compliance ops. Compliance no longer chases every data defect — run the simulator once, filter cleanly, open tickets.
- AI-agent-friendly. The endpoint has the exact same shape as
POST /v1/dpp/validate. A Cursor or Claude agent can call it directly from a task like "find FR-ready passports" — without a mini script in between.
Still API-first
Everything visible in the dashboard is reachable over the API:
POST /v1/dpp/validate— stateless validator for create flows.POST /v1/dpp/:id/validate-update— stateless validator for partial updates (the simulator).GET /v1/dpp/:id/eu-compliance— persistent check for existing passports (great for CI).POST /v1/dpp/import— CSV/XLSX bulk import with new textile templates (GET /v1/dpp/import/templates/textile?format=xlsx).GET /01/{GTIN}/21/{SERIAL}— consumer view with the AGEC microplastics warning box, origin chain, SVHC list, durability section.
All three validator endpoints return the same EuComplianceResult shape. So you build issue grouping and severity rendering exactly once.
Non-breaking guarantee
Everything in this release is additive:
- Existing
POST /v1/dpp/validateclients can ignore the neweu_compliancefield without changes. - Battery flows are unchanged.
market_countriesis optional and defaults to[].
Details are in the changelog and our API versioning policy.
Get started
- Textile DPP docs — schema, microplastics rule, ESPR opt-in
- EU compliance docs — rule catalog, live preview, simulator
- Start for free — free plan, dashboard + API
- Follow on GitHub — issues, SDK releases, roadmap
If you have a large textile passport catalog or need to audit AGEC/France risk, talk to us — we are set up for pilot customers between 500 and 50,000 SKUs.