> ## 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` sub-client manages W3C Verifiable Credentials and SD-JWT selective disclosures. You can retrieve individual credentials, list credentials with filters, verify credential JWTs, and create selective-disclosure presentations.

```typescript theme={null}
// Get, list, verify, present
const vc = await grantex.credentials.get('vc_01HXYZ...');
const all = await grantex.credentials.list({ principalId: 'user_abc123' });
const verification = await grantex.credentials.verify(vcJwt);
const presentation = await grantex.credentials.present({ sdJwt, disclosedClaims: ['name', 'email'] });
```

***

## credentials.get()

Retrieve a single Verifiable Credential by its ID.

```typescript theme={null}
const vc = await grantex.credentials.get('vc_01HXYZ...');

console.log(vc.id);           // 'vc_01HXYZ...'
console.log(vc.type);         // ['VerifiableCredential', 'IdentityCredential']
console.log(vc.issuer);       // 'did:web:grantex.dev'
console.log(vc.subject);      // 'did:grantex:user_abc123'
console.log(vc.issuanceDate); // '2026-03-01T00:00:00Z'
console.log(vc.status);       // 'active'
console.log(vc.jwt);          // compact JWT string
```

### Parameters

<ParamField body="credentialId" type="string" required>
  The unique credential identifier.
</ParamField>

### Response: `VerifiableCredential`

<ResponseField name="id" type="string">
  Unique credential identifier.
</ResponseField>

<ResponseField name="type" type="string[]">
  Credential types (always includes `'VerifiableCredential'`).
</ResponseField>

<ResponseField name="issuer" type="string">
  DID of the credential issuer.
</ResponseField>

<ResponseField name="subject" type="string">
  DID of the credential subject (the holder).
</ResponseField>

<ResponseField name="issuanceDate" type="string">
  ISO 8601 timestamp when the credential was issued.
</ResponseField>

<ResponseField name="expirationDate" type="string | null">
  ISO 8601 timestamp when the credential expires, or `null` if it does not expire.
</ResponseField>

<ResponseField name="status" type="string">
  Current status: `'active'`, `'revoked'`, or `'expired'`.
</ResponseField>

<ResponseField name="jwt" type="string">
  The credential in compact JWT format.
</ResponseField>

<ResponseField name="claims" type="Record<string, unknown>">
  The credential subject claims (key-value pairs).
</ResponseField>

***

## credentials.list()

List Verifiable Credentials with optional filters.

```typescript theme={null}
const result = await grantex.credentials.list({
  principalId: 'user_abc123',
  type: 'IdentityCredential',
  status: 'active',
  page: 1,
  pageSize: 20,
});

console.log(result.credentials.length); // 3
console.log(result.total);              // 3
for (const vc of result.credentials) {
  console.log(vc.id, vc.type);
}
```

### Parameters

<ParamField body="principalId" type="string">
  Filter credentials by principal (subject) ID.
</ParamField>

<ParamField body="type" type="string">
  Filter by credential type (e.g., `'IdentityCredential'`, `'EmploymentCredential'`).
</ParamField>

<ParamField body="status" type="'active' | 'revoked' | 'expired'">
  Filter by credential status.
</ParamField>

<ParamField body="page" type="number">
  Page number for pagination (default: 1).
</ParamField>

<ParamField body="pageSize" type="number">
  Number of results per page (default: 20, max: 100).
</ParamField>

### Response: `ListCredentialsResponse`

<ResponseField name="credentials" type="VerifiableCredential[]">
  Array of Verifiable Credential objects.
</ResponseField>

<ResponseField name="total" type="number">
  Total number of matching credentials.
</ResponseField>

***

## credentials.verify()

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

```typescript theme={null}
const result = await grantex.credentials.verify(vcJwt);

if (result.valid) {
  console.log(result.issuer);    // 'did:web:grantex.dev'
  console.log(result.subject);   // 'did:grantex:user_abc123'
  console.log(result.claims);    // { name: 'Alice', email: 'alice@example.com' }
  console.log(result.expiresAt); // '2027-03-01T00:00:00Z'
} else {
  console.log(result.reason);    // 'expired' | 'revoked' | 'invalid_signature'
}
```

### Parameters

<ParamField body="vcJwt" type="string" required>
  The Verifiable Credential in compact JWT format.
</ParamField>

### Response: `VerifyCredentialResponse`

<ResponseField name="valid" type="boolean">
  Whether the credential is valid.
</ResponseField>

<ResponseField name="issuer" type="string">
  DID of the credential issuer (present when valid).
</ResponseField>

<ResponseField name="subject" type="string">
  DID of the credential subject (present when valid).
</ResponseField>

<ResponseField name="claims" type="Record<string, unknown>">
  The credential subject claims (present when valid).
</ResponseField>

<ResponseField name="expiresAt" type="string | null">
  ISO 8601 expiration timestamp, or `null` if the credential does not expire.
</ResponseField>

<ResponseField name="reason" type="string">
  Reason for invalidity (present when `valid` is `false`): `'expired'`, `'revoked'`, `'invalid_signature'`, or `'untrusted_issuer'`.
</ResponseField>

***

## credentials.present()

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

```typescript theme={null}
const presentation = await grantex.credentials.present({
  sdJwt: 'eyJ0eXAiOiJ2YytzZC1qd3QiLC...',
  disclosedClaims: ['name', 'email'],
});

console.log(presentation.presentationJwt);   // compact JWT with selective disclosures
console.log(presentation.disclosedClaims);   // ['name', 'email']
console.log(presentation.holderBinding);     // key binding JWT
```

### Parameters

<ParamField body="sdJwt" type="string" required>
  The SD-JWT credential to create a presentation from.
</ParamField>

<ParamField body="disclosedClaims" type="string[]" required>
  List of claim names to disclose in the presentation. All other claims remain hidden.
</ParamField>

<ParamField body="audience" type="string">
  The intended verifier DID or URL. Included in the holder binding JWT if provided.
</ParamField>

<ParamField body="nonce" type="string">
  A nonce value for replay protection in the holder binding.
</ParamField>

### Response: `PresentCredentialResponse`

<ResponseField name="presentationJwt" type="string">
  The SD-JWT presentation containing only the disclosed claims.
</ResponseField>

<ResponseField name="disclosedClaims" type="string[]">
  The claim names that were disclosed.
</ResponseField>

<ResponseField name="holderBinding" type="string">
  The key binding JWT proving the holder's possession of the credential.
</ResponseField>

***

## Full example

```typescript theme={null}
import { Grantex } from '@grantex/sdk';

const grantex = new Grantex({ apiKey: process.env.GRANTEX_API_KEY });

// List active credentials for a user
const { credentials } = await grantex.credentials.list({
  principalId: 'user_abc123',
  status: 'active',
});

// Verify a specific credential
const vc = credentials[0];
const verification = await grantex.credentials.verify(vc.jwt);
if (!verification.valid) {
  throw new Error(`Credential invalid: ${verification.reason}`);
}

// Create a selective-disclosure presentation for a verifier
const presentation = await grantex.credentials.present({
  sdJwt: vc.jwt,
  disclosedClaims: ['name', 'email'],
  audience: 'did:web:verifier.example.com',
  nonce: 'unique-request-nonce',
});

// Send presentation.presentationJwt to the verifier
```
