Resolution
The DID Registry exposes unauthenticated GET endpoints that serve DID documents as did.json. All patterns fan out to every DID Store linked as a dependency on the registry.
The registry does not host documents at the standard did:web HTTPS path automatically. To make https://{domain}/{path}/did.json work externally, point your reverse proxy or DNS at these Enterprise API endpoints. See External DID Web Hosting.
Deriving {id} from a DID
For did:web:waltid.enterprise.localhost:users:alice, the {id} path parameter is the colon-separated path suffix: users:alice.
Colons in {id} do not need to be percent-encoded — the server accepts them literally in the path (users:alice). Percent-encoding them (users%3Aalice) also works, if you prefer to encode on principle.
Service-targeted resolution
Resolves {id} against a specific DID Registry instance.
GET /v1/{registry-target}/did-registry-service-api/registry/{id}/did.json
curl -X GET \
'https://{orgId}.enterprise.localhost/v1/waltid.tenant1.did-registry-main/did-registry-service-api/registry/users:alice/did.json'
Path Parameters
{registry-target}— Full path of the DID Registry service, e.g.waltid.tenant1.did-registry-main{id}— Colon-separated path suffix from thedid:web
Response 200 OK
{
"@context": ["https://www.w3.org/ns/did/v1"],
"id": "did:web:waltid.enterprise.localhost:users:alice",
"verificationMethod": [ ],
"authentication": [ ]
}
Response 404 Not Found — No DID matching {id} in any linked store:
{
"message": "No DID found with id: users:alice"
}
Tenant-relative resolution
Resolves against a registry within an organization, without repeating the org ID in the path. The organization itself is resolved from the request's Host header ({orgId}).
GET /{target}/{id}/did.json
{target} names a node in the organization tree, resolved relative to the org root — what kind of node it is determines how the request resolves:
- DID Registry service (e.g.
tenant1.did-registry-main, or the full absolute pathwaltid.tenant1.did-registry-main) —{id}is resolved against it directly. - Tenant (e.g.
tenant1) — the tenant's configureddidRegistry(see Tenant-level DIDs) is used instead. The stored value is tried both as given and expanded relative to the tenant, so it resolves whetherdidRegistrywas configured as a full absolute path or as a short, tenant-relative service ID.
Both forms fan out to the same DID Stores and produce identical documents — which one you use just depends on whether you'd rather address the registry service directly or via its owning tenant.
If {target} doesn't match any node, or matches a tenant with no didRegistry configured, the request 404s (see Responses below).
# Target = registry service path
curl -X GET \
'https://{orgId}.enterprise.localhost/tenant1.did-registry-main/users:alice/did.json'
# Target = tenant ID (registry resolved via the tenant's didRegistry config)
curl -X GET \
'https://{orgId}.enterprise.localhost/tenant1/users:alice/did.json'
Path Parameters
{orgId}— Organization ID, resolved from the request host (e.g.waltidforwaltid.enterprise.localhost).{target}— Either a registry service path (relative to the org root, e.g.tenant1.did-registry-main, or absolute, e.g.waltid.tenant1.did-registry-main) or a tenant ID (e.g.tenant1) whose configureddidRegistryshould be used.{id}— Colon-separated path suffix, e.g.users:alice
Response 404 Not Found — {target} doesn't resolve to a registry service or a tenant:
{
"message": "No DID registry found at: tenant1"
}
Response 404 Not Found — {target} is a tenant with no didRegistry configured:
{
"message": "A DID registry has not been configured for this tenant"
}
Organization root resolution
The simplest form — no service path in the URL. Requires rootDidRegistry to be configured on the organization (see Setup → Step 4).
GET /{id}/did.json
curl -X GET \
'https://waltid.enterprise.localhost/users:alice/did.json'
Path Parameters
{id}— Colon-separated path suffix
Response 404 Not Found — If rootDidRegistry is not configured:
{
"message": "A root DID registry has not been installed in this organization"
}
Internally this reads organization.configuration.rootDidRegistry, loads that registry, and resolves {id}.
List registered DIDs
List all did:web identifiers across linked stores:
curl -X GET \
'https://{orgId}.enterprise.localhost/v1/waltid.tenant1.did-registry-main/did-registry-service-api/registry/list' \
-H 'Authorization: Bearer {yourToken}'
Response 200 OK
[
"did:web:waltid.enterprise.localhost:users:alice",
"did:web:waltid.enterprise.localhost:org:issuer"
]
Resolution URL summary
| Pattern | Example URL |
|---|---|
| Service-targeted | /v1/waltid.tenant1.did-registry-main/did-registry-service-api/registry/users:alice/did.json |
| Tenant-relative | /tenant1.did-registry-main/users:alice/did.json |
| Organization root | /users:alice/did.json |
Next steps
- External DID Web Hosting — Map these endpoints to a custom domain
