> For the complete documentation index, see [llms.txt](https://docs.empe.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.empe.io/develop/wallet-server/faq.md).

# FAQ

Short answers to common questions about the Wallet Server. For full details, see the linked pages elsewhere in this section.

## Why use a server-side cloud wallet when mobile wallets exist?

Automation. A cloud wallet lets CI pipelines, backend scripts, and AI agents run the same OpenID4VCI issuance and OpenID4VP presentation flows that a person would run in a phone wallet — without a human scanning QR codes. The flows stay standards-compliant, so a credential claimed or presented by a server-side holder is interoperable with mobile wallets. Use a mobile wallet when an end user holds their own credentials on their device; use a server-side holder when a service or agent needs to hold and use credentials programmatically.

## How does multi-tenancy work?

Each cloud wallet is a **holder** — a per-user tenant identified by a `holderId`. A holder is created for an authenticated OIDC user via `POST /agent/holder`, and that user can list their own holders with `GET /agent/holders`. Every holder operation lives under `/holders/:holderId` and is guarded by ownership: a user can only process URIs and read credentials for holders they created. Requests to these routes require a valid Bearer token with the **admin** role.

```
Authorization: Bearer <token>
```

## How does a holder get a credential?

By processing a credential-offer URI — a single call:

**POST** `/holders/:holderId/process`

```json
{ "uri": "openid-credential-offer://?credential_offer_uri=..." }
```

The holder resolves the offer, requests the offered credential(s), binds them to the holder's DID, and stores them. The response reports how many were stored:

```json
{ "status": "success", "claimed": 1, "ids": ["<record-id>"] }
```

Credentials are never uploaded as raw JSON; they are always acquired through the offer flow.

## How does the wallet present a credential?

You pass the verifier's authorization-request URI to the **same** `/holders/:holderId/process` endpoint:

```json
{ "uri": "openid4vp://?request_uri=..." }
```

There is no separate confirmation step and you do not pass the credential yourself. The holder resolves the request, automatically selects a matching credential from its store (using DIF Presentation Exchange or DCQL, whichever the request uses), and sends the presentation:

```json
{ "status": "success", "action": "presentation_sent" }
```

The endpoint dispatches on the URI scheme, so `openid-credential-offer://` claims a credential while `openid4vp://` (or an `https://` authorization request) presents one.

## How do I list a holder's stored credentials?

Two endpoints, both scoped to one holder:

* **GET** `/holders/:holderId/credentials` — raw, encoded credentials: `[{ id, format, credential }]`.
* **GET** `/holders/:holderId/credentials/decoded` — decoded payloads: `[{ id, format, decoded, error? }]`.

Both endpoints return every credential the holder currently stores; there is no filtering.

## Which DID methods and credential formats are supported?

A holder is provisioned with a **`did:key`** (a self-contained Ed25519 identifier, no hosting required) or a **`did:web`** (whose document the service hosts over HTTPS). The supported credential formats are **SD-JWT VC** (`sd-jwt-vc` / `vc+sd-jwt`) and **JWT-VC-JSON** (`jwt_vc_json`). A holder can additionally store JSON-LD VC, W3C v2 (`vc+jwt` / `vc+sd-jwt`), and mdoc credentials it receives. (When listing stored credentials, the holder reports SD-JWT VCs with the media type `dc+sd-jwt`.)

## Can I use did:web without owning a domain?

For production you must control the domain you supply, because the DID document is published under that hostname and other parties resolve it there. The identifier is built as `did:web:<domain>:<uuid>` and served at `/<uuid>/did.json` (also at `/<uuid>/.well-known/did.json`), so the DID encodes the host you choose. The host comes strictly from the `domain` field of the holder-creation request — you must supply it, and creating a `did:web` holder without it fails. For local testing you can point a hostname at the service (for example via your hosts file or port forwarding) and pass that hostname as the `domain` field when you create the holder (`POST /agent/holder` with `{ "method": "web", "domain": "<your-host>" }`); the DID will encode that host. If you do not control any domain, create the holder with `method: "key"` instead — `did:key` needs no hosting.

## Does the service create did:empe or anchor DIDs on a blockchain?

No. The EMPE DID method (`did:empe`) and the EMPE blockchain are separate parts of the wider Empeiria ecosystem. The Wallet Server does not create or anchor `did:empe` identifiers; its holders use `did:key` and `did:web`, and the service serves their DID documents itself over HTTPS.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.empe.io/develop/wallet-server/faq.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
