> 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.

# Issuance Flow

Credential issuance is the process by which an Issuer creates, signs, and delivers a Verifiable Credential to a Holder.

## Issuance Flow Overview

```mermaid
sequenceDiagram
    participant Issuer
    participant IDA API
    participant ADI Chain
    participant Holder Wallet

    Issuer->>IDA API: 1. POST /credentials/issue
    IDA API->>ADI Chain: 2. Verify issuer DID is active
    IDA API->>ADI Chain: 3. Verify schema exists
    IDA API->>IDA API: 4. Validate claims against schema
    IDA API->>IDA API: 5. Construct VC document
    IDA API->>IDA API: 6. Sign with issuer's key
    IDA API->>ADI Chain: 7. Register status entry
    IDA API->>Issuer: 8. Return signed VC

    Issuer->>Holder Wallet: 9. Send credential offer (DIDComm)
    Holder Wallet->>Holder Wallet: 10. Review and accept
    Holder Wallet->>Holder Wallet: 11. Store encrypted VC
```

## Step-by-Step

### Step 1: Issuer Submits Issuance Request

```http
POST /api/v1/credentials/issue
Content-Type: application/json
Authorization: Bearer <issuer-api-key>

{
  "schemaId": "did:adi:schema:university-degree-v1",
  "issuerDid": "did:adi:issuer001...",
  "holderDid": "did:adi:holder001...",
  "claims": {
    "degree": {
      "type": "BachelorDegree",
      "name": "Bachelor of Science in Computer Science",
      "university": "MIT",
      "graduationYear": 2025,
      "gpa": 3.8
    }
  },
  "expirationDate": "2030-12-31T23:59:59Z",
  "proofType": "Ed25519Signature2020",
  "revocable": true
}
```

### Steps 2-3: Verification

The API verifies:

* Issuer DID exists and is not deactivated
* Issuer has an `assertionMethod` key of the requested proof type
* Schema exists in the Schema Registry
* Issuer is authorized to issue against this schema (if restricted)

### Step 4: Schema Validation

The `claims` object is validated against the schema's JSON Schema definition. All required fields must be present and types must match.

### Steps 5-6: VC Construction and Signing

The API constructs the full VC document with:

* JSON-LD `@context` from the schema
* `type` array from schema + `VerifiableCredential`
* `credentialStatus` entry for revocation tracking
* `proof` object signed with the issuer's private key

### Step 7: Status Registration

A status entry is created in the Revocation Registry for future revocation capability.

### Step 8: Response

```json
{
  "credential": {
    "@context": ["https://www.w3.org/2018/credentials/v1", "..."],
    "id": "urn:uuid:f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "type": ["VerifiableCredential", "UniversityDegreeCredential"],
    "issuer": { "id": "did:adi:issuer001...", "name": "MIT" },
    "issuanceDate": "2026-03-28T10:00:00Z",
    "expirationDate": "2030-12-31T23:59:59Z",
    "credentialSubject": {
      "id": "did:adi:holder001...",
      "degree": { "..." }
    },
    "credentialStatus": { "..." },
    "proof": { "..." }
  },
  "credentialId": "urn:uuid:f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "statusListIndex": 3
}
```

### Steps 9-11: Credential Delivery

The issuer delivers the VC to the holder via:

1. **DIDComm**: Encrypted message to the holder's agent endpoint
2. **QR Code**: Holder scans a QR code containing the credential offer
3. **API**: Holder retrieves the credential via API using a one-time token

#### DIDComm Credential Offer

```json
{
  "type": "https://didcomm.org/issue-credential/3.0/offer-credential",
  "id": "offer-001",
  "from": "did:adi:issuer001...",
  "to": ["did:adi:holder001..."],
  "body": {
    "credential_preview": {
      "type": "UniversityDegreeCredential",
      "attributes": [
        { "name": "degree.type", "value": "BachelorDegree" },
        { "name": "degree.university", "value": "MIT" }
      ]
    },
    "formats": [
      {
        "attach_id": "vc-1",
        "format": "aries/ld-proof-vc-detail@v1.0"
      }
    ]
  }
}
```

## Bulk Issuance

Issue credentials to multiple holders in a single API call:

```http
POST /api/v1/credentials/issue/batch
Content-Type: application/json
Authorization: Bearer <issuer-api-key>

{
  "schemaId": "did:adi:schema:university-degree-v1",
  "issuerDid": "did:adi:issuer001...",
  "credentials": [
    {
      "holderDid": "did:adi:holder001...",
      "claims": { "degree": { "type": "BachelorDegree", "..." } }
    },
    {
      "holderDid": "did:adi:holder002...",
      "claims": { "degree": { "type": "MasterDegree", "..." } }
    }
  ],
  "expirationDate": "2030-12-31T23:59:59Z"
}
```

Response:

```json
{
  "results": [
    { "holderDid": "did:adi:holder001...", "credentialId": "urn:uuid:...", "status": "issued" },
    { "holderDid": "did:adi:holder002...", "credentialId": "urn:uuid:...", "status": "issued" }
  ],
  "issued": 2,
  "failed": 0,
  "transactionHash": "0xbatch..."
}
```

## BBS+ Issuance

For credentials that support selective disclosure, use the BBS+ proof type:

```http
POST /api/v1/credentials/issue
Content-Type: application/json

{
  "schemaId": "did:adi:schema:university-degree-v1",
  "issuerDid": "did:adi:issuer001...",
  "holderDid": "did:adi:holder001...",
  "claims": { "..." },
  "proofType": "BbsBlsSignature2020"
}
```

The resulting VC will have a `BbsBlsSignature2020` proof that enables the holder to create derived proofs revealing only selected attributes.

## Agent Delegation Issuance

Issuing a delegation credential to an AI agent follows the same flow but uses the agent delegation schema:

```http
POST /api/v1/credentials/issue
Content-Type: application/json

{
  "schemaId": "did:adi:schema:agent-delegation-v1",
  "issuerDid": "did:adi:human001...",
  "holderDid": "did:adi:agent:7f3a...",
  "claims": {
    "delegator": "did:adi:human001...",
    "delegate": "did:adi:agent:7f3a...",
    "scope": ["purchase-groceries", "compare-prices"],
    "constraints": {
      "maxSpendPerWeek": 200,
      "authorizedMerchants": ["FreshMart", "OrganicCo"]
    },
    "maxDepth": 1
  },
  "expirationDate": "2026-09-15T00:00:00Z"
}
```

## Issuance Errors

| Error Code                 | Description                     |
| -------------------------- | ------------------------------- |
| `ISSUER_NOT_FOUND`         | Issuer DID does not exist       |
| `ISSUER_DEACTIVATED`       | Issuer DID has been deactivated |
| `SCHEMA_NOT_FOUND`         | Schema ID not in registry       |
| `SCHEMA_VALIDATION_FAILED` | Claims do not match schema      |
| `HOLDER_NOT_FOUND`         | Holder DID does not exist       |
| `SIGNING_FAILED`           | Failed to sign the credential   |
| `RATE_LIMIT_EXCEEDED`      | Too many issuance requests      |