> ## Documentation Index
> Fetch the complete documentation index at: https://docs.grantex.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Credentials

> Retrieve, verify, and present W3C Verifiable Credentials and SD-JWT selective disclosures.

## Overview

The `credentials` client manages W3C Verifiable Credentials and SD-JWT selective disclosures. Retrieve individual credentials, list with filters, verify credential JWTs, and create selective-disclosure presentations.

Access the credentials client via `client.credentials`.

## Get

Retrieve a single Verifiable Credential by its ID.

```python theme={null}
from grantex import Grantex

with Grantex(api_key="gx_live_...") as client:
    vc = client.credentials.get("vc_01HXYZ...")

    print(f"ID: {vc.id}")
    print(f"Type: {vc.type}")
    print(f"Issuer: {vc.issuer}")
    print(f"Subject: {vc.subject}")
    print(f"Status: {vc.status}")
    print(f"Issued: {vc.issuance_date}")
```

### Parameters

| Parameter       | Type  | Required | Description                       |
| --------------- | ----- | -------- | --------------------------------- |
| `credential_id` | `str` | Yes      | The unique credential identifier. |

### VerifiableCredential

| Field             | Type              | Description                                                  |
| ----------------- | ----------------- | ------------------------------------------------------------ |
| `id`              | `str`             | Unique credential identifier.                                |
| `type`            | `tuple[str, ...]` | Credential types (always includes `'VerifiableCredential'`). |
| `issuer`          | `str`             | DID of the credential issuer.                                |
| `subject`         | `str`             | DID of the credential subject (the holder).                  |
| `issuance_date`   | `str`             | ISO 8601 timestamp when the credential was issued.           |
| `expiration_date` | `str \| None`     | ISO 8601 expiration timestamp, or `None` if no expiry.       |
| `status`          | `str`             | Current status: `'active'`, `'revoked'`, or `'expired'`.     |
| `jwt`             | `str`             | The credential in compact JWT format.                        |
| `claims`          | `dict[str, Any]`  | The credential subject claims.                               |

## List

List Verifiable Credentials with optional filters.

```python theme={null}
from grantex import Grantex, ListCredentialsParams

with Grantex(api_key="gx_live_...") as client:
    result = client.credentials.list(ListCredentialsParams(
        principal_id="user_abc123",
        type="IdentityCredential",
        status="active",
        page=1,
        page_size=20,
    ))

    print(f"Total: {result.total}")
    for vc in result.credentials:
        print(f"  {vc.id}: {vc.type}")
```

### ListCredentialsParams

| Parameter      | Type          | Required | Description                                               |
| -------------- | ------------- | -------- | --------------------------------------------------------- |
| `principal_id` | `str \| None` | No       | Filter credentials by principal (subject) ID.             |
| `type`         | `str \| None` | No       | Filter by credential type (e.g., `'IdentityCredential'`). |
| `status`       | `str \| None` | No       | Filter by status: `'active'`, `'revoked'`, `'expired'`.   |
| `page`         | `int \| None` | No       | Page number for pagination (default: 1).                  |
| `page_size`    | `int \| None` | No       | Results per page (default: 20, max: 100).                 |

### ListCredentialsResponse

| Field         | Type                         | Description                            |
| ------------- | ---------------------------- | -------------------------------------- |
| `credentials` | `list[VerifiableCredential]` | List of Verifiable Credential objects. |
| `total`       | `int`                        | Total number of matching credentials.  |

## Verify

Verify a Verifiable Credential JWT. Checks signature, expiration, revocation status, and issuer trust chain.

```python theme={null}
from grantex import Grantex

with Grantex(api_key="gx_live_...") as client:
    result = client.credentials.verify("eyJhbGciOiJFUzI1NiIs...")

    if result.valid:
        print(f"Issuer: {result.issuer}")
        print(f"Subject: {result.subject}")
        print(f"Claims: {result.claims}")
        print(f"Expires at: {result.expires_at}")
    else:
        print(f"Invalid: {result.reason}")
```

### Parameters

| Parameter | Type  | Required | Description                                      |
| --------- | ----- | -------- | ------------------------------------------------ |
| `vc_jwt`  | `str` | Yes      | The Verifiable Credential in compact JWT format. |

### VerifyCredentialResponse

| Field        | Type                     | Description                                                                                   |
| ------------ | ------------------------ | --------------------------------------------------------------------------------------------- |
| `valid`      | `bool`                   | Whether the credential is valid.                                                              |
| `issuer`     | `str \| None`            | DID of the issuer (present when valid).                                                       |
| `subject`    | `str \| None`            | DID of the subject (present when valid).                                                      |
| `claims`     | `dict[str, Any] \| None` | Credential subject claims (present when valid).                                               |
| `expires_at` | `str \| None`            | ISO 8601 expiration timestamp.                                                                |
| `reason`     | `str \| None`            | Reason for invalidity: `'expired'`, `'revoked'`, `'invalid_signature'`, `'untrusted_issuer'`. |

## Present

Create a selective-disclosure presentation from an SD-JWT. Only the specified claims are disclosed.

```python theme={null}
from grantex import Grantex, PresentCredentialParams

with Grantex(api_key="gx_live_...") as client:
    presentation = client.credentials.present(PresentCredentialParams(
        sd_jwt="eyJ0eXAiOiJ2YytzZC1qd3QiLC...",
        disclosed_claims=["name", "email"],
        audience="did:web:verifier.example.com",
        nonce="unique-request-nonce",
    ))

    print(f"Presentation JWT: {presentation.presentation_jwt}")
    print(f"Disclosed: {presentation.disclosed_claims}")
    print(f"Holder binding: {presentation.holder_binding}")
```

### PresentCredentialParams

| Parameter          | Type          | Required | Description                                          |
| ------------------ | ------------- | -------- | ---------------------------------------------------- |
| `sd_jwt`           | `str`         | Yes      | The SD-JWT credential to create a presentation from. |
| `disclosed_claims` | `list[str]`   | Yes      | Claim names to disclose. All others remain hidden.   |
| `audience`         | `str \| None` | No       | Intended verifier DID or URL for the holder binding. |
| `nonce`            | `str \| None` | No       | Nonce for replay protection in the holder binding.   |

### PresentCredentialResponse

| Field              | Type        | Description                                                   |
| ------------------ | ----------- | ------------------------------------------------------------- |
| `presentation_jwt` | `str`       | The SD-JWT presentation containing only the disclosed claims. |
| `disclosed_claims` | `list[str]` | The claim names that were disclosed.                          |
| `holder_binding`   | `str`       | The key binding JWT proving holder possession.                |

## Example: Credential Lifecycle

```python theme={null}
from grantex import Grantex, ListCredentialsParams, PresentCredentialParams

with Grantex(api_key="gx_live_...") as client:
    # List active credentials for a user
    result = client.credentials.list(ListCredentialsParams(
        principal_id="user_abc123",
        status="active",
    ))

    # Verify a specific credential
    vc = result.credentials[0]
    verification = client.credentials.verify(vc.jwt)
    if not verification.valid:
        raise ValueError(f"Credential invalid: {verification.reason}")

    # Create a selective-disclosure presentation
    presentation = client.credentials.present(PresentCredentialParams(
        sd_jwt=vc.jwt,
        disclosed_claims=["name", "email"],
        audience="did:web:verifier.example.com",
        nonce="unique-request-nonce",
    ))

    # Send presentation.presentation_jwt to the verifier
    print(f"Presentation ready: {len(presentation.disclosed_claims)} claims disclosed")
```
