Skip to content

Frequently Asked Questions

Common questions about dppvalidator, Digital Product Passports, and EU compliance.


What is dppvalidator?

What does dppvalidator do?

dppvalidator is a Python library that validates Digital Product Passports (DPP) against EU ESPR regulations and UNTP standards. It ensures your DPP data is structurally correct, semantically meaningful, and optionally cryptographically verifiable before production deployment.

Core capabilities:

  • Validate DPP JSON data through seven validation layers (plus a Layer 0 detection phase)
  • Parse DPP data into type-safe Pydantic models
  • Export validated passports to JSON-LD format for W3C Verifiable Credentials
  • Verify cryptographic signatures on signed credentials
  • Crawl supply chains by following linked documents

What dppvalidator is NOT

  • Not a DPP generator — It validates existing data, not creates it from scratch
  • Not a database — It doesn't store passports; use it as validation middleware
  • Not a blockchain — Signature verification supports DIDs, but doesn't require blockchain
  • Not a UI framework — It's a backend library; build your own frontend

Who Should Use dppvalidator?

Primary Users

Role Use Case
Fashion/Textile Brands Validate DPP data before QR code generation
Backend Developers Integrate DPP validation into APIs and microservices
DevOps Engineers Add compliance gates to CI/CD pipelines
Sustainability Teams Validate supplier DPP submissions
System Integrators Migrate legacy product data to DPP format

Industry Applications

  • Textiles & Apparel — EU ESPR compliance starting 2027
  • Electronics & Batteries — Battery passport requirements
  • Construction Materials — Building product passports
  • Packaging — Recyclability and material traceability

Technical Questions

What Python versions are supported?

Python 3.10+ is required. We recommend Python 3.12 for best performance.

What are the core dependencies?

All included by default:

  • Pydantic v2 — Data validation and parsing
  • jsonschema — JSON Schema validation
  • pyld — JSON-LD expansion and context resolution
  • httpx — HTTP client for deep validation
  • cryptography — Signature verification
  • PyJWT — JWT token handling

Optional extras:

  • rich — CLI formatting (install with uv add "dppvalidator[cli]" or pip install "dppvalidator[cli]")

How fast is validation?

Validation Type Throughput
Schema only ~200,000 ops/sec
Model only ~85,000 ops/sec
Full (all layers) ~60,000 ops/sec
With JSON-LD ~10,000 ops/sec (network-dependent)

Benchmarked on Apple M2, Python 3.12

What schema versions are supported?

Currently supported:

  • UNTP DPP 0.6.0 — supported (legacy)
  • UNTP DPP 0.6.1 — supported (legacy)
  • UNTP DPP 0.7.0 — default

Schema version is auto-detected from @context or $schema fields. You can also specify it explicitly:

Python
engine = ValidationEngine(schema_version="0.7.0")  # current default
engine = ValidationEngine(schema_version="0.6.1")  # opt in to legacy v0.6

For the full version-handling story see UNTP DPP versions.

Can I migrate v0.6.x payloads to v0.7.0?

Yes — dppvalidator ships a compat shim that rewrites v0.6.x payloads into v0.7.0 shape with structured warnings for anything it can't fully translate:

Bash
# Upgrade and write to a new file
dppvalidator migrate passport-v06.json -o passport-v07.json

# Validate-after-upgrade in one shot
dppvalidator validate passport-v06.json \
    --upgrade-from 0.6.1 \
    --schema-version 0.7.0
Python
from dppvalidator.compat import upgrade

upgraded, warnings = upgrade(payload_v06, country_lookup={"DE": "Germany"})

The shim emits four warning codes (UPG001UPG004) covering lossy transformations, synthesised values, unmapped country codes, and required-field gaps. See the migration guide for the field rename table and the documented limitations.


Validation Questions

What are the seven validation layers?

  1. Layer 0: Detection — Auto-detects DPP family + schema version
  2. Layer 1: Schema — JSON Schema structure validation (SCH001SCH099)
  3. Layer 2: Model — Pydantic type validation (MDL001MDL099)
  4. Layer 3: JSON-LD — Context expansion and term resolution (JLD001JLD099)
  5. Layer 4: Semantic — Date logic, GTIN checksums, mass-fraction sums (SEM001SEM099)
  6. Layer 5: Vocabulary — ISO / UNECE / HS code lists (VOC001VOC099)
  7. Layer 6: Plugin — Per-pack rules (TXT*, CQ*, TYR*, …)
  8. Layer 7: Signature (reserved) — VC signature verification (optional; codes pending)

The canonical taxonomy lives in ADR 0006.

Can I run only specific layers?

Yes, use the layers parameter:

Python
# Schema validation only (fastest)
engine = ValidationEngine(layers=["schema"])

# Model + Semantic only
engine = ValidationEngine(layers=["model", "semantic"])

# Full validation with JSON-LD
engine = ValidationEngine(layers=["schema", "model", "semantic", "jsonld"])

What error codes does dppvalidator use?

Prefix Surface Description
SCH Schema (Layer 1) JSON Schema validation errors
MDL Model (Layer 2) Pydantic validation errors
JLD JSON-LD (Layer 3) Context/term resolution errors
SEM Semantic (Layer 4) Business rule violations
VOC Vocabulary (Layer 5) Code list validation errors
SIG Signature (Layer 7) Reserved; verifier emits string errors today
PRS Parse (pre-Layer 1) Input parsing errors
DET Detection (Layer 0) Family-mismatch routing errors
VER Version routing UNTP version-mismatch errors
UPG Upgrade shim (0.6 → 0.7) Intra-family upgrade warnings
MAP Migration shim (UNTP ↔ CIRPASS) Cross-family mapping warnings
PRT Advisory rules Role-enum strictness and other advisory checks

