Skip to content

Resolution and dereferencing

Resolving a DID means fetching its DID document: the public keys and service endpoints the identifier publishes. DID.is resolves the identifier for you and also reports what the result shows. The answer has a short verdict and seven evidence dimensions, such as key material, origin binding and verifiable history.

DID.is only reports evidence. It does not give trust scores and it does not decide who you should trust. A DID that resolves correctly can still belong to anyone.

Your applicationa DID
DID.is checks
  • DID syntax and method
  • Fetch the document safely
  • Keys are well formed
  • Domain binding and TLS
  • Verifiable history, when the method has one
Your applicationDocument + 7 dimensions
  • Syntax and method. The DID must be valid syntax and use a supported method: did:key, did:jwk, did:web or did:webvh.
  • Safe fetching. For did:web and did:webvh, the host must resolve only to public addresses (see Egress protection).
  • Document integrity. The document is JSON and its id equals the requested DID.
  • Key material. Every verification method is a well-formed key, usable for the relationships it is declared for.
  • Origin binding. For web-based DIDs, the DIF Well-Known DID Configuration of the domain is verified.
  • Transport. The TLS certificate the origin presented at resolution time.
  • Verifiable history. For did:webvh, the signed log of document versions.
  • Real-world identity. The organization dimension is always NOT_ESTABLISHED for every method. A domain name is not a legal entity.
  • Who holds the private keys. Well-formed keys say nothing about who controls them.
  • Past versions of did:web documents. did:web keeps no verifiable history, so whoever controls the web server and DNS can replace the document.

Every response repeats these limits in its limitations array.

Endpoint Returns Use it when
GET /v1/resolve/{did} Document, metadata, verdict, seven dimensions, evidence, graph, trace You want to know what the result shows.
GET /v1/fast-verify/did/{did} Compact verdict: outcome, headline, dimension states, keys, document hash Gateways and agents that need a short answer.
GET /1.0/identifiers/{did} W3C DID Resolution HTTPS binding You need a standard resolver interface.
GET /v1/dereference/{didUrl} One resource selected by a DID URL You need a single key or service.

Put the DID in the path. The SDKs percent-encode it for you. These endpoints use the standard budget (20 requests per minute); resolving a did:webvh identifier uses the intensive budget. See Errors and rate limits.

Terminal window
curl https://did.is/api/v1/resolve/did:web:did.is

Top-level fields: did, method, didDocument, didResolutionMetadata, didDocumentMetadata, verdict, dimensions, evidence, graph, trace, limitations, resolver, observedAt, cached.

Results are cached. Add ?noCache=true (SDK: noCache / no_cache) to resolve fresh.

For a shorter answer, GET /v1/fast-verify/did/{did} returns did, resolved, outcome, headline, statements, dimensions (id and state only), keys, domainBinding, documentSha256, observedAt and cached. The SDK methods are fastVerifyDid and fast_verify_did.

The verdict for did:web:did.is, abridged from a live response:

{
"verdict": {
"outcome": "RESOLVED",
"headline": "Controlled by the operator of did.is; publishes Ed25519 verification keys.",
"statements": ["Origin verified via DIF configuration.", "No verifiable history.", "Organization not established."]
},
"dimensions": [
{ "id": "integrity", "label": "Document integrity", "state": "ESTABLISHED" },
{ "id": "keys", "label": "Key material", "state": "ESTABLISHED" },
{ "id": "control", "label": "Update authority", "state": "NOT_ESTABLISHED" },
{ "id": "origin", "label": "Origin binding", "state": "ESTABLISHED" },
{ "id": "transport", "label": "Transport security", "state": "ESTABLISHED" },
{ "id": "history", "label": "Verifiable history", "state": "NOT_ESTABLISHED" },
{ "id": "organization", "label": "Real-world identity", "state": "NOT_ESTABLISHED" }
]
}

Each dimension also has statement, proves and doesNotProve lines. Read every dimension on its own; there is no total score.

verdict.outcome is RESOLVED, RESOLVED_WITH_WARNINGS (a dimension FAILED, a key is invalid, or the document has warnings) or DEACTIVATED.

