Who this is for: Technical implementers and trust architects working on registry-based assurance, digital product labelling, decentralised identifiers, or system-wide traceability in trade, ESG, and supply chain ecosystems.
Pyx Identity Resolver: What’s changed since v1.0
Since its launch in May 2025, the Pyx Identity Resolver (IDR) has moved rapidly from early deployment into real-world use. It has been embedded in the UNTP reference implementation and deployed across UNTP-aligned pilot environments and production trade scenarios. And we’ve continued to refine and iterate on it.
Its evolution reflects changes in the UN Transparency Protocol (UNTP). It also reflects what we’ve learned from implementing UNTP-aligned architecture in production.
The core idea hasn’t changed: You don’t need to standardise every system to make them interoperable. What you do need is a reliable way to resolve identifiers across them.
That is why the Pyx IDR was developed.
Earlier versions already supported flexible identifier resolution, including anonymous resolution, authenticated write access, containerised deployment, and alignment with standards such as ISO18975, GS1 Digital Link and RFC 9264.
But running it in practice surfaced real-world challenges:
- Multiple identifier schemes coexisting
- Frequent updates to claims and metadata
- Different access rights for different actors
- The need to track history, not just current state
Since v1.0, the Pyx IDR has evolved to handle that reality. This post looks at what’s changed.
If you need an explainer on what an identity resolver is and how the Pyx IDR fits into UNTP architecture, start here: https://kb.pyx.io/docs/Development/idresolver
What’s changed and why it matters
Let’s walk through the updates from a developer and implementer perspective.
1. Update links without rebuilding everything or losing data
Previously, updating links (references to external data sources) meant re-sending all links associated with that identifier in a single request. Because updates replaced the full set, any link not included in the request could be unintentionally removed.
Each link is now treated as its own first-class object:
- Individually created, updated, or deleted
- Assigned a unique identifier
- Tracked with full version history
- Removed cleanly from resolution responses when inactive
Why it matters
Real-world systems don’t update in bulk. They change incrementally. Rebuilding entire records just to fix one link doesn’t scale.
Managing links individually makes the resolver usable in live environments, not just controlled scenarios.
2. See what changed and when with built-in versioning
Every link now carries a unique ID, version number and version history.
Changes don’t overwrite previous states. They create traceable lineage, including predecessor-version references.
Why it matters
Traceability isn’t just about “what is true now”.
You often need to show what was true at a specific point in time, especially for compliance, audit, and verification.
3. Control what data is shared with different actors across UNTP-aligned workflows
The resolver now supports UNTP concepts directly:
- UNTP link types alongside GS1 vocabularies
- Role-based access to data (e.g. consumer, verifier, auditor)
- Linkset extensions and version references
- Forwarding of decryption keys for protected data
Why it matters
Different actors need different views of the same underlying data.
The resolver now supports controlled disclosure, enabling verifiable claims without exposing everything.
4. Avoid ambiguity and integration errors with validated, structured link types
Link types must follow a defined prefix:key format (e.g. gs1:pip, untp:dpp) and match recognised vocabularies.
Free-form strings are no longer accepted.
Currently supported vocabularies are:
- GS1
- UNTP
Why it matters
Consistency matters for interoperability.
Structured, validated link types make it easier for systems to understand and act on the data they receive.
5. More easily discover and integrate with link types
Link types are now grouped by vocabulary, rather than returned as a single flat list.
The resolver also publishes a stable description at:
/.well-known/resolver
This explicitly defines supported vocabularies and remains consistent across deployments.
Why it matters
Systems need to reliably discover and interpret available link types.
Grouping vocabularies and stabilising resolver behaviour reduces ambiguity and simplifies integration.
6. Work with real-world data relationships without flattening them
The resolver now builds link responses dynamically from active data at request time, reflecting how related data actually exists across systems.
It also supports:
- Relationships between identifiers (e.g. product → batch → facility)
- Structured link headers
- Controlled response sizes
Why it matters
Identifiers don’t exist in isolation.
The resolver better reflects how data actually exists across systems, rather than flattening relationships.
7. Implement the resolver with less complexity
Field naming and requirements have been simplified (with backward compatibility), reducing setup friction especially for non-GS1 identifiers. Documentation has also been reworked with clearer structure and versioned migration guides.
Why it matters
Adoption depends on usability.
Reducing friction makes it easier to implement the resolver across different contexts and identifier schemes.
8. Run and operate the resolver with more reliability and visibility
The resolver now includes:
- Better error handling and logging (e.g. storage-layer failures)
- More consistent build and release processes
- Automated changelog generation
Why it matters
Production systems need to be observable and reliable.
These changes make it easier to run and maintain the resolver in real-world environments.
Technical notes (for implementers)
The following details are relevant for teams integrating or operating the resolver and reflect the current behaviour in v3.0.1:
-
Versioned API paths
All endpoints are versioned under
/api/2.0.0/...to support stable integrations over time without breaking existing implementations. -
Duplicate detection logic
Link uniqueness is determined using a composite of:
targetUrl,linkType,mimeType,ianaLanguage, andcontext.This allows valid variations of links that would previously have been blocked, enabling multiple legitimate representations of the same identifier without unintended conflicts.
-
Link management endpoints
Links can be managed individually via
/resolver/linksendpoints, including update, soft delete, and hard delete operations, without needing to resubmit the full identifier record. -
Resolution behaviour
Link responses are built at request time from active links, rather than pre-rendered documents.
-
Link headers
Responses include structured link headers (e.g.
owl:sameAs, linksets, target links) with a controlled size budget, ensuring responses remain predictable and within practical limits for consuming systems. -
Query parameters
?accessRole=filters responses by role?decryptionKey=forwards keys for protected resources
-
Vocabulary endpoints
/voc?show=linktypesreturns link types grouped by vocabulary, with optional filtering by prefix, making it easier to identify and work with the relevant link types for a given integration. -
Resolver description
/.well-known/resolverexposes supported vocabularies and capabilities consistently across deployments, so integrations don’t need to infer capabilities from configuration.
What this evolution shows
The shift from v1.0 to v3.0.1 is not just about adding features.
It reflects a move from:
- static link resolution → to dynamic, versioned data
- flat structures → to structured, interoperable systems
- single-use implementations → to scalable, production-ready infrastructure
This is what happens when trust architecture moves from concept to practice.
Try it
The Pyx Identity Resolver is open source and available now:
- Docs: https://pyx-industries.github.io/pyx-identity-resolver/
- Container:
docker pull ghcr.io/pyx-industries/pyx-identity-resolver:3.0.1
Discuss it
If you’re working on UNTP-aligned implementations, registry design, or cross-system traceability:
- How are you handling identifier resolution across systems?
- Where are access control and data ownership becoming blockers?
- What breaks when you try to scale beyond a single platform?
Join the conversation:
👉 https://chat.pyx.io/#narrow/stream/25-Community---UNTP-Topics/topic/Pyx.20Identity.20Resolver