---
title: "W3C VC via OID4VCI"
description: "Receive a W3C Verifiable Credential into a Wallet API v2 wallet using OID4VCI 1.0."
stack: "Community Stack (open source) — 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/community-stack/wallet2/credential-receiving/w3c-vc
generated: 2026-10-01
---
# Receiving W3C VC Credentials via OID4VCI

This guide shows you how to receive a [W3C Verifiable Credential](https://docs.walt.id/concepts/digital-credentials/verifiable-credentials-w3c.md) (JWT-signed) into a wallet using the walt.id Wallet API v2. You'll take a credential offer — for example one created with [Issuer2](https://docs.walt.id/community-stack/issuer2/credential-issuance/w3c-vc.md) — and claim it into a wallet in a single call, then confirm it was stored.

[**W3C VC**](https://docs.walt.id/concepts/digital-credentials/verifiable-credentials-w3c.md): The W3C Verifiable Credentials data model. Here the credential is delivered as a JWT (`jwt_vc_json`).

[**OID4VCI**](https://docs.walt.id/concepts/data-exchange-protocols/openid4vci.md): The protocol used to deliver the credential from the issuer to the wallet.

**Note:**

This page follows the **pre-authorized code flow**. For the authorization-code flow and for driving each step yourself (custom UIs, deferred issuance), see [Isolated Flow](https://docs.walt.id/community-stack/wallet2/credential-receiving/isolated-flow.md).

## Prerequisites

Before you begin, ensure you have:

- **Wallet API v2 running** — Follow the [Setup](https://docs.walt.id/community-stack/wallet2/setup.md) guide. The examples use `http://localhost:7006` as the base URL (Issuer2 defaults to `7005`).
- **A wallet holding a key and a DID** — [Create a wallet](https://docs.walt.id/community-stack/wallet2/wallets.md), then [generate a key](https://docs.walt.id/community-stack/wallet2/key-management/local.md) and [create a DID](https://docs.walt.id/community-stack/wallet2/did-management.md) from it (e.g. `did:key`, `did:jwk`, or `did:web`); both become the wallet's defaults. You'll need the wallet's `walletId`.
- **A W3C VC credential offer** — For a full end-to-end run, issue one with the [Issuer2 W3C VC guide](https://docs.walt.id/community-stack/issuer2/credential-issuance/w3c-vc.md). The offer is an `openid-credential-offer://` URL.

**Error:**

A W3C VC is bound to the holder's **DID**, and the wallet signs the OID4VCI proof with a **key** — so it needs both. Without a DID the issuer can't bind the credential subject and rejects the request with `Cannot find in context: subjectDid`. (SD-JWT VC and mDL need only a key.)

---

## Receive the Credential

Hand the offer to the wallet. This single call resolves the offer, requests a token, signs a proof of possession with the wallet's default key, fetches the credential, and stores it.

**Option: CURL**

**Endpoint:** `POST /wallet/{walletId}/credentials/receive` | [API Reference](https://docs.walt.id/community-stack/wallet2/full-api-reference.md)

##### Example Request

```bash
curl -X POST http://localhost:7006/wallet/{walletId}/credentials/receive \
  -H 'Content-Type: application/json' \
  -d '{
    "offerUrl": "openid-credential-offer://?credential_offer_uri=http%3A%2F%2Flocalhost%3A7005%2Fopenid4vci%2Fcredential-offer%3Fid%3D48f1dc54-134c-4e10-b889-17f3c0a595bf"
  }'
```

**Path Parameters**

- **walletId**: _String_ (required) - The ID of the wallet that will receive the credential. Returned when you [create a wallet](https://docs.walt.id/community-stack/wallet2/wallets.md#create-a-wallet); to look up an existing one, list your wallets with `GET /wallet`.

**Body Parameters**

- **Credential offer** (required) — provide exactly one of:
    - **offerUrl**: _String_ - The OID4VCI credential offer URL, e.g. the `credentialOffer` value returned by Issuer2.
    - **offerJson**: _Object_ - The credential offer as an inline JSON object, instead of a URL.
- **txCode**: _String_ (optional) - Transaction code (PIN) if the offer requires one. Check the offer, or [resolve it first](https://docs.walt.id/community-stack/wallet2/credential-receiving/isolated-flow.md#resolve-the-offer) to see `txCodeRequired`.
- **keyId**: _String_ (optional) - Key from the wallet's key store to bind the credential to. Defaults to the wallet's default key.
- **did**: _String_ (optional) - DID for holder binding. Defaults to the wallet's default DID.
- **clientId**: _String_ (optional) - The OAuth 2.0 `client_id` the wallet presents to the issuer's authorization server. Defaults to `eudiw-abca`, which works with issuers that don't require client registration.

---

##### Example Response

```json
{
  "credentialIds": ["6ba7b810-9dad-11d1-80b4-00c04fd430c8"],
  "deferredTransactionIds": {}
}
```

**Response Fields**

- **credentialIds**: _String[]_ - Wallet-assigned IDs of the credentials that were received and stored.
- **deferredTransactionIds**: _Object_ - Map of credential configuration ID → `transaction_id`, present only when the issuer defers issuance. See [deferred issuance](https://docs.walt.id/community-stack/wallet2/credential-receiving/isolated-flow.md#deferred-credentials).

🎉 You've received a W3C VC credential into the wallet.

---

## Confirm It Was Stored

List the wallet's credentials to see the one you just received. This returns metadata only — no raw credential data.

**Option: CURL**

**Endpoint:** `GET /wallet/{walletId}/credentials` | [API Reference](https://docs.walt.id/community-stack/wallet2/full-api-reference.md)

##### Example Request

```bash
curl http://localhost:7006/wallet/{walletId}/credentials
```

**Path Parameters**

- **walletId**: _String_ (required) - The ID of the wallet whose credentials you want to list. Returned when you [create a wallet](https://docs.walt.id/community-stack/wallet2/wallets.md#create-a-wallet); to look up an existing one, list your wallets with `GET /wallet`.

---

##### Example Response

```json
[
  {
    "id": "5ea45ef4-19aa-40bc-9746-96bb9d3893ec",
    "format": "jwt_vc_json",
    "issuer": "did:jwk:eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2Ii...",
    "subject": "did:key:zDnaeyvVjxHZwnWBb8gLxnHhJLM6TcRZfyCzs35DHMGk39V4f",
    "addedAt": "2026-07-08T20:35:24.653545720Z"
  }
]
```

**Response Fields**

- **id**: _String_ - The stored credential's ID. Use it with [Credential Management](https://docs.walt.id/community-stack/wallet2/credential-management.md) to view or delete it.
- **format**: _String_ - Credential format, `jwt_vc_json` for a JWT-signed W3C VC.
- **issuer**: _String_ (optional) - Issuer identifier — here the issuer's `did:jwk`.
- **subject**: _String_ (optional) - Holder DID the credential is bound to. For a W3C VC this is your wallet's DID from the prerequisites above.
- **label**: _String_ (optional) - User-assigned label, when set.
- **addedAt**: _String_ - ISO-8601 timestamp of when the credential was stored.

Optional fields (`issuer`, `subject`, `label`) are omitted when not present.

---

## Doing It Step by Step

The full-flow call above is the fastest path. If you're building a wallet UI and need to show intermediate state — resolve the offer, preview what's being issued, prompt for a PIN, handle the authorization-code flow — drive the isolated endpoints yourself. Each step and its request/response shape is documented in [Isolated Flow](https://docs.walt.id/community-stack/wallet2/credential-receiving/isolated-flow.md).

---

## Next Steps

- **Present the credential you just received** — Try [Presenting W3C VC Credentials](https://docs.walt.id/community-stack/wallet2/credential-presenting/w3c-vc.md) to share it with [Verifier2](https://docs.walt.id/community-stack/verifier2/credential-verification/vc-oid4vp.md).
- **Receive other credential types** — [SD-JWT VC](https://docs.walt.id/community-stack/wallet2/credential-receiving/sd-jwt-vc.md) or [mDL](https://docs.walt.id/community-stack/wallet2/credential-receiving/mdl.md).
- **Manage stored credentials** — [List, view, and delete](https://docs.walt.id/community-stack/wallet2/credential-management.md) credentials in the wallet.
