Default Requests
If you create many DIDs on the same domain, most of each request is the same: the DID type, the domain, and the service endpoints in the DID Document. Default requests let you save that shared part once on your DID service, so each creation only carries what is unique to the DID.
Default requests are optional. Nothing on this page is required to create DIDs. Use it once you notice you are repeating the same did:web settings.
When This Is Worth It
Default requests pay off when a service creates many DIDs that share a setup and differ in a few fields. For the DID service that means:
did:webDIDs on one domain. Onboarding users under your domain. Thetype,domainand DID Document extras (such as aLinkedDomainsservice entry that ties the DID to your website) are the same every time. The key, the path and the DID ID are different every time. This is the case this page walks through.- A
did:keyformat convention.did:keyhas one real option,useJwkJcsPub, which changes the format of the identifier. If your ecosystem needs one format everywhere, pin it once.
Two operations are a poor fit:
did:jwkhas nothing to pin besides the key itself, and the key is different per DID.- Keys and paths. These identify the DID. A
did:keyand adid:jwkare derived from the key, and adid:webis derived from the domain and path. Storing them makes every DID the same DID (see Good to Know).
What Changes
Without a default, every did:web creation carries the full body:
{
"type": "single_key_reference",
"domain": "did.example.com",
"serviceConfigurationSet": [
{
"type": "LinkedDomains",
"serviceEndpoint": ["https://did.example.com"]
}
],
"keyReference": "waltid.tenant1.kms1.alice-key",
"path": "tenant1/alice",
"didId": "alice"
}
With the first three fields stored as a default, the call becomes:
{
"keyReference": "waltid.tenant1.kms1.alice-key",
"path": "tenant1/alice",
"didId": "alice"
}
The service fills in everything you left out. Anything you do send in the call wins over the stored value.
Prerequisites
- A DID service with a KMS attached. See Setup and Using KMS for DID Creation.
- Optional: a DID store attached, if you want the created DIDs persisted under their
didId. - A bearer token with the
update-default-requestspermission and the permission to create the DID type you are setting a default for. Both are needed to store a default.
Step 1: Store a Default
Store the shared settings with a PUT. The last part of the URL, create-did-web, names the API call the default applies to: the one behind POST /v1/{target}/did-service-api/dids/create/web. The body is an ordinary did:web creation request. Leave out every field that changes per DID, and always include type.
Endpoint: PUT /v1/{target}/did-service-api/dids/default-requests/create-did-web | API Reference
Example Request
curl -X 'PUT' \
'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/did-service-api/dids/default-requests/create-did-web' \
-H 'accept: application/json' \
-H 'Authorization: Bearer {yourToken}' \
-H 'Content-Type: application/json' \
-d '{
"type": "single_key_reference",
"domain": "did.example.com",
"serviceConfigurationSet": [
{
"type": "LinkedDomains",
"serviceEndpoint": ["https://did.example.com"]
}
]
}'
Path Parameters
- orgID: String (required) - Organization host alias. For the sandbox organization
test, the base URL ishttps://test.enterprise-sandbox.waltid.dev. - target: resourceIdentifier (required) -
{organizationID}.{tenantID}.{didServiceID}, for examplewaltid.tenant1.did1.
Header Parameters
- Authorization: String (required) - Bearer token. Format:
Bearer {yourToken}.
Body Parameters
- The body is a partial
did:webcreation request. It accepts the same fields as creating a did:web, and you can send a subset of them.typeis required, because it selects the request shape; a body without it is rejected with400. Unknown or misspelled keys are rejected now, not later when a DID is created. Missing values such asdomainor the key are not checked until you create a DID.
Example Response 200 OK
The stored document is echoed back.
{
"type": "single_key_reference",
"domain": "did.example.com",
"serviceConfigurationSet": [
{
"type": "LinkedDomains",
"serviceEndpoint": ["https://did.example.com"]
}
]
}
Response Codes
200- Default request stored.400- The document is not a valid partial body for this operation.401/403- Authentication or authorization failure.update-default-requestsand the operation's own permission are both required.404- Service not found, or the operation name is unknown.
Step 2: Create a DID
Send only what is specific to this DID: its key, its path and its ID.
Endpoint: POST /v1/{target}/did-service-api/dids/create/web | API Reference
Example Request
curl -X 'POST' \
'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/did-service-api/dids/create/web' \
-H 'accept: application/json' \
-H 'Authorization: Bearer {yourToken}' \
-H 'Content-Type: application/json' \
-d '{
"keyReference": "waltid.tenant1.kms1.alice-key",
"path": "tenant1/alice",
"didId": "alice"
}'
Path Parameters
- orgID: String (required) - Organization host alias.
- target: resourceIdentifier (required) -
{organizationID}.{tenantID}.{didServiceID}.
Header Parameters
- Authorization: String (required) - Bearer token. Format:
Bearer {yourToken}.
Body Parameters
- Any field you send overrides the stored value. The key (
keyReferenceorkey) is always needed, either in the default or in the call.
Example Response 201 Created
The DID is created on the stored domain, and its DID Document carries the stored LinkedDomains service entry. See Create a did:web for the full response.
{
"id": "waltid.tenant1.did-store1.alice",
"did": "did:web:did.example.com:tenant1:alice",
"document": {
"id": "did:web:did.example.com:tenant1:alice",
"verificationMethod": [ ... ],
"service": [
{
"id": "did:web:did.example.com:tenant1:alice#...",
"type": "LinkedDomains",
"serviceEndpoint": "https://did.example.com"
}
]
}
}
Response Codes
201- DID created.400- The merged request is not a valid creation request, for example when neither the default nor the call provides a key.401/403- Authentication or authorization failure.
Override Part of the Default
To change one thing, send only that. This request creates a DID on another domain and keeps the stored type and service entry:
{
"keyReference": "waltid.tenant1.kms1.bob-key",
"domain": "other.example.org",
"path": "bob",
"didId": "bob-other"
}
Pin the did:key Format
did:key creation has one option worth pinning, useJwkJcsPub. It defaults to true, which produces the jwk_jcs-pub form (did:key:z2dm…). Set it to false to produce the classic multibase form (did:key:zDna… for a P-256 key) on every creation.
Endpoint: PUT /v1/{target}/did-service-api/dids/default-requests/create-did-key | API Reference
Example Request
curl -X 'PUT' \
'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/did-service-api/dids/default-requests/create-did-key' \
-H 'accept: application/json' \
-H 'Authorization: Bearer {yourToken}' \
-H 'Content-Type: application/json' \
-d '{
"useJwkJcsPub": false
}'
Path Parameters
- orgID: String (required) - Organization host alias.
- target: resourceIdentifier (required) -
{organizationID}.{tenantID}.{didServiceID}.
Body Parameters
- A partial
did:keycreation request. Unlikedid:web, it has notypefield.
Example Response 200 OK
{
"useJwkJcsPub": false
}
Response Codes
200- Default request stored.400- The document is not a valid partial body for this operation.401/403- Authentication or authorization failure.
Later POST …/dids/create/key calls only need keyReference and, if you store the DID, a didId.
Good to Know
- Never store the key, the path or the
didId. A DID is defined by them. Storing apathmakes every DIDdid:web:…:{path}, and storing a key makes everydid:keyordid:jwkidentical. The calls still succeed, each with201, and the DID store ends up with several records for the same DID. - A stored key field follows you into other shapes. If the default holds
keyReferenceand a call switches totype: "key_reference_set", the merged request contains bothkeyReferenceandkeyReferenceSetand fails with400(unknown key). Store only the fields that every caller's shape has in common. - Same key, same
did:key. Creating adid:keyfrom one key twice yields the same identifier, whateverdidIdyou use. - Defaults are not guardrails. Anyone allowed to create DIDs can override any stored field in their own call.
- Each operation has its own default.
create-did-web,create-did-keyandcreate-did-jwkare separate. - Explicit values win, including
falseover a storedtrue. Arrays and primitives are replaced wholesale, so a call that sendsserviceConfigurationSetreplaces the stored list.
Read or Remove a Default
- List all stored defaults:
GET /v1/{target}/did-service-api/dids/default-requests(needsview-default-requests). - Read one:
GET …/default-requests/create-did-web. Returns404if none is stored. - Remove one:
DELETE …/default-requests/create-did-web. Returns204, also when nothing was stored.
Full details, permissions and the other services that support default requests: Default Requests.
