---
title: "Demo: real server-side present + verify"
method: POST
path: "/v1/presentations/{uuid}/demo-present"
tags: ["OpenID4VP Verification"]
---

# Demo: real server-side present + verify

`POST /v1/presentations/{uuid}/demo-present`

Demo / verifier-simulation endpoint (public, no API key). Server-side it issues a credential matching the request's `vct`, builds a real SD-JWT VC verifiable presentation with a fresh holder key (real KB-JWT, real nonce/aud binding), and verifies it through the full production crypto pipeline — without needing a second device or a real wallet. Used by the verifier console and the holder fallback to produce a genuine verified result. The request must have a credential template for its `vct`, and is single-use (a request that already has a result is rejected with 422). The request body is empty.

## Path parameters

- `uuid` string, uuid, required

## Request body

- object

## Response `200`

The demo presentation verified successfully (verdict `verified`). Returns the verification payload.

- object
  - `id` string, uuid — Unique identifier of the verification result record.
  - `request_id` string, uuid — UUID of the presentation request this verification answers.
  - `verdict` 'verified' | 'failed' — Outcome of verification; `verified` on a 200 response.
  - `vct` string — The Verifiable Credential Type that was requested and presented.
  - `verifier` string — The verifier audience (the request's `aud` — client_id / origin) the presentation was bound to.
  - `requested_claims` string[] — The claim names the request asked to be disclosed.
  - `disclosed_claims` object — Map of claim name to value for the claims disclosed in the presentation. In demo mode the values are synthesized as `demo-{claim_name}` for every requested claim.
  - `checks` object — Per-check boolean results of verification (all true on a verified result).
    - `signature` boolean — The issuer's signature over the SD-JWT is valid (issuer key resolved by `kid`).
    - `key_binding` boolean — The KB-JWT is present and signed by the holder key bound in `cnf` (holder possession proof).
    - `aud` boolean — The KB-JWT audience matches the request's verifier audience.
    - `nonce` boolean — The KB-JWT nonce matches the request's single-use nonce (anti-replay).
    - `alg_allowlist` boolean — Every algorithm in the presentation is on the ES256 allow-list.
    - `not_expired` boolean — The credential's `exp` is in the future.
    - `not_revoked` boolean — The credential is not revoked or suspended per its Token Status List.
  - `error` string — Empty string on a verified result.
  - `created_at` string, date-time — ISO 8601 timestamp when the verification result was recorded.

## Other responses

- `422` — The demo presentation failed verification, the request was already used, or no credential template exists for the request's `vct`. On a recorded failure the body is the verification payload with verdict `failed`; on the no-template / already-used short-circuit it is a minimal failure shape (`verdict`, `error`, empty `checks`).

## Changes

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

[Change history](https://skmtc.dev/didit-protocol/apis/didit-credentials-api/changes/v1/presentations/:uuid/demo-present/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.dev/didit-protocol/apis/didit-credentials-api/revisions/2eeb13158ffa?raw)