Dimension state What it means What to do
ESTABLISHED DID.is found evidence for this dimension. Read proves and doesNotProve to see how far it goes.
SELF_CERTIFYING True by construction: the identifier itself encodes it (did:key, did:jwk). No outside source is involved; that is expected for these methods.
NOT_ESTABLISHED No evidence for this dimension. Often normal: did:web has no verifiable history. Decide whether your use needs it.
FAILED Evidence was found and it is wrong (for example a broken domain binding). Treat it as a problem with the identifier.
INDETERMINATE The check could not be completed. Retry later; do not read it as passed.
NOT_APPLICABLE The dimension does not apply to this method. Nothing to do.

If the DID cannot be resolved at all, you receive an RFC 9457 problem instead, such as 501 METHOD_NOT_SUPPORTED or 404 NOT_FOUND. See Errors and rate limits. Core concepts explains the verdict and dimensions in more detail.

/1.0/identifiers/{did} implements the DID Resolution v1 HTTPS binding. The Accept header selects the representation:

  • application/did-resolution: the full resolution result (didDocument, didResolutionMetadata, didDocumentMetadata).
  • application/did (or */*): the DID document only.
Terminal window
curl -H 'Accept: application/did-resolution' \
https://did.is/api/1.0/identifiers/did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK

This endpoint uses the specification’s status codes: 400 invalid DID, 404 not found, 406 representation not supported, 410 deactivated, 501 method not supported. Other errors are 500. DID URLs are dereferenced here as well.

Encode # as %23.

Terminal window
curl https://did.is/api/v1/dereference/did:web:did.is%23key-1
{
"@context": "https://w3id.org/did-resolution/v1",
"dereferencingMetadata": { "contentType": "application/json", "retrieved": "2026-10-13T09:07:34Z" },
"contentStream": {
"controller": "did:web:did.is",
"id": "did:web:did.is#key-1",
"publicKeyJwk": { "crv": "Ed25519", "kty": "OKP", "x": "7cJsq2cBTFJjHGswkemeCO-uB5vbKwFIdGWStM7ELiY" },
"type": "JsonWebKey2020"
},
"contentMetadata": {}
}

Supported selectors:

  • Fragment (%23key-1): a verification method or service.
  • ?service=<id>: a service endpoint, with an optional relativeRef. Path traversal is refused.
  • ?versionId=, ?versionTime=, ?versionNumber=: a specific did:webvh version.

DID URL paths (did:web:example.com/path) are not supported and return FEATURE_NOT_SUPPORTED.

Endpoint What it returns
GET /v1/history/{did} Snapshots DID.is recorded for this identifier, coalesced when unchanged. Observations are records, not proofs of history.
GET /v1/diff/{did}?from=&to= A semantic diff between two recorded snapshots (document hashes). Without from/to, the latest two.
GET /v1/graph/{did} The evidence graph: nodes and edges, each edge with a state.

The diff lists added, removed and rotated keys, changed relationships and services, controller and alsoKnownAs changes, and the domain binding before and after:

Terminal window
curl https://did.is/api/v1/diff/did:web:did.is
{
"did": "did:web:did.is",
"identical": true,
"keysAdded": [],
"keysRemoved": [],
"keysRotated": [],
"relationshipsChanged": [],
"servicesAdded": [],
"servicesRemoved": [],
"servicesChanged": [],
"controllerChanged": false,
"alsoKnownAsChanged": false,
"domainBindingFrom": "VERIFIED",
"domainBindingTo": "VERIFIED",
"domainBindingChanged": false,
"summary": ["documents are identical"]
}

(Abridged: the response also includes the hashes, observation times and both documents.)

  • GET /v1/claims/{did}: current proofs that a controller demonstrated control of the DID. Each claim states what it proves and what it doesNotProve. A claim is not legal identity.
  • GET /v1/directory?q=&method=&limit=&cursor=: DIDs whose controllers proved control and chose to be listed. limit is 1 to 50 (default 20); q is at most 100 characters.

The SDKs have no method for these two endpoints; call them over HTTP.

Terminal window
curl 'https://did.is/api/v1/directory?method=web&limit=5'

Search any DID on did.is to see the same result as a page. Reading a result explains each part, and Live stream shows the resolution stages as they run.