For upcoming changes, check out the latest Work in Progress.
How to Register an Extension
This guide walks extension owners through the steps required to get a UNTP extension listed in the Credential Extensions (EXT) Register.
If you want to understand how the registry itself is governed (registrar role, agent operation, dispute and retention policy), see the Governance document. If you simply want to browse already-registered extensions, see the register itself.
Who should register
You are a candidate extension owner if your organisation is a member organisation that represents the shared interests of multiple constituent organisations and your community needs UNTP credentials with sector-specific or jurisdiction-specific extensions. Eligible owner types include:
- Industry associations
- Standards bodies
- Intergovernmental bodies
- Multi-stakeholder consortia
- Research centres acting on behalf of an industry community
Single companies are not eligible owners. Extensions exist to serve communities, not individual vendors. If your need is company-specific, use UNTP core's per-class @vocab mechanism documented in the Extensions Methodology — no registration required.
What you'll get when you're done
- An entry in the EXT Register at
https://registers.uncefact.org/untp/ext/{your-extension-slug}. - A UNECE-issued Digital Identity Anchor (DIA) credential about your owner DID, hosted on your register entry.
- Continuous, automated drift detection by the UNTP registrar agent — your published schema, context, and vocabulary are hashed on every cycle and any silent change is flagged.
- Discoverability for software vendors, conformity assessment bodies, and community activations selecting extensions to support.
Quick summary
The full process boils down to three things:
- Publish an owner DID at a domain you control (typically
did:web:yourdomain.org). - Publish your extension schema, JSON-LD context, and vocabulary at stable URIs you control. The context MUST import the UNTP context at exactly the version your extension extends.
- Issue a registration Verifiable Credential describing your extension and pointing at the schema/context/vocabulary URIs, and notify UNECE.
The registrar agent does the rest: fetches the documents, hashes them, runs UNTP extension-conformance checks (UNTP context required, all terms resolved, no UNTP redefinitions, samples validate), and writes signed observations.
Prerequisites
Before you start, you'll need:
| Item | Notes |
|---|---|
| A web domain you control | Required for did:web and for hosting your extension artefacts. |
| Ability to host static linked-data documents | JSON Schema, JSON-LD context, RDF/SKOS vocabulary, sample VCs. |
| A defined community use case | What credential type does your community need? What does it extend? |
| Familiarity with the UNTP specification | Especially the credential type your extension extends and the Extensions Methodology. |
| A representative who can liaise with UNECE | For initial onboarding and any future disputes. |
You do not need:
- A formal vote or charter from your members before registering. Registration is on intent.
- Pre-existing UNTP-conformant software for your members. The agent observes the extension itself, not its implementations.
- A complete vocabulary on day one. You can register at
proposedand progress as you publish.
Step-by-step
Step 1 — Get in touch with UNECE
Tell UNECE you intend to publish a UNTP extension. UNECE will create a proposed register entry as a placeholder while you set up your DID and develop your artefacts. There is no review or approval gate at this stage — proposals are accepted on intent.
You'll receive a placeholder DID and a slug for your extension entry; both will be replaced once you publish your real DID and registration VC.
Step 2 — Publish your owner DID
Stand up did:web:yourdomain.org (or another DID method you prefer). Your DID Document must include at least one assertionMethod verification method usable to sign Verifiable Credentials.
Notify UNECE of your DID URL. UNECE will replace the placeholder DID on your entry, and shortly after will issue a UNECE-signed DIA credential about your DID — this is the trust anchor that downstream verifiers use to confirm your extension is duly registered.
Step 3 — Identify what credential types you're defining
For each credential type your extension defines:
- Pick a
credentialTypename (e.g.DigitalBatteryPassport,LivestockDigitalProductPassport). Use PascalCase. The name becomes a class IRI under your domain and an entry in the credential'stypearray. - Identify which UNTP base credential type it extends. The choices are:
DigitalProductPassport,DigitalConformityCredential,DigitalTraceabilityEvent,DigitalFacilityRecord, orDigitalIdentityAnchor. Each registered extension MUST extend one of these (or another already-registered extension credential). - Decide which UNTP version you'll extend (e.g.
0.7.0). The extension is locked to this UNTP version until you publish a new extension version.
You can register multiple credential types under one extension entry.
Step 4 — Develop the schema, context, and vocabulary triple
For each credential type and version, publish three documents at stable URIs:
| Document | What it does | Example URI |
|---|---|---|
| JSON Schema | Defines the credential's structure (required and optional properties). | https://yourdomain.org/extensions/your-ext/0.1.0/YourCredential.schema.json |
| JSON-LD context | Maps each property name to an RDF IRI. MUST import the UNTP context at the declared version. MUST NOT redefine any UNTP term. | https://yourdomain.org/extensions/your-ext/0.1.0/your-context.jsonld |
| Vocabulary | RDF or SKOS document defining the meaning of every term your context introduces. | https://yourdomain.org/extensions/your-ext/0.1.0/your-vocabulary.ttl |
Once published, never edit a versioned URI's content. Mint a new version instead. The agent records content hashes on first observation and detects any later drift.
The context can declare an @vocab catch-all for terms that an implementer may add that are NOT defined in either your vocabulary or UNTP — but every term your extension itself uses must be properly defined in your vocabulary or context.
Step 5 — Publish at least one sample instance per credential type
For each credential type, publish at least one sample VC instance at a stable URI. Two samples per type are recommended; negative-test samples (samples that should fail validation, marked isExpectedPass: false) improve coverage.
Each sample should illustrate a real-world scenario (a typical use case for the credential). The agent fetches and validates samples on every cycle; sample-validation failures appear in your conformance observation.
Step 6 — Issue your registration VC
Sign a Verifiable Credential whose credentialSubject matches the ExtensionEntry shape (per register-schema.json) including:
- Your extension name, statement, industry sector, geographic scope.
- Your owner type (industry-association, standards-body, intergovernmental, consortium, research-centre).
- Each credential type, what it extends, and the schema/context/vocabulary URIs.
- Sample URIs and metadata.
- Optional co-owners (for jointly governed extensions).
Host the VC at a stable URI you control (e.g. https://yourdomain.org/.well-known/untp/ext/registration-vc.json). Notify UNECE of the URI.
Step 7 — First observation
The registrar agent fetches your registration VC, verifies the signature, fetches your schema/context/vocabulary documents, hashes them, and runs the conformance checks. If everything passes and you have at least one sample per credential type, status moves to pilot.
You can ask UNECE for a faster-than-cyclical first observation; otherwise it runs at the next scheduled cycle (typically within a week).
What gets verified
These are the conformance checks the agent runs on every cycle. Pass these and your status holds.
| Check | What you need to do to pass |
|---|---|
| Registration VC signature valid | Keep your DID Document's verification methods current; re-sign and re-publish your VC after any key rotation. |
| Schema hash match | Treat published schema documents as immutable. Edits = new versions, never overwrites. |
| Context hash match | Same for context documents. |
| Vocabulary hash match | Same for vocabulary documents. |
| UNTP context required | Your extension context must import the UNTP context at exactly the extendsUntpVersion you declared. |
| Extension context defined | You must publish your own context document (you can't only reuse the UNTP context). |
| All terms resolved | Every property in your schema must resolve to a definition either via your context/vocabulary or via UNTP's. |
| No UNTP redefinitions | Your context must not redefine any term defined in the UNTP context. |
@vocab catch-all scope | If you declare @vocab, it must only catch terms outside both your vocabulary and the UNTP vocabulary. |
| Samples validate | Each isExpectedPass: true sample must validate against your schema; each isExpectedPass: false sample must fail as declared. |
A small failure (e.g. one sample issue) yields partially-conformant. A fatal failure (signature, hash, redefinition, term resolution) yields non-conformant. The agent records exactly which checks failed.
After registration: the lifecycle
After your initial registration:
- The agent re-fetches your published documents on every cycle (typically weekly).
- Drift in your published documents (changes to a hash, broken term references, etc.) is detected automatically and surfaces as observation failures.
- Your status reflects the latest observation — no human review or re-submission is required.
Maintaining your registration
Publishing a new extension version
A version in this register is the unit at which schemas, hashes, and observations are tracked. To publish a new version of one of your credential types:
- Mint a new
versionLabel(e.g.0.2.0). Use SemVer or a calendar scheme — your choice, just be consistent. - Mint a new stable URI for each new schema/context/vocabulary document. Do not edit the previous version's documents. Old implementers must continue to resolve the old hashes.
- Decide whether the new version still extends the same UNTP version. If you're upgrading to a new UNTP core version, set
extendsUntpVersionaccordingly and re-test against the new core context. - Update samples for the new version (or document explicitly that the old samples remain valid).
- Re-issue your registration VC with the new version appended to the
versions[]array. Keep prior versions in the array — the register is append-only. - Notify UNECE if you want a faster-than-cyclical update; otherwise the next cycle picks it up.
The agent treats each version independently: an old version remaining conformant does not depend on the new version passing.
Rotating keys
If you need to rotate the signing key your DID controls:
- Update your DID Document's verification methods.
- Re-sign your registration VC with the new key.
- Re-publish the VC at the same URI.
The agent re-verifies the registration VC on every cycle. There is a brief window where an in-flight observation may fail signature validation; the next cycle will succeed.
Withdrawing
You may exit at any time. Tell UNECE; your entry is marked withdrawn. Historical observations are retained for audit. Your published schema/context/vocabulary URIs should remain reachable for a reasonable transition period to avoid breaking historical credentials that reference them.
Disputes
If you disagree with an observation about your extension:
- Fetch the
registrarAttestationlinked from the observation. It points to a signed VC the agent issued, with all check details. - If you can demonstrate the check was incorrect (e.g. transient fetch failure, clock-skew issue, misinterpretation of a conformance rule), file a dispute with UNECE.
- UNECE re-runs the relevant validation independently. If your dispute is upheld, the observation is amended; the original is retained, marked retracted, and the new observation links back to it.
- If the disagreement concerns interpretation of a conformance rule (rather than the data), the change goes through the formal change-control process described in the Governance document.
Common questions
What if my industry doesn't already have a UNTP extension? You're a candidate to create one if you represent the shared interests of multiple member organisations. Get in touch with UNECE; the Community Activation Program is a structured path for industry associations leading new extensions.
Can my extension extend another community's extension?
Yes. The schema permits an ExtensionCredential whose extends URI points at another registered extension credential rather than a UNTP core type. The rdfs:subPropertyOf rdfs:subClassOf relationship makes inheritance transitive.
Two communities want to define the same credential type. Who wins?
Both can register. The disambiguation is by extension context URI, not by credentialType name alone. Verifiers resolve types via the credential's @context array. We recommend communities check the existing register before defining a new credential type and prefer convergence where possible.
Is there a fee? There is likely to be a minimal registration fee that is used to maintain register integrity on a non-for-profit basis. The actual fee structure will be determined before UNTP version 1.0 release.
What happens if the UNTP core version I extend gets superseded?
Your existing extension version remains valid against the UNTP version it was registered under. To support a new UNTP core version, mint a new extension version with extendsUntpVersion set to the new core version.
Do I need to publish my schema as machine-readable JSON Schema? Yes. The agent validates samples against the schema; samples are how the schema gets exercised. A free-text specification document doesn't satisfy the conformance checks.
Where to get help
- The Extensions Methodology: https://untp.unece.org/docs/tools-and-support/ExtensionsMethodology
- Sample registered extensions: see the register itself
- Direct contact: raise an issue on the UNTP specification repository, or reach out via the UNTP mailing list or UNTP slack channel (join via the links on the home page).