> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.adid.dev/llms.txt.
> For full documentation content, see https://docs.adid.dev/llms-full.txt.

# Create a Verifiable Presentation

##### When to use

A verifier has asked you for a presentation — typically by sharing a Proof Request URL/QR (see [§5.2](#proof-request-builder)). You want to compile one or more of your VCs into a signed VP and submit it.

##### Before you begin

* The verifier's Proof Request (a Presentation Definition per DIF [Presentation Exchange v2](https://identity.foundation/presentation-exchange/spec/v2.0.0/)).
* The VCs that satisfy the request.

##### Steps

1. Open the Proof Request (URL or QR scan in the wallet).
2. The portal/wallet matches the request against your held VCs and shows you which credentials would satisfy each input descriptor.
   3\. Approve. The portal calls `POST /api/v1/presentations/create` (`vc.go:316`).
3. The API:
   * Fetches the named VCs.
   * Constructs a VP envelope.
   * Signs the VP with your DID's authentication key.
   * Returns the VP JSON.
4. The portal/wallet then submits the VP to the verifier (typically via `POST /api/v1/presentations/verify` on the verifier's side, or a callback URL specified in the Proof Request).

##### API & SDK

<table>
  <tr>
    <th>cURL</th>

    <th>TypeScript SDK</th>
  </tr>

  <tr>
    <td>
      ```bash
      curl -X POST https://adid.dev/api/v1/presentations/create \
        -H "Authorization: Bearer $ACCESS_TOKEN" \
        -H "Content-Type: application/json" \
        -d '{
          "holderDid":"did:adi:0x9a2c...",
          "credentialIds":["urn:uuid:c5b7e3..."],
          "challenge":"verifier-nonce-abc",
          "domain":"verifier.example.com"
        }'
      ```
    </td>

    <td>
      ```ts
      const vp = await client.createPresentation({
        holderDid: 'did:adi:0x9a2c...',
        credentialIds: ['urn:uuid:c5b7e3...'],
        challenge: 'verifier-nonce-abc',
        domain: 'verifier.example.com',
      });
      ```
    </td>
  </tr>
</table>

Response (truncated):

```json
{
  "verifiablePresentation": {
    "@context":["https://www.w3.org/ns/credentials/v2"],
    "type":["VerifiablePresentation"],
    "holder":"did:adi:0x9a2c...",
    "verifiableCredential":[ { ... } ],
    "proof":{ "type":"Ed25519Signature2020", "challenge":"verifier-nonce-abc", "domain":"verifier.example.com", "proofValue":"z3..." }
  }
}
```

##### Verify

The verifier's portal will show "Presentation received → verifying..." and within \~1 s display the verdict. You should see a matching record in your own `/presentations/history` (if surfaced — currently part of [§5.4 Verification History](#verification-history) for the verifier side).

##### Troubleshooting

| Code                                    | Cause                                           | Fix                                           |
| --------------------------------------- | ----------------------------------------------- | --------------------------------------------- |
| `400 NO_MATCHING_CREDENTIAL`            | None of your VCs satisfy the request            | Acquire the missing credential first.         |
| `403 NOT_HOLDER`                        | The VC's `credentialSubject.id` is not your DID | You cannot present someone else's credential. |
| `409 PRESENTATION_REJECTED_BY_VERIFIER` | Verifier policy rejected the VP                 | See response body for `reasons[]`.            |

#### 3.2.5. Checking a Credential's Revocation Status ##### When to use

You hold a credential and want to confirm it has not been revoked. The status check is also performed automatically every time you open a credential's detail page.

##### Before you begin

You have a credential ID.

##### Steps (manual)

```bash
curl https://adid.dev/api/v1/credentials/urn:uuid:c5b7e3.../status
```

(No auth needed — this endpoint is public, registered at `router.go:68`.)

Response:

```json
{
  "credentialId":"urn:uuid:c5b7e3...",
  "revoked": false,
  "statusListId":"abcd",
  "statusListIndex": 42,
  "checkedAt":"2026-04-26T12:00:00Z"
}
```

##### How it works under the hood

The handler reads the bit at the credential's `statusListIndex` from the **RevocationRegistry** contract. Bit `1` = revoked, bit `0` = active. See [§4.4.3](#status-list-mechanics) for the bitstring encoding.

##### Troubleshooting

| Code                       | Cause                                              | Fix                    |
| -------------------------- | -------------------------------------------------- | ---------------------- |
| `404 CREDENTIAL_NOT_FOUND` | Credential never existed or was deleted from index | Confirm credential ID. |
| `502 CHAIN_UNREACHABLE`    | RPC down                                           | Retry.                 |