> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/credebl/platform/llms.txt
> Use this file to discover all available pages before exploring further.

# Schemas and Credentials

> Credential schemas, credential definitions, the issuance lifecycle, verification flows, bulk issuance, OOB issuance, and OID4VC/OID4VP protocols in CREDEBL.

CREDEBL supports two credential families: **AnonCreds** (Hyperledger Indy-based) and **W3C Verifiable Credentials** (JSON-LD). Both share the concept of a schema that describes the structure of a credential, but they differ in how credentials are signed and presented.

## Credential schemas

A **credential schema** defines the set of attributes (claims) a credential of that type will contain, along with a version string. Schemas are published to a ledger or referenced by a DID Document so that any party can look up and validate the credential's structure.

CREDEBL supports two schema types, defined in the `SchemaType` enum:

<Tabs>
  <Tab title="AnonCreds (Indy)">
    Schemas are published to a Hyperledger Indy ledger. Each attribute has a name; the data type is expressed separately in the credential definition and issuance payload.

    Supported attribute data types (`IndySchemaDataType`):

    * `string`
    * `number`
    * `datetime-local`
    * `boolean`

    An Indy schema ID is derived from the publisher's DID, the schema name, and the version:

    ```text theme={null}
    <publisherDid>:2:<schemaName>:<version>
    ```
  </Tab>

  <Tab title="W3C JSON-LD">
    W3C schemas are associated with a JSON-LD context. CREDEBL supports both Polygon-anchored W3C schemas and ledger-less W3C schemas (using `did:key` or `did:web`).

    Supported attribute data types (`W3CSchemaDataType`):

    * `string`
    * `number`
    * `integer`
    * `datetime-local`
    * `array`
    * `object`
    * `boolean`

    The `JSONSchemaType` enum distinguishes between `polygon` (Polygon W3C) and `no_ledger` (ledger-less) variants.
  </Tab>
</Tabs>

### Creating a schema

Only `owner` and `admin` roles can create schemas. The endpoint supports Indy, Polygon, and W3C schemas through a single generic endpoint:

```http theme={null}
POST /orgs/:orgId/schemas
Authorization: Bearer <token>

{
  "name": "EmployeeCredential",
  "version": "1.0",
  "attributes": ["firstName", "lastName", "employeeId", "department"],
  "schemaType": "indy"
}
```

Schemas can be listed and retrieved per organization via `GET /orgs/:orgId/schemas` and `GET /orgs/:orgId/schemas/:schemaId`.

## Credential definitions

A **credential definition** links a schema to an issuer's cryptographic keys. For AnonCreds credentials, a credential definition must exist before any credentials can be issued. It publishes the issuer's public key material to the ledger so that holders can later prove possession without revealing the credential itself (using zero-knowledge proofs).

Credential definitions are retrieved by schema ID:

```http theme={null}
GET /orgs/:orgId/schemas/:schemaId/cred-defs
```

The `CredDefSortFields` enum supports sorting by `createDateTime`, `tag`, `schemaLedgerId`, and `credentialDefinitionId`.

<Note>
  W3C JSON-LD credentials do not use credential definitions. The issuer's signing key is referenced directly via the DID Document verification method.
</Note>

## The credential issuance lifecycle

### Connection-based issuance

<Steps>
  <Step title="Establish a connection">
    The issuer and holder establish a DIDComm connection. The connection state transitions through: `start` → `invitation-sent` → `invitation-received` → `request-sent` / `request-received` → `response-sent` / `response-received` → `completed`.
  </Step>

  <Step title="Create a credential offer">
    The issuer sends a credential offer to the holder over the established connection:

    ```http theme={null}
    POST /orgs/:orgId/credentials/offer?credentialType=indy
    Authorization: Bearer <token>

    {
      "connectionId": "<connection-id>",
      "credentialDefinitionId": "<cred-def-id>",
      "credentialData": [
        {
          "attributes": {
            "firstName": "Alice",
            "employeeId": "EMP-001"
          }
        }
      ]
    }
    ```

    Supported `credentialType` values: `indy` (AnonCreds) and `jsonld` (W3C JSON-LD).
  </Step>

  <Step title="Holder receives and requests">
    The holder's agent receives the offer. The issuance state transitions: `offer-sent` → `offer-received` → `request-sent` → `request-received`.
  </Step>

  <Step title="Credential issued">
    The issuer's agent issues the signed credential. State transitions to `credential-issued` → `credential-received` → `done`.
  </Step>
</Steps>

The full set of issuance states (`IssuanceProcessState`):

| State                                 | Description                                      |
| ------------------------------------- | ------------------------------------------------ |
| `proposal-sent` / `proposal-received` | Holder proposes a credential type                |
| `offer-sent` / `offer-received`       | Issuer has sent a credential offer               |
| `request-sent` / `request-received`   | Holder has accepted and requested the credential |
| `credential-issued`                   | Issuer has signed and sent the credential        |
| `credential-received`                 | Holder's agent has received the credential       |
| `done`                                | Issuance completed successfully                  |
| `declined`                            | One party declined                               |
| `abandoned`                           | Process abandoned                                |

### Out-of-Band (OOB) issuance

OOB issuance allows credentials to be offered without a prior connection. CREDEBL supports two OOB modes:

**Email delivery** — The issuer creates OOB credential offers and sends them directly to holder email addresses:

