Default Requests
A wallet service acts as one holder, so its presentation calls keep repeating the same thing: which key and which DID to sign with. Default requests let you save that once on your Wallet2 service, so a presentation call only carries the request URL.
Default requests are optional. Nothing on this page is required to present credentials. If your wallet holds a single key and DID, you don't need them at all: the wallet uses them automatically.
When This Is Worth It
When a call omits keyReference and didReference, the wallet uses the first key in its linked KMS and the first DID in its DID Store. With one key that is exactly what you want. It stops being reliable once the wallet holds more than one key, for example an Ed25519 key next to a P-256 key: the first one is not necessarily the one your credentials are bound to.
This matters because a credential is bound to its holder's key. Presenting with any other key fails at the verifier. A default removes the guesswork and keeps every call on the same holder identity:
- Presenting from stored credentials.
wallet2-present-credential. Only therequestUrlchanges per call. This is the case this page walks through. - Driving the isolated flow step by step. Previewing a request and building the VP token must use the same key, otherwise the two steps disagree about what the wallet can do. Store the same key as the default of
wallet2-preview-presentationandwallet2-build-vp-tokenand neither step can drift.
What Changes
Without a default, every presentation names the key and DID it should use:
{
"requestUrl": "openid4vp://authorize?client_id=...&request_uri=...",
"keyReference": "waltid.tenant1.wallet1.kms.wallet_key",
"didReference": "waltid.tenant1.wallet1.didstore.wallet_did"
}
With the key and DID stored as a default, the call becomes:
{
"requestUrl": "openid4vp://authorize?client_id=...&request_uri=..."
}
The service fills in everything you left out. Anything you do send in the call wins over the stored value.
Prerequisites
- A Wallet2 service with a KMS and a DID Store attached, holding a key and a DID. See Setup.
- A credential in the wallet. See Receiving credentials.
- A presentation request from a verifier, for example a Verifier2 session.
- A bearer token with the
update-default-requestspermission and the permission to present credentials. Both are needed to store a default.
Step 1: Store a Default
Store the holder identity with a PUT. The last part of the URL, wallet2-present-credential, names the API call the default applies to: the one behind POST /v2/{target}/wallet-service-api/credentials/present. The body is an ordinary presentation request. Leave out requestUrl, which changes on every call.
Endpoint: PUT /v2/{target}/wallet-service-api/default-requests/wallet2-present-credential | API Reference
Example Request
curl -X 'PUT' \
'https://{orgID}.enterprise-sandbox.waltid.dev/v2/{target}/wallet-service-api/default-requests/wallet2-present-credential' \
-H 'accept: application/json' \
-H 'Authorization: Bearer {yourToken}' \
-H 'Content-Type: application/json' \
-d '{
"keyReference": "waltid.tenant1.wallet1.kms.wallet_key",
"didReference": "waltid.tenant1.wallet1.didstore.wallet_did"
}'
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}.{walletServiceID}, for examplewaltid.tenant1.wallet1.
Header Parameters
- Authorization: String (required) - Bearer token. Format:
Bearer {yourToken}.
Body Parameters
- The body is a partial presentation request. It accepts the same fields as presenting a credential, and you can send any subset of them. Unknown or misspelled keys are rejected now, not later when you present. The key and DID references themselves are not checked here, see Good to Know.
Example Response 200 OK
The stored document is echoed back.
{
"keyReference": "waltid.tenant1.wallet1.kms.wallet_key",
"didReference": "waltid.tenant1.wallet1.didstore.wallet_did"
}
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: Present a Credential
Send only the request URL.
Endpoint: POST /v2/{target}/wallet-service-api/credentials/present | API Reference
Example Request
curl -X 'POST' \
'https://{orgID}.enterprise-sandbox.waltid.dev/v2/{target}/wallet-service-api/credentials/present' \
-H 'accept: application/json' \
-H 'Authorization: Bearer {yourToken}' \
-H 'Content-Type: application/json' \
-d '{
"requestUrl": "openid4vp://authorize?client_id=...&request_uri=..."
}'
Path Parameters
- orgID: String (required) - Organization host alias.
- target: resourceIdentifier (required) -
{organizationID}.{tenantID}.{walletServiceID}.
Header Parameters
- Authorization: String (required) - Bearer token. Format:
Bearer {yourToken}.
Body Parameters
- requestUrl: String (required) - The OID4VP authorization request URL from the verifier. Any other field you send overrides the stored value.
Example Response 200 OK
The response is the same as for any presentation. See Presenting SD-JWT VC Credentials for the fields.
{
"transmission_success": true,
"verifier_response": {
"status": "received",
"message": "Presentation received and is being processed."
}
}
Response Codes
200- Presentation built and submitted.400- The request could not be resolved, or the merged request is invalid, for example when the storedkeyReferencedoes not exist.401/403- Authentication or authorization failure.
Override Part of the Default
To sign with a different key for one call, send it. The rest of the default stays:
{
"requestUrl": "openid4vp://authorize?client_id=...&request_uri=...",
"keyReference": "waltid.tenant1.wallet1.kms.other_key"
}
Keep Isolated-Flow Steps on the Same Key
In the isolated flow, you preview the request and later build the VP token in separate calls. Both must use the same key. A default on each operation guarantees it.
Endpoint: PUT /v2/{target}/wallet-service-api/default-requests/wallet2-preview-presentation | API Reference
Example Request
curl -X 'PUT' \
'https://{orgID}.enterprise-sandbox.waltid.dev/v2/{target}/wallet-service-api/default-requests/wallet2-preview-presentation' \
-H 'accept: application/json' \
-H 'Authorization: Bearer {yourToken}' \
-H 'Content-Type: application/json' \
-d '{
"keyReference": "waltid.tenant1.wallet1.kms.wallet_key"
}'
Path Parameters
- orgID: String (required) - Organization host alias.
- target: resourceIdentifier (required) -
{organizationID}.{tenantID}.{walletServiceID}.
Body Parameters
- A partial preview request. Store the same
keyReferenceforwallet2-build-vp-tokenwith a secondPUTto…/default-requests/wallet2-build-vp-token.
Example Response 200 OK
{
"keyReference": "waltid.tenant1.wallet1.kms.wallet_key"
}
Response Codes
200- Default request stored.400- The document is not a valid partial body for this operation.401/403- Authentication or authorization failure.
A preview call with only requestUrl now reports the stored key as the effective keyId in its response.
Good to Know
- Receive defaults need an offer.
wallet2-receive-credentialandwallet2-receive-credential-pre-authorizedrequireofferUrlorofferJsonwhen the request is decoded, so a default that only pins the key can't be stored. ThePUTcurrently fails with500("Either offerUrl or offerJson must be provided"). SendkeyReferenceon each receive call, or rely on the wallet's first key and DID. - References are checked when you present, not when you store. A default with a key that doesn't exist is accepted with
200. The next presentation then fails with400("No key found at path …"), which looks like an error in that call rather than in the default. - The key must be the credential's holder key. A credential is bound to the key it was issued to. A default that points at another key makes the verifier reject the presentation (the key-binding signature check fails).
- Defaults are not guardrails. Anyone allowed to present can override any stored field in their own call.
- Each operation has its own default. Presenting, previewing and building a VP token are separate operations, and 24 Wallet2 operations in total accept a default. Store one for each operation you use.
- Explicit values win, including
falseover a storedtrue. Arrays and primitives are replaced wholesale.
Read or Remove a Default
- List all stored defaults:
GET /v2/{target}/wallet-service-api/default-requests(needsview-default-requests). - Read one:
GET …/default-requests/wallet2-present-credential. Returns404if none is stored. - Remove one:
DELETE …/default-requests/wallet2-present-credential. Returns204, also when nothing was stored.
Full details, permissions and the other services that support default requests: Default Requests.
