---
title: "Default Requests"
description: "Store the holder key and DID your wallet uses once so each presentation only sends the request URL."
stack: "Enterprise Stack (commercial) — version 1.1.1"
stack_version: "1.1.1"
stack_comparison: https://docs.walt.id/community-vs-enterprise.md
canonical_url: https://docs.walt.id/enterprise-stack/services/wallet2-service/default-requests
generated: 2026-10-01
---
# 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.

**Note:**

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 the `requestUrl` changes 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-presentation` and `wallet2-build-vp-token` and neither step can drift.

## What Changes

Without a default, every presentation names the key and DID it should use:

```json
{
  "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:

```json
{
  "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](https://docs.walt.id/enterprise-stack/services/wallet2-service/setup.md).
- A credential in the wallet. See [Receiving credentials](https://docs.walt.id/enterprise-stack/services/wallet2-service/credential-receiving/overview.md).
- A presentation request from a verifier, for example a [Verifier2](https://docs.walt.id/enterprise-stack/services/verifier2-service/overview.md) session.
- A bearer token with the `update-default-requests` permission 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.

**Option: CURL**

**Endpoint:** `PUT /v2/{target}/wallet-service-api/default-requests/wallet2-present-credential` | [API Reference](https://enterprise.sandbox.walt.id/swagger/index.html)

##### Example Request

```bash
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 is `https://test.enterprise-sandbox.waltid.dev`.
- **target**: _resourceIdentifier_ (required) - `{organizationID}.{tenantID}.{walletServiceID}`, for example `waltid.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](https://docs.walt.id/enterprise-stack/services/wallet2-service/credential-presenting/sd-jwt-vc.md), 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](#good-to-know).

##### Example Response `200 OK`

The stored document is echoed back.

```json
{
  "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-requests` and 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.

**Option: CURL**

**Endpoint:** `POST /v2/{target}/wallet-service-api/credentials/present` | [API Reference](https://enterprise.sandbox.walt.id/swagger/index.html)

##### Example Request

```bash
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](https://docs.walt.id/enterprise-stack/services/wallet2-service/credential-presenting/sd-jwt-vc.md) for the fields.

```json
{
  "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 stored `keyReference` does 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:

```json
{
  "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](https://docs.walt.id/enterprise-stack/services/wallet2-service/credential-presenting/isolated-flow.md), 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.

**Option: CURL**

**Endpoint:** `PUT /v2/{target}/wallet-service-api/default-requests/wallet2-preview-presentation` | [API Reference](https://enterprise.sandbox.walt.id/swagger/index.html)

##### Example Request

```bash
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 `keyReference` for `wallet2-build-vp-token` with a second `PUT` to `…/default-requests/wallet2-build-vp-token`.

##### Example Response `200 OK`

```json
{
  "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-credential` and `wallet2-receive-credential-pre-authorized` require `offerUrl` or `offerJson` when the request is decoded, so a default that only pins the key can't be stored. The `PUT` currently fails with `500` ("Either offerUrl or offerJson must be provided"). Send `keyReference` on 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 with `400` ("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 `false` over a stored `true`. Arrays and primitives are replaced wholesale.

## Read or Remove a Default

- List all stored defaults: `GET /v2/{target}/wallet-service-api/default-requests` (needs `view-default-requests`).
- Read one: `GET …/default-requests/wallet2-present-credential`. Returns `404` if none is stored.
- Remove one: `DELETE …/default-requests/wallet2-present-credential`. Returns `204`, also when nothing was stored.

Full details, permissions and the other services that support default requests: [Default Requests](https://docs.walt.id/enterprise-stack/administration/services/configuration/default-requests.md).
