---
title: "Credential endpoint (holder proof-of-possession → SD-JWT VC)"
method: POST
path: "/v1/credential"
tags: ["OpenID4VCI Protocol"]
---

# Credential endpoint (holder proof-of-possession → SD-JWT VC)

`POST /v1/credential`

OpenID4VCI credential endpoint. Exchanges a Bearer access token (from POST /v1/oauth/token) plus a holder proof-of-possession JWT for the issued SD-JWT VC. Requires `Authorization: Bearer <access_token>`. The proof JWT (typ `openid4vci-proof+jwt`) carries the holder's public key and must include the `c_nonce` minted by POST /v1/nonce as its `nonce` claim and the issuer's `credential_issuer` identifier as its `aud`. On success the access token, c_nonce, and offer are all consumed (single-use), the credential is bound to the holder key, and the SD-JWT VC is returned. Returns 401 if the Authorization header is missing/not Bearer, and 400 if the proof is missing or invalid (expired token/nonce, bad signature, wrong audience, etc.).

## Request body

- object
  - `proof` object, required — The holder proof-of-possession object. Carries the JWT that proves control of the holder key the credential will be bound to.
    - `proof_type` string, required — Proof type. Must be `jwt` (the only type supported, per `proof_types_supported` in the issuer metadata).
    - `jwt` string — The proof JWT (header typ `openid4vci-proof+jwt`, signed with ES256 or EdDSA). Its payload must contain `nonce` = the `c_nonce` from POST /v1/nonce, `aud` = the issuer's `credential_issuer` identifier, and `iat`; its header carries the holder public `jwk`. Required — a missing or empty `proof.jwt` returns 400 `invalid_proof`.

## Response `200`

The issued SD-JWT VC.

- object
  - `credential` string — The issued credential as a `dc+sd-jwt` (SD-JWT VC) string: the issuer-signed JWS followed by tilde-separated selective-disclosure segments, ending in a trailing tilde — `<jws>~<disclosure>~<disclosure>~`. The holder stores this and presents it (optionally with a key-binding JWT) to verifiers.
  - `vct` string — Verifiable Credential Type of the issued credential (the schema's `vct`).

## Other responses

- `400` — Missing or invalid proof (no `proof.jwt`, expired/invalid access token, expired/consumed c_nonce, malformed proof payload, bad key binding, or wrong audience).
- `401` — Missing or non-Bearer Authorization header.

## Changes

- **2026-06-30** `1ee4908e9af4` — 1 breaking, 2 info
  - request body became required
  - added the non-success response with the status `400`
  - added the non-success response with the status `401`

[Change history](https://skmtc.dev/didit-protocol/apis/didit-credentials-api/changes/v1/credential/post.md)

---

[API](https://skmtc.dev/didit-protocol/apis/didit-credentials-api.md) · [All operations](https://skmtc.dev/didit-protocol/apis/didit-credentials-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/didit-protocol/didit-credentials-api/revisions/1ee4908e9af4/schema)
