> ## Documentation Index
> Fetch the complete documentation index at: https://docs.openpayload.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Resolve a DID

> Discover the public keys, services, devices, aliases, and status associated with an OpenPayload identity

Resolving a DID means asking a Directory for the identity's current public record. This is usually the first call a compatible client makes before it encrypts a message, verifies a signature, selects a service endpoint, or displays identity information.

An OpenPayload DID has three parts:

```text theme={null}
did:openpayload:1111111111111111111111
│   │       └─ unique Base58 identifier
│   └───────── platform or network name
└───────────── decentralized identifier scheme
```

The canonical form is `did:<platform>:<Base58Address>`. The platform is 1–32 lowercase ASCII letters or digits. The Base58 address is 16–96 characters. `openpayload` is the default platform name rather than a hard-coded requirement.

Send the complete identifier. The response can contain public cryptographic keys and network endpoints, but never a private key.

<Info>
  This is a safe, read-only request. You do not need an account, signature, nonce, or OpenPayload SDK.
</Info>

## When to use this endpoint

Resolve a DID when your application needs to:

* Find a recipient's key-agreement key before encrypting a message
* Find a Relay, Cache, or Archive service declared by the identity
* Verify a signature using a public verification method
* Check whether a device has been tombstoned
* Display a public alias
* Detect a deactivated identity or a newer record version

## Request

<ParamField path="did" type="string" required>
  The complete canonical DID. URL-encode it in the path.
</ParamField>

<RequestExample>
  ```bash Request theme={null}
  curl --request GET \
    --url "https://directory.example.com/resolve/did%3Aopenpayload%3A1111111111111111111111"
  ```
</RequestExample>

### Example in plain JavaScript

```javascript theme={null}
const did = "did:openpayload:1111111111111111111111";
const directory = "https://directory.example.com";

const response = await fetch(`${directory}/resolve/${encodeURIComponent(did)}`);

if (!response.ok) {
  throw new Error(`Directory returned HTTP ${response.status}`);
}

const record = await response.json();
console.log(record.document);
```

## Response

<ResponseField name="owner" type="string | null">
  The public chain account that owns the record, when one exists. DIDs registered through a Directory are ownerless; records created directly on chain may have an account owner.
</ResponseField>

<ResponseField name="aliases" type="string[] | null">
  Public aliases assigned to the DID. Do not assume there is only one.
</ResponseField>

<ResponseField name="devices" type="object[] | null">
  Registered devices. Each item contains `deviceId`, `addedAt`, and `tombstoned`.
</ResponseField>

<ResponseField name="version" type="number" required>
  The public record version.
</ResponseField>

<ResponseField name="document" type="object | null">
  The public DID document, including verification, key-agreement, authentication, and service entries.
</ResponseField>

<ResponseField name="updatedAt" type="number" required>
  The update time as Unix milliseconds.
</ResponseField>

<ResponseField name="freshness" type="string | null">
  A label indicating where the Directory obtained the result, when available.
</ResponseField>

<ResponseField name="registration_status" type="string" required>
  The public registration state.
</ResponseField>

<ResponseField name="root_pubkey" type="string">
  The 32-byte public root key encoded as `0x`-prefixed hexadecimal, when available.
</ResponseField>

<ResponseField name="deactivated" type="boolean" required>
  `true` when the identity has been permanently deactivated.
</ResponseField>

<ResponseField name="tx_id" type="string">
  The registration transaction identifier, when available.
</ResponseField>

<ResponseField name="document_nonce" type="string">
  The current DID-document authorization nonce when document mutation state is available.
</ResponseField>

<ResponseField name="pending_document_nonce" type="string">
  The nonce reserved by a pending DID-document mutation.
</ResponseField>

<ResponseField name="pending_document_action" type="boolean">
  `true` when a DID-document mutation is awaiting confirmation.
</ResponseField>

<ResponseField name="pending_document_action_name" type="string">
  The operation name for a pending DID-document mutation.
</ResponseField>

<ResponseField name="pending_extrinsic_hash" type="string">
  The transaction hash for a pending DID-document mutation.
</ResponseField>

<ResponseField name="pending_document_submitted_at" type="string">
  The submission time for a pending DID-document mutation.
</ResponseField>

<ResponseExample>
  ```json 200 Response theme={null}
  {
    "owner": null,
    "aliases": ["river.stone"],
    "devices": [
      {
        "deviceId": "mobile-01",
        "addedAt": 1784910600000,
        "tombstoned": false
      }
    ],
    "version": 3,
    "document": {
      "id": "did:openpayload:1111111111111111111111",
      "verificationMethod": [
        {
          "id": "did:openpayload:1111111111111111111111#keys-1",
          "type": "Ed25519VerificationKey2020",
          "controller": "did:openpayload:1111111111111111111111",
          "publicKeyMultibase": "z<ed25519-public-key>"
        }
      ],
      "authentication": [
        "did:openpayload:1111111111111111111111#keys-1"
      ],
      "keyAgreement": [
        {
          "id": "did:openpayload:1111111111111111111111#x25519-1",
          "type": "X25519KeyAgreementKey2020",
          "controller": "did:openpayload:1111111111111111111111",
          "publicKeyMultibase": "z<x25519-public-key>"
        }
      ],
      "service": [
        {
          "id": "did:openpayload:1111111111111111111111#relay",
          "type": "OpenPayloadRelayService",
          "serviceEndpoint": ["https://relay.example.com"]
        },
        {
          "id": "did:openpayload:1111111111111111111111#cache",
          "type": "OpenPayloadCacheService",
          "serviceEndpoint": ["https://cache.example.com"],
          "authorization": [
            "did:openpayload:1111111111111111111111#keys-1"
          ]
        }
      ]
    },
    "updatedAt": 1784236800000,
    "freshness": "chain",
    "root_pubkey": "0x<64-hex-characters>",
    "deactivated": false,
    "registration_status": "confirmed"
  }
  ```
</ResponseExample>

<Note>
  `200` returns the record. `404` means the DID was not found. `425` means registration is awaiting confirmation.
</Note>

<Note>
  Account-owned DID operations remain available directly on chain. The Directory registers ownerless DIDs and submits later changes using authorized DID-key proofs.
</Note>

## How to interpret the result safely

* Treat `null` as “not available,” not as an empty public key or service.
* Reject or warn before messaging when `deactivated` is `true`.
* Ignore devices whose `tombstoned` value is `true`.
* Select keys by their full DID URL, purpose, and type. Do not blindly use the first array item.
* Expect new optional public fields in future versions.

## Straight to the point

```http theme={null}
GET /resolve/{url-encoded-did}
```

* Authentication: none
* Request body: none
* Success: `200 OK`
* Not found: `404`
* Registration pending: `425`
* Primary result: the current public `document`, `aliases`, `devices`, and lifecycle status

<Card title="New to DIDs?" icon="circle-question" href="/concepts/what-is-a-did">
  Read the complete beginner's explanation of DID structure, keys, services, and common uses.
</Card>

<Card title="Complete messaging DID document" icon="file-code" href="/concepts/complete-did-document">
  See how verification and encryption keys work with Relay, Cache, Archive, and Cache-authorization service entries.
</Card>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.