# Create your first hosted DID

> Register your WebVH Hosting appliance with your VTA, create a did:webvh identifier on it, and resolve it at its public URL.

By the end of this guide, your VTA is connected to your WebVH Hosting appliance, and you have a live did:webvh identifier that anyone can resolve at its public URL.

## Prerequisites

- An active WebVH Hosting appliance. See [Deploy WebVH Hosting appliance](/products/affinidi-elements/webvh-hosting/get-started/webvh-affinidi-portal.md) if you haven’t set one up yet.

- The appliance’s Server DID:

- Affinidi-hosted: the Server DID on the configuration’s details page in Affinidi Portal.

- Self-hosted: server_did in the service’s configuration file.

- The domain your DIDs will use:

- Affinidi-hosted: the host of the WebVH URL on the configuration card in Affinidi Portal.

- Self-hosted: the host of public_url in the service’s configuration file.

- PNM connected to the VTA you linked to the appliance, and your VTA’s slug to hand:

- Affinidi-hosted VTA: the VTA slug printed by pnm bootstrap connect. See [Deploy VTA appliance](/products/affinidi-elements/vta/get-started/vta-affinidi-portal.md).

- Self-hosted VTA: the slug printed by pnm setup. See [Self-hosted (open source)](/products/affinidi-elements/vta/get-started/self-hosted.md).

- Super-admin access to the VTA, which creating a context requires.

- Self-hosted only: an entry for your VTA’s DID in the server’s own ACL. A unified daemon set up in VTA-managed mode adds it automatically. Otherwise, add it with did-hosting-daemon add-acl --did <vta-did> --role admin on a unified daemon, or did-hosting-control add-acl --did <vta-did> --role admin on standalone services.

## Steps

Register the appliance with your VTA

Give the appliance a short local ID, so later commands can refer to it with --server:

```bash
pnm --vta  did-mgmt servers add \
    --id    my-webvh \
    --did    \
    --label "My WebVH Hosting appliance"
```

Replace <server-did> with the appliance’s Server DID. You register an appliance once per VTA.

Create a context for your application

Create a [context](/products/affinidi-elements/webvh-hosting/get-started/glossary.md#core-concepts) to hold this application’s keys:

```bash
pnm --vta  contexts create \
    --id   my-app \
    --name "My App"
```

Create the DID

```bash
pnm --vta  did-mgmt dids create \
    --context my-app \
    --server  my-webvh \
    --path    my-service
```

Your VTA generates the keys, signs the DID’s first log entry, and publishes it to the appliance. Expected output (abridged):

```text
WebVH DID created:
  DID:              did:webvh:Q1abc…:did.example.com:my-service
  Context:          my-app
  Server:           my-webvh
  SCID:             Q1abc…
```

The DID ends with your appliance’s domain and the path you chose. See [how each part of the DID maps to its URL](/products/affinidi-elements/webvh-hosting/overview.md#how-a-hosted-did-maps-to-its-url).

You now have a live, publicly resolvable did:webvh identifier, backed by keys that stay in your VTA.

## Confirm

### Test 1: dids list shows the new DID

```bash
pnm --vta  did-mgmt dids list --context my-app
```

Expected output: a table row with the new DID, context my-app, and server my-webvh.

### Test 2: request for the DID’s log returns it

Replace did.example.com with the host of your appliance’s WebVH URL:

```bash
curl -s "https://did.example.com/my-service/did.jsonl"
```

Expected output: one line of JSON, the DID’s signed first log entry. Anyone can fetch and verify this log without credentials.

## Troubleshooting

| Symptom | Likely cause | Fix |
| Error: not found: webvh server not found: my-webvh | The --server value does not match the ID from Step 1. | Run pnm --vta <vta-slug> did-mgmt servers list and use the registered ID. |
| Error: forbidden: … from contexts create | Creating a context needs super-admin access to the VTA. | Ask a VTA super admin to create the context and give your DID the admin role in it. |
| Error: forbidden: … from dids create | Your DID is not an admin of the context. | Run pnm --vta <vta-slug> acl list --context my-app and confirm your DID has the admin role. |
| webvh path already taken on the hosting server | Another DID already uses that path on the appliance. | Choose a different --path, or omit it to have one generated. |
| curl returns 404 | The request host is not your appliance’s domain, or the path differs from the DID. | Use the host and path from the DID printed in Step 3. |

## Next steps

- [Give a DID a human-readable name](/products/affinidi-elements/webvh-hosting/webvh-management/agent-names.md): make the DID reachable at /@name.

- [Create and manage DIDs](/products/affinidi-elements/webvh-hosting/webvh-management/did-management.md): update, inspect, and delete DIDs.

- [Glossary](/products/affinidi-elements/webvh-hosting/get-started/glossary.md): terms used across these pages and in pnm output.