```http theme={null}
POST /orgs/:orgId/credentials/oob/email?credentialType=indy
Authorization: Bearer <token>

{
  "credentialOffer": [
    {
      "emailId": "alice@example.com",
      "attributes": { "firstName": "Alice", "employeeId": "EMP-001" }
    }
  ],
  "credentialDefinitionId": "<cred-def-id>"
}
```

**URL-based offer** — The issuer generates an invitation URL that the holder can scan or click:

```http theme={null}
POST /orgs/:orgId/credentials/oob/offer?credentialType=indy
```

This returns an invitation URL and QR code payload the holder can use to accept the credential without an existing connection.

### Bulk issuance via CSV

CREDEBL supports issuing credentials to many holders simultaneously using a CSV file.

<Steps>
  <Step title="Download the CSV template">
    Download a pre-formatted template that matches the schema's attributes:

    ```http theme={null}
    POST /orgs/:orgId/credentials/bulk/template
    ```

    The template includes column headers matching the credential schema attributes. The `email_identifier` column (`TemplateIdentifier.EMAIL_COLUMN`) is used to identify each recipient.
  </Step>

  <Step title="Fill and upload the CSV">
    Upload the completed CSV file:

    ```http theme={null}
    POST /orgs/:orgId/bulk/upload?schemaType=indy
    Content-Type: multipart/form-data
    ```

    This returns a `requestId` used to track the batch.
  </Step>

  <Step title="Preview the data">
    Review the parsed data before issuing:

    ```http theme={null}
    GET /orgs/:orgId/:requestId/preview
    ```
  </Step>

  <Step title="Start bulk issuance">
    Trigger issuance for all rows in the file:

    ```http theme={null}
    POST /orgs/:orgId/:requestId/bulk
    ```
  </Step>

  <Step title="Monitor progress">
    Check the status of uploaded files and retry failed rows if needed:

    ```http theme={null}
    GET /orgs/:orgId/bulk/files
    POST /orgs/:orgId/:fileId/retry/bulk
    ```
  </Step>
</Steps>

## The verification flow

<Steps>
  <Step title="Send a proof request">
    The verifier sends a proof request to a holder's connection. CREDEBL supports two proof request types (`ProofRequestType`): `indy` (AnonCreds) and `presentationExchange` (DIF Presentation Exchange).

    ```http theme={null}
    POST /orgs/:orgId/proofs?requestType=indy
    Authorization: Bearer <token>

    {
      "connectionId": "<connection-id>",
      "proofFormats": {
        "indy": {
          "attributes": [
            { "attributeName": "firstName", "credDefId": "<cred-def-id>" }
          ]
        }
      }
    }
    ```

    For connectionless scenarios, use `POST /orgs/:orgId/proofs/oob`.
  </Step>

  <Step title="Holder presents proof">
    The holder's agent receives the proof request and sends a presentation. The verification state transitions: `request-sent` → `request-received` → `presentation-sent` → `presentation-received`.
  </Step>

  <Step title="Verifier verifies the presentation">
    The verifier calls the verify endpoint to cryptographically check the presentation:

    ```http theme={null}
    POST /orgs/:orgId/proofs/:proofId/verify
    ```
  </Step>

  <Step title="Retrieve verified proof details">
    Retrieve the verified attributes from the presentation:

    ```http theme={null}
    GET /orgs/:orgId/verified-proofs/:proofId
    ```
  </Step>
</Steps>

The full set of verification states (`VerificationProcessState`):

| State                                         | Description                         |
| --------------------------------------------- | ----------------------------------- |
| `proposal-sent` / `proposal-received`         | Holder proposes a proof type        |
| `request-sent` / `request-received`           | Verifier has sent a proof request   |
| `presentation-sent` / `presentation-received` | Holder has sent a presentation      |
| `done`                                        | Verification completed successfully |
| `declined`                                    | One party declined                  |
| `abandoned`                                   | Process abandoned                   |

## Credential revocation

AnonCreds credentials support revocation. A revocation registry is created alongside a credential definition, and the issuer can revoke specific credentials without revealing which credential was revoked or the holder's identity. The verifier requests a non-revocation proof as part of the proof request.

## OID4VC and OID4VP protocols

CREDEBL supports OpenID for Verifiable Credentials issuance (OID4VC) and OpenID for Verifiable Presentations (OID4VP). The `OpenId4VcIssuanceSessionState` enum tracks OID4VC issuance sessions:

| State                        | Description                                  |
| ---------------------------- | -------------------------------------------- |
| `OfferCreated`               | Credential offer has been created            |
| `OfferUriRetrieved`          | The offer URI has been fetched by the wallet |
| `AuthorizationInitiated`     | Authorization flow has started               |
| `AuthorizationGranted`       | Authorization has been granted               |
| `AccessTokenRequested`       | Wallet has requested an access token         |
| `AccessTokenCreated`         | Access token has been issued                 |
| `CredentialRequestReceived`  | Wallet has sent a credential request         |
| `CredentialsPartiallyIssued` | Some credentials in a batch have been issued |
| `Completed`                  | All credentials have been issued             |
| `Error`                      | An error occurred during the session         |

<Note>
  OID4VP supports `indy` and `presentationExchange` request types, mirroring the connection-based verification flow. The response modes `direct_post`, `direct_post.jwt`, `dc_api`, and `dc_api.jwt` are defined in the `ResponseMode` enum.
</Note>