How do I handle validation errors?

Python
result = engine.validate(dpp_data)

if not result.valid:
    for error in result.errors:
        print(f"[{error.code}] {error.path}: {error.message}")
        if error.suggestion:
            print(f"  Suggestion: {error.suggestion}")

Each error includes:

  • code — Error identifier (e.g., SEM001)
  • path — JSON path to the error (e.g., $.credentialSubject.materials[0].massFraction)
  • message — Human-readable description
  • suggestion — How to fix the error (optional)
  • docs_url — Link to detailed documentation (optional)

Use Case Questions

Can I use dppvalidator for CI/CD compliance gates?

Yes! Add validation to your pipeline:

YAML
# .github/workflows/validate-dpp.yml
- name: Validate DPP files
  run: |
    # Using uv (recommended)
    uv pip install dppvalidator
    # Or: pip install dppvalidator
    dppvalidator validate data/passports/*.json --strict --format json

Exit codes:

  • 0 — All validations passed
  • 1 — Validation failed
  • 2 — System error (file not found, invalid JSON)

Can I validate supplier submissions via API?

Yes, integrate into your backend:

Python
from fastapi import FastAPI, HTTPException
from dppvalidator import ValidationEngine

app = FastAPI()
engine = ValidationEngine(strict_mode=True)


@app.post("/api/v1/dpp/validate")
async def validate_dpp(dpp: dict):
    result = engine.validate(dpp)
    if not result.valid:
        raise HTTPException(status_code=422, detail=result.to_dict())
    return {"valid": True, "passport_id": dpp.get("id")}

Can I validate entire supply chains?

Yes, use deep validation to crawl linked documents:

Python
result = await engine.validate_deep(
    dpp_data,
    max_depth=3,
    follow_links=["credentialSubject.traceabilityEvents"],
    timeout=30.0,
    auth_header={"Authorization": "Bearer token..."},
)

print(f"Total documents validated: {result.total_documents}")
print(f"All valid: {result.valid}")

Can I batch validate thousands of passports?

Yes, use async batch validation:

Python
results = await engine.validate_batch(
    list_of_dpps,
    concurrency=20,
)

valid_count = sum(1 for r in results if r.valid)
print(f"Valid: {valid_count}/{len(results)}")

Can I add custom validation rules?

Yes, use the plugin system:

Python
from dppvalidator.plugins import PluginRegistry


class TextileFiberRule:
    rule_id = "TEX001"
    description = "Fiber composition must sum to 100%"
    severity = "error"

    def check(self, passport):
        violations = []
        # Your validation logic here
        return violations


registry = PluginRegistry()
registry.register_validator("textile", TextileFiberRule)

Export Questions

What export formats are supported?

  • JSON — Standard JSON output
  • JSON-LD — W3C Verifiable Credentials format
Python
from dppvalidator.exporters import JSONLDExporter

exporter = JSONLDExporter()
jsonld = exporter.export(passport)

Is the JSON-LD output compatible with VC wallets?

Yes, exported JSON-LD follows the W3C Verifiable Credentials Data Model v2 and includes proper @context for UNTP DPP vocabularies.


Compliance Questions

Does dppvalidator ensure EU ESPR compliance?

dppvalidator validates the technical structure of DPP data against UNTP standards. However, compliance is your responsibility — you must ensure your product data accurately reflects:

  • Material composition
  • Manufacturing processes
  • Environmental indicators
  • Chemical compliance (REACH)
  • Traceability information

dppvalidator catches data errors; it doesn't verify the truthfulness of claims.

What standards does dppvalidator support?

  • UNTP DPP — UN/CEFACT Digital Product Passport specification
  • W3C VC — Verifiable Credentials Data Model v2
  • JSON Schema Draft 2020-12 — For structure validation
  • GS1 — GTIN checksum validation
  • ISO — Country codes, unit codes via UNECE vocabularies

When will EU DPP requirements take effect?

  • 2027 — Textiles and apparel
  • 2027 — Batteries (separate regulation)
  • TBD — Other product categories under ESPR

Start preparing now to avoid last-minute compliance failures.


Troubleshooting

Why is JSON-LD validation slow?

JSON-LD validation requires fetching context documents from remote URLs. Enable caching:

Python
# Contexts are cached after first request
# Subsequent validations will be faster
engine = ValidationEngine(validate_jsonld=True)

For offline environments, context resolution may fail.

Why do I get "pyld not installed" warnings?

This shouldn't happen with a standard installation since pyld is a core dependency. Try reinstalling:

Bash
# Using uv (recommended)
uv sync --reinstall-package dppvalidator

# Or using pip
pip install --force-reinstall dppvalidator

How do I enable signature verification?

Signature verification is available out of the box since cryptography is a core dependency:

Python
engine = ValidationEngine(verify_signatures=True)
result = engine.validate(signed_dpp)

if result.signature_valid:
    print(f"Signed by: {result.issuer_did}")

Getting Help

For AI assistants, see llms.txt and llms-ctx.txt.