---
title: "Isolated Flow"
description: "Drive OID4VCI 1.0 issuance step by step — isolated endpoints, the authorization-code grant, and deferred issuance — with the Enterprise Wallet2 Service."
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/credential-receiving/isolated-flow
generated: 2026-10-01
---
# Isolated Flow

The [full-flow](https://docs.walt.id/enterprise-stack/services/wallet2-service/credential-receiving/overview.md#two-ways-to-receive) endpoint (`credentials/receive`) runs the whole exchange in one call. The **isolated flow** lets you drive each step yourself when you need to:

- Build a custom wallet UI with consent screens and PIN prompts
- Use the **authorization-code grant** (browser redirect)
- Handle **deferred issuance**
- Inspect intermediate results, or manage keys/credentials externally

[Resolve Offer](#step-1-resolve-offer) returns a **consent-oriented** preview — issuer branding and per-offer credential details — so UIs can show what will be issued before accepting. Accepting still re-sends the offer URL (the resolve step is stateless).

All endpoints live under `/v2/{target}/wallet-service-api/`.

## Holder Key & DID

Every receive flow signs a **proof of possession** to prove the wallet controls the holder key. You can let the wallet use its defaults, reference stored material, or pass material inline:

| Field | Type | Description |
|---|---|---|
| `keyReference` | String | Full resource path of a key in a linked KMS, e.g. `waltid.tenant1.kms.wallet_key`. Referenced keys stay in the KMS, so backends whose keys never leave the KMS (PKCS#11, HSM) work in this flow. |
| `key` | Object | Inline serialized key (`{ "type": "jwk", "jwk": { … } }`). Takes precedence over `keyReference`. |
| `did` | String | DID to use as the holder identity, e.g. `did:jwk:…`. Resolved against a linked DID Store or used inline. |
| `didReference` | String | Full resource path of a DID in a linked DID Store, e.g. `waltid.tenant1.didstore.wallet-did`. An alternative to `did` — when provided, the wallet resolves the DID from the store by this reference. Returns an error if the referenced DID does not exist. |

All of these are **optional** — if omitted, the wallet uses its configured default key and DID.

---

## Pre-Authorized Code Flow

Drive the pre-authorized code grant one step at a time:

```text
1. Resolve Offer   →  2. Request Token  →  2b. Get Nonce  →  3. Sign Proof  →  4. Fetch Credential
```

For the authorization-code grant (browser redirect, user login), see [Authorization-Code Grant](#authorization-code-grant) below — it reuses Get Nonce, Sign Proof, and Fetch Credential from this flow.

### Step 1 — Resolve Offer

Parse the offer URL and resolve the issuer metadata in one call. Returns a consent-oriented preview (issuer branding and offered-credential details). No server-side offer handle is retained — complete issuance with the pre-authorized or authorization-code endpoints using the original offer (and any PIN).

**Option: CURL**

Endpoint: `POST /v2/{target}/wallet-service-api/credentials/receive/resolve-offer`

**Example Request**

```bash
curl -X POST \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v2/{org}.{tenant}.{wallet-id}/wallet-service-api/credentials/receive/resolve-offer' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "offerUrl": "openid-credential-offer://?credential_offer_uri=https%3A%2F%2Fissuer.example.org%2Fcredential-offer%3Fid%3Dabc123"
}'
```

**Body Parameters**

- **Credential offer** (required) — provide exactly one of:
    - `offerUrl` _String_ — The OID4VCI offer URL.
    - `offerJson` _Object_ — Raw credential offer JSON, instead of a URL.

**Example Response**

```json
{
  "credentialIssuer": "https://issuer.example.org",
  "credentialConfigurationIds": ["UniversityDegree_jwt_vc_json"],
  "grantType": "pre-authorized_code",
  "preAuthorizedCode": "SplxlOBeZQQYbYS6WxSbIA",
  "txCodeRequired": false,
  "credentialEndpoint": "https://issuer.example.org/credential",
  "tokenEndpoint": "https://auth.example.org/token",
  "nonceEndpoint": "https://issuer.example.org/nonce",
  "issuer": {
    "credentialIssuer": "https://issuer.example.org",
    "display": {
      "name": "Example University",
      "locale": "en-US",
      "logoUri": "https://issuer.example.org/logo.png",
      "logoAltText": "Example University"
    }
  },
  "offeredCredentials": [
    {
      "configurationId": "UniversityDegree_jwt_vc_json",
      "format": "jwt_vc_json",
      "scope": null,
      "vct": null,
      "doctype": null,
      "display": {
        "name": "University Degree",
        "locale": "en-US",
        "description": "Bachelor of Science"
      },
      "claims": []
    }
  ],
  "transactionCode": null
}
```

**Note:**

  **Breaking change:** `offeredCredentials` is now an array of offer-detail objects, not a list of configuration ID strings. Use **`credentialConfigurationIds`** (or `offeredCredentials[].configurationId`) whenever you need the flat ID list.

- `credentialIssuer` — Issuer identifier from the offer.
- `credentialConfigurationIds` — Flat list of credential configuration IDs listed in the offer.
- `grantType` — `pre-authorized_code` or `authorization_code`.
- `preAuthorizedCode` (optional) — The pre-authorized code from the credential offer, returned when the offer uses the pre-authorized code grant.
- `txCodeRequired` — Whether a transaction code (PIN) is required for the pre-authorized grant.
- `credentialEndpoint` — Where to POST the credential request in Step 4.
- `tokenEndpoint` (optional) — The token endpoint from the issuer's authorization-server metadata.
- `nonceEndpoint` (optional) — The issuer's nonce endpoint for `c_nonce` flows (OID4VCI 1.0).
- `issuer` — Issuer metadata projection for consent UIs (`credentialIssuer`, optional localized `display`).
- `offeredCredentials` — Per-configuration offer details for the UI (not strings): `configurationId`, `format`, optional `scope` / `vct` / `doctype`, `display`, and `claims` (`path`, `mandatory`, `displayName`).
- `transactionCode` (optional) — UI hints for collecting a transaction code when required (`inputMode`, optional `length`, optional `description`). Distinct from the PIN value you send later as `txCode`.

**Response Codes**

- `200` — Offer resolved.
- `400` — Offer could not be resolved.

### Step 2 — Request Token

Exchange a pre-authorized code for an access token.

**Option: CURL**

Endpoint: `POST /v2/{target}/wallet-service-api/credentials/receive/request-token`

**Example Request**

```bash
curl -X POST \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v2/{org}.{tenant}.{wallet-id}/wallet-service-api/credentials/receive/request-token' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "tokenEndpoint": "https://auth.example.org/token",
  "preAuthorizedCode": "SplxlOBeZQQYbYS6WxSbIA",
  "credentialIssuer": "https://issuer.example.org",
  "txCode": "493536"
}'
```

**Body Parameters**

- `tokenEndpoint` _String_ — The authorization server's token endpoint.
- `preAuthorizedCode` _String_ — The pre-authorized code from the offer.
- `credentialIssuer` (optional) _String_ — Credential issuer base URL. When supplied, Enterprise resolves authorization-server metadata and can apply client-attestation headers if a client attester is linked.
- `txCode` (optional) _String_ — Transaction code (PIN), if the offer requires one.
- `clientId` (optional) _String_ — Defaults to `wallet-client`. If one client attester service is linked and the issuer supports attestation-based client authentication, Enterprise uses the wallet resource path as the effective client ID.
- `redirectUri` (optional) _String_ — Defaults to `openid://`.
- `tokenRequestHeaders` (optional) _Object_ — Additional headers to attach to the token request, such as `OAuth-Client-Attestation` and `OAuth-Client-Attestation-PoP`.
- `anonymousPreAuthorizedCode` (optional) _Boolean_ — Request an anonymous pre-authorized-code token exchange when the issuer supports it. Defaults to `false`.

**Example Response**

```json
{
  "accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expiresIn": 300
}
```

- `accessToken` — Bearer token for the credential request in Step 4.
- `cNonce` (optional) — Proof nonce, **if** the issuer returns one in the token response. Under OID4VCI 1.0 the issuer (including Issuer2) instead exposes a dedicated **Nonce Endpoint**, so `cNonce` is usually absent here — fetch the nonce in [Step 2b](#step-2b-get-a-nonce) instead.

**Response Codes**

- `200` — Token issued.
- `400` — Invalid or expired pre-authorized code.

**Note:**

Under OID4VCI 1.0 the proof nonce (`c_nonce`) comes from the issuer's **Nonce Endpoint**, not the token response, so `request-token` typically returns no `cNonce`. Get it via [Step 2b](#step-2b-get-a-nonce) before signing the proof.

### Step 2b — Get a Nonce

Under OID4VCI 1.0 the proof `c_nonce` comes from the issuer's dedicated **Nonce Endpoint**, not the token response. The wallet does not proxy this — call the **issuer's** nonce endpoint directly. Its URL is returned as **`nonceEndpoint`** from [Step 1 — Resolve Offer](#step-1-resolve-offer) when the issuer publishes one (otherwise use the `nonce_endpoint` from the issuer's credential-issuer metadata; for [Issuer2](https://docs.walt.id/enterprise-stack/services/issuer2-service/overview.md) it is `{credentialIssuer}/nonce`).

**Option: CURL**

Endpoint: `POST {credentialIssuer}/nonce` — this is the **issuer's** endpoint, not a wallet endpoint.

**Example Request**

```bash
curl -X POST 'https://issuer.example.org/nonce'
```

**Example Response**

```json
{
  "c_nonce": "wKI4LT5Sadf6a0dyih5b0Ws"
}
```

Use the returned `c_nonce` as the `nonce` in [Step 3](#step-3-sign-proof).

**Response Codes**

- `200` — Nonce issued.

### Step 3 — Sign Proof

Sign a proof of possession over the issuer's `c_nonce` to prove control of the holder key.

**Option: CURL**

Endpoint: `POST /v2/{target}/wallet-service-api/credentials/receive/sign-proof`

**Example Request**

```bash
curl -X POST \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v2/{org}.{tenant}.{wallet-id}/wallet-service-api/credentials/receive/sign-proof' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "issuerUrl": "https://issuer.example.org",
  "nonce": "wKI4LT5Sadf6a0dyih5b0Ws",
  "credentialConfigurationId": "UniversityDegree_jwt_vc_json",
  "keyReference": "waltid.tenant1.kms.wallet_key",
  "did": "did:jwk:eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5Ii..."
}'
```

**Body Parameters**

- `issuerUrl` _String_ — The credential issuer identifier (used as the proof `aud`).
- `nonce` _String_ — The `c_nonce` from the [Nonce Endpoint](#step-2b-get-a-nonce) (Step 2b), or from the token response if the issuer returned one.
- `credentialConfigurationId` _String_ — The credential configuration the proof is for (required).
- `keyReference` / `key` (optional) — Holder key reference or inline key (see [Holder Key & DID](#holder-key-did)).
- `did` (optional) _String_ — Holder DID. When set, the proof binds to the DID; otherwise it binds to the raw JWK.
- `didReference` (optional) _String_ — Full resource path of a DID in a linked DID Store (`{org}.{tenant}.{didstore}.{did-id}`). An alternative to `did` — when provided, the wallet resolves the DID from the store by this reference. Returns an error if the referenced DID does not exist.

**Example Response**

```json
{
  "proofJwt": "eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dC..."
}
```

**Response Codes**

- `200` — Proof signed.
- `400` — No resolvable holder key.

### Step 4 — Fetch Credential

Request the credential from the issuer's credential endpoint using the access token and the signed proof.

**Option: CURL**

Endpoint: `POST /v2/{target}/wallet-service-api/credentials/receive/fetch-credential`

**Example Request**

```bash
curl -X POST \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v2/{org}.{tenant}.{wallet-id}/wallet-service-api/credentials/receive/fetch-credential' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "credentialEndpoint": "https://issuer.example.org/credential",
  "accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "credentialConfigurationId": "UniversityDegree_jwt_vc_json",
  "proofJwt": "eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dC...",
  "storeInWallet": true
}'
```

**Body Parameters**

- `credentialEndpoint` _String_ — The issuer's credential endpoint (from Step 1 or issuer metadata).
- `accessToken` _String_ — The access token from Step 2.
- `credentialConfigurationId` _String_ — The credential configuration being requested.
- `proofJwt` (optional) _String_ — The proof JWT from Step 3. Required when the issuer mandates key-proof.
- `clientId` (optional) _String_ — Defaults to `wallet-client`.
- `storeInWallet` (optional) _Boolean_ — Store the fetched credential(s) in the wallet's linked Credential Store. Defaults to `false`.

**Example Response**

```json
{
  "rawCredentials": [
    "eyJraWQiOiJkaWQ6a2V5Ono2TWtqb1Jo..."
  ]
}
```

- `rawCredentials` — The issued credential string(s) (JWT, SD-JWT, or base64-encoded mDoc). Set `storeInWallet` to `true` to persist them during this call. If you leave it as `false`, store a returned credential later with `POST /v2/{target}/wallet-service-api/credentials/import`, or use the [full-flow](https://docs.walt.id/enterprise-stack/services/wallet2-service/credential-receiving/overview.md#two-ways-to-receive) endpoints.

**Response Codes**

- `200` — Credential(s) fetched.
- `400` / `500` — The issuer rejected the credential request (e.g. missing or invalid proof).

---

## Authorization-Code Grant

You don't know which grant an offer uses until you resolve it — [Step 1 — Resolve Offer](#step-1-resolve-offer) above returns `grantType`, and `authorization_code` is what routes you here instead of the pre-authorized flow. The authorization-code grant then requires the user to authenticate with the issuer's authorization server via a browser redirect, so it cannot be a single blocking call:

```text
Step 1 (above) — Resolve Offer  →  grantType: "authorization_code"

Generate Authorization URL   →  redirect the user to the issuer
   ── user authenticates in the browser ──
Complete Receive             →  exchange the code, sign the proof, fetch & store the credential (single call)

   — or drive it yourself: —

Exchange Code  →  Step 2b (above) — Get Nonce  →  Step 3 (above) — Sign Proof  →  Step 4 (above) — Fetch Credential
   (Get Nonce, Sign Proof, and Fetch Credential are the same steps used by the pre-authorized flow above)
```

### Generate Authorization URL

Resolve the offer and build the authorization URL the user must be redirected to.

**Option: CURL**

Endpoint: `POST /v2/{target}/wallet-service-api/credentials/receive/authorization-url`

**Example Request**

```bash
curl -X POST \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v2/{org}.{tenant}.{wallet-id}/wallet-service-api/credentials/receive/authorization-url' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "offerUrl": "openid-credential-offer://?credential_offer_uri=https%3A%2F%2Fissuer.example.org%2Fcredential-offer%3Fid%3Dabc123",
  "redirectUri": "https://your-wallet-app.example.com/callback"
}'
```

**Body Parameters**

- **Credential offer** (required) — provide exactly one of:
    - `offerUrl` _String_ — The OID4VCI offer URL.
    - `offerJson` _Object_ — Raw credential offer JSON, instead of a URL.
- `clientId` (optional) _String_ — Defaults to `wallet-client`.
- `redirectUri` (optional) _String_ — Where the authorization server redirects the user after authentication. Defaults to `openid://`.
- `usePkce` (optional) _Boolean_ — Whether to use PKCE. Defaults to `true`.

**Example Response**

```json
{
  "authorizationUrl": "https://auth.example.org/authorize?response_type=code&client_id=wallet-client&redirect_uri=https%3A%2F%2Fyour-wallet-app.example.com%2Fcallback&scope=UniversityDegree_jwt_vc_json&issuer_state=eyJhbGciOiJSU...&code_challenge=abc123&code_challenge_method=S256",
  "state": "abc123",
  "codeVerifier": "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM",
  "credentialConfigurationId": "UniversityDegree_jwt_vc_json",
  "credentialIssuerBaseUrl": "https://issuer.example.org",
  "nonceEndpoint": "https://issuer.example.org/nonce"
}
```

- `authorizationUrl` — Redirect the user here to begin authentication.
- `state` — Returned to your `redirectUri` as a query parameter; use it to correlate the callback.
- `codeVerifier` — PKCE code verifier. **Store this securely** — the [Exchange Code](#exchange-code-isolated) step below needs it.
- `credentialConfigurationId` — The credential configuration this authorization is for.
- `credentialIssuerBaseUrl` — Credential issuer base URL. Pass it to [Exchange Code](#exchange-code-isolated).
- `nonceEndpoint` (optional) — The issuer's nonce endpoint, for [Step 2b — Get a Nonce](#step-2b-get-a-nonce) once the user returns with an authorization code.

After redirecting the user, your app receives the authorization code at `redirectUri`: `?code={authorizationCode}&state={state}`.

**Response Codes**

- `200` — Authorization URL generated.
- `400` — Offer could not be resolved, or the issuer has no authorization endpoint.

### Exchange Code (Isolated)

Exchange the authorization code obtained above for an access token. This is the isolated alternative to [Complete Receive](#complete-receive-combined-alternative) below — after this, continue with [Step 2b — Get a Nonce](#step-2b-get-a-nonce), [Step 3 — Sign Proof](#step-3-sign-proof), and [Step 4 — Fetch Credential](#step-4-fetch-credential) from the pre-authorized flow above; they're identical for both grant types.

**Option: CURL**

Endpoint: `POST /v2/{target}/wallet-service-api/credentials/receive/exchange-code`

**Example Request**

```bash
curl -X POST \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v2/{org}.{tenant}.{wallet-id}/wallet-service-api/credentials/receive/exchange-code' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "code": "SplxlOBeZQQYbYS6WxSbIA",
  "credentialIssuerBaseUrl": "https://issuer.example.org",
  "codeVerifier": "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"
}'
```

**Body Parameters**

- `code` _String_ — The authorization code from the redirect callback.
- `credentialIssuerBaseUrl` _String_ — Credential issuer base URL returned by [Generate Authorization URL](#generate-authorization-url). Enterprise uses it to resolve authorization-server metadata, including the token endpoint.
- `codeVerifier` (optional) _String_ — The PKCE code verifier saved from the authorization-url step.
- `clientId` (optional) _String_ — Defaults to `wallet-client`. If one client attester service is linked and the issuer supports attestation-based client authentication, Enterprise uses the wallet resource path as the effective client ID.
- `redirectUri` (optional) _String_ — Must match the redirect URI used earlier. Defaults to `openid://`.
- `tokenRequestHeaders` (optional) _Object_ — Additional headers to attach to the token request.

**Example Response**

Same structure as [Step 2 — Request Token](#step-2-request-token) in the pre-authorized flow.

**Response Codes**

- `200` — Token issued.
- `400` — Invalid authorization code or PKCE verifier.

### Complete Receive (Combined Alternative)

The simpler alternative to driving Exchange Code, Get Nonce, Sign Proof, and Fetch Credential yourself once the user is back with an authorization code: exchange the code for a token, sign the proof, fetch the credential, and store it — in one call.

**Option: CURL**

Endpoint: `POST /v2/{target}/wallet-service-api/credentials/receive/authorized`

**Example Request**

```bash
curl -X POST \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v2/{org}.{tenant}.{wallet-id}/wallet-service-api/credentials/receive/authorized' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "code": "SplxlOBeZQQYbYS6WxSbIA",
  "codeVerifier": "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM",
  "credentialIssuer": "https://issuer.example.org",
  "credentialEndpoint": "https://issuer.example.org/credential",
  "nonceEndpoint": "https://issuer.example.org/nonce",
  "credentialConfigurationId": "UniversityDegree_jwt_vc_json",
  "keyReference": "waltid.tenant1.kms.wallet_key",
  "did": "did:jwk:eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5Ii..."
}'
```

**Body Parameters**

- `code` _String_ — The authorization code received at your `redirectUri`.
- `codeVerifier` (optional) _String_ — The PKCE code verifier saved from Step 1. Required if PKCE was used.
- `credentialIssuer` _String_ — The credential issuer identifier.
- `credentialEndpoint` _String_ — The issuer's credential endpoint (from its metadata).
- `credentialConfigurationId` _String_ — The credential configuration being requested.
- `nonceEndpoint` (optional in the request schema, but effectively required for Issuer2) _String_ — The issuer's nonce endpoint — for Issuer2 this is `{credentialIssuer}/nonce`. Under OID4VCI 1.0 the token response typically carries no `c_nonce` (same as [Step 2b](#step-2b-get-a-nonce)), so if you omit `nonceEndpoint` **and** the issuer doesn't return a `c_nonce`, this call fails with a `500`.
- `keyReference` (optional) _String_ — Resource path of a holder key in one of the wallet's linked KMS stores (e.g. `waltid.tenant1.kms.wallet_key`). Referenced keys are used through their KMS-backed signer, so they work with KMS backends whose keys never leave the KMS (e.g. PKCS#11, HSM). Ignored when `key` is provided.
- `key` (optional) _Object_ — Inline serialized holder key. Takes precedence over `keyReference`.
- `did` (optional) _String_ — Holder DID.
- `didReference` (optional) _String_ — Full resource path of a DID in a linked DID Store (`{org}.{tenant}.{didstore}.{did-id}`). An alternative to `did` — when provided, the wallet resolves the DID from the store by this reference. Returns an error if the referenced DID does not exist.
- `clientId` (optional) _String_ — Defaults to `wallet-client`. If one client attester service is linked and the issuer supports attestation-based client authentication, Enterprise uses the wallet resource path as the effective client ID.
- `redirectUri` (optional) _String_ — Must match the `redirectUri` used in Step 1. Defaults to `openid://`.

**Example Response**

```json
{
  "credentialIds": [
    "f58ac347-0728-45c6-ba59-bde9d3343aa6"
  ],
  "deferredTransactionIds": {}
}
```

**Response Codes**

- `200` — Credential(s) received and stored.
- `400` — Invalid authorization code, or the issuer rejected the request.
- `500` — The issuer provided no `c_nonce` and no `nonceEndpoint` was supplied to fetch one.

---

## Deferred Issuance

If the issuer defers a credential, the full-flow (or `authorized`) response returns its `transaction_id` under `deferredTransactionIds`. Poll the issuer's deferred credential endpoint until the credential becomes available.

**Option: CURL**

Endpoint: `POST /v2/{target}/wallet-service-api/credentials/receive/deferred`

**Example Request**

```bash
curl -X POST \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v2/{org}.{tenant}.{wallet-id}/wallet-service-api/credentials/receive/deferred' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "deferredCredentialEndpoint": "https://issuer.example.org/credential_deferred",
  "transactionId": "8xLOxBtZp8",
  "accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}'
```

**Body Parameters**

- `deferredCredentialEndpoint` _String_ — The deferred credential endpoint from the issuer's metadata.
- `transactionId` _String_ — The `transaction_id` returned under `deferredTransactionIds`.
- `accessToken` _String_ — The access token from the original token response.

**Example Response**

```json
{
  "credentialIds": [
    "f58ac347-0728-45c6-ba59-bde9d3343aa6"
  ],
  "deferredTransactionIds": {}
}
```

If the credential is not yet ready, `credentialIds` is empty — retry later.

**Response Codes**

- `200` — Poll completed (credential stored, or not yet ready).
- `400` / `500` — The issuer rejected the deferred request.

---

## Next Steps

- **Receive with the full flow** — the per-format guides ([SD-JWT VC](https://docs.walt.id/enterprise-stack/services/wallet2-service/credential-receiving/sd-jwt-vc.md), [W3C VC](https://docs.walt.id/enterprise-stack/services/wallet2-service/credential-receiving/w3c-vc.md), [mDL](https://docs.walt.id/enterprise-stack/services/wallet2-service/credential-receiving/mdl.md)) use the single-call `credentials/receive` endpoint.
- **Manage stored credentials** — [list and retrieve](https://docs.walt.id/enterprise-stack/services/wallet2-service/management.md) credentials in the wallet.
- **Present a credential** — [Credential Presenting](https://docs.walt.id/enterprise-stack/services/wallet2-service/credential-presenting/overview.md).
