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

# Mint a credential for a person as themselves

> Mints an L2 or L3 SD-JWT-VC credential for a verified person, referenced by the `principal_ref` issued to your organization, scoped to a counterparty `audience`, and bound to the presenting agent's public key. Every credential is issuer-signed with `sub` (the person's audience-scoped pairwise DID, stable across mints and levels) and `aud` (the canonical counterparty domain), so counterparties can verify audience binding and key returning customers offline. Credentials are short-lived projections of the person's current verification — mint on demand rather than storing them long-term.



## OpenAPI

````yaml /api-reference/openapi.json post /credentials/individual
openapi: 3.1.0
info:
  title: baselayer-api-service
  version: 0.1.0
servers:
  - url: https://api.baselayer.com/
security: []
paths:
  /credentials/individual:
    post:
      tags:
        - Credentials
      summary: Mint a credential for a person as themselves
      description: >-
        Mints an L2 or L3 SD-JWT-VC credential for a verified person, referenced
        by the `principal_ref` issued to your organization, scoped to a
        counterparty `audience`, and bound to the presenting agent's public key.
        Every credential is issuer-signed with `sub` (the person's
        audience-scoped pairwise DID, stable across mints and levels) and `aud`
        (the canonical counterparty domain), so counterparties can verify
        audience binding and key returning customers offline. Credentials are
        short-lived projections of the person's current verification — mint on
        demand rather than storing them long-term.
      operationId: mint_individual_credential
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/v1.IndividualCredentialMintRequest'
          application/vnd.baselayer.v1+json:
            schema:
              $ref: '#/components/schemas/v1.IndividualCredentialMintRequest'
        required: true
      responses:
        '201':
          description: Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/v1.CredentialMintResponse'
            application/vnd.baselayer.v1+json:
              schema:
                $ref: '#/components/schemas/v1.CredentialMintResponse'
        '404':
          description: >-
            The principal_ref is unknown or was issued to another organization —
            the two are indistinguishable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIError'
                title: ResourceNotFound
                description: Could not locate the resource for the given URI.
                examples:
                  - code: 1
                    message: Could not locate the resource for the given URI.
                    metadata: {}
        '409':
          description: >-
            The person's verified-identity snapshot is superseded or expired;
            re-verify before minting.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIError'
                title: CredentialSnapshotNotCurrent
                description: >-
                  The subject's verified-identity snapshot is superseded or
                  expired; re-verify before minting.
                examples:
                  - code: 6301
                    message: >-
                      The subject's verified-identity snapshot is superseded or
                      expired; re-verify before minting.
                    metadata: {}
        '422':
          description: >-
            The mint payload failed validation, the audience cannot be reduced
            to a canonical counterparty domain, or a requested disclosure field
            is outside the vault schema.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIError'
                title: InvalidCredentialMintPayload
                description: The credential mint payload failed validation.
                examples:
                  - code: 6303
                    message: The credential mint payload failed validation.
                    metadata: {}
      security:
        - APIKeyHeader: []
components:
  schemas:
    v1.IndividualCredentialMintRequest:
      additionalProperties: false
      description: |-
        Body for ``POST /credentials/individual``: mint an L2 or L3
        credential for a verified person as themselves.
      properties:
        principal_ref:
          description: >-
            Pairwise reference to the verified principal, as issued to the
            calling organization at verification completion.
          maxLength: 255
          minLength: 1
          title: Principal Ref
          type: string
        level:
          $ref: '#/components/schemas/v1.CredentialMintLevel'
          description: >-
            Credential layer to mint: L2 (audience-scoped pairwise DID) or L3
            (selectively disclosed verified identity).
        audience:
          description: >-
            The counterparty the credential is scoped to — a domain, or a URL
            reduced to its hostname.
          maxLength: 512
          minLength: 1
          title: Audience
          type: string
        agent_key:
          $ref: '#/components/schemas/v1.CredentialAgentKey'
          description: >-
            Public JWK of the agent that will present the credential; becomes
            the credential's cnf binding.
        disclosed_fields:
          description: >-
            L3 only: the dotted disclosure paths the credential should carry,
            e.g. `user.email.hash`. Individual mints take `user.*` paths;
            business mints take `business.*` and `actor.user.*` paths.
          items:
            type: string
          maxItems: 64
          title: Disclosed Fields
          type: array
        disclosure_mode:
          $ref: '#/components/schemas/v1.DisclosureMode'
          default: CLEARTEXT_AND_HASH
          description: >-
            L3 disclosure mode: CLEARTEXT_AND_HASH (default) discloses requested
            fields as cleartext alongside their recognition hashes; HASH_ONLY
            discloses only the recognition hashes.
      required:
        - principal_ref
        - level
        - audience
        - agent_key
      title: IndividualCredentialMintRequest (v1)
      type: object
    v1.CredentialMintResponse:
      description: |-
        Body for the mint routes: the wire credential and its issuance facts.

        ``credential`` is the SD-JWT presentation without a Key Binding JWT —
        the presenting agent appends the KB-JWT at request time.
      properties:
        credential:
          description: The SD-JWT-VC wire string.
          title: Credential
          type: string
        credential_type:
          $ref: '#/components/schemas/v1.IssuedCredentialType'
          description: The minted credential layer (L2 or L3).
        jti:
          description: The credential's unique token id; the issuance-record handle.
          title: Jti
          type: string
        principal_ref:
          description: The pairwise principal reference minted for.
          title: Principal Ref
          type: string
        business_ref:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: >-
            The pairwise business reference minted for; null on individual
            mints.
          title: Business Ref
        audience:
          description: The canonical counterparty domain the credential is scoped to.
          title: Audience
          type: string
        issued_at:
          description: Issuance instant (the issuer JWT's iat).
          format: date-time
          title: Issued At
          type: string
        expires_at:
          description: Expiry instant (the issuer JWT's exp).
          format: date-time
          title: Expires At
          type: string
        disclosed_fields:
          description: The dotted disclosure paths the credential carries.
          items:
            type: string
          title: Disclosed Fields
          type: array
        active_keys:
          description: >-
            Dotted keys of the identity attributes the credential attests to (on
            business mints, the union of the business and actor scopes).
          items:
            type: string
          title: Active Keys
          type: array
      required:
        - credential
        - credential_type
        - jti
        - principal_ref
        - audience
        - issued_at
        - expires_at
      title: CredentialMintResponse (v1)
      type: object
    APIError:
      properties:
        code:
          type: integer
          title: Code
        message:
          type: string
          title: Message
        uri:
          anyOf:
            - type: string
            - type: 'null'
          title: Uri
        metadata:
          additionalProperties: true
          type: object
          title: Metadata
      type: object
      required:
        - code
        - message
      title: APIError
      description: >-
        APIError is a Pydantic model for standardizing error responses from the
        API.


        This class is used internally by APIException for JSON serialization.

        Users should typically work with APIException directly in exception
        catalogs.
    v1.CredentialMintLevel:
      description: |-
        The credential layer a subject mint request selects (KYA).

        Deliberately narrower than ``IssuedCredentialType``: the individual
        and business mint routes issue only the two subject layers.
        Counterparty credentials have their own route and request shape, so
        a ``level`` of COUNTERPARTY must stay an edge-level payload refusal
        — this enum is what keeps issuance-record vocabulary growth from
        widening the mint requests.
      enum:
        - L2
        - L3
      title: CredentialMintLevel
      type: string
    v1.CredentialAgentKey:
      additionalProperties: false
      description: |-
        The presenting agent's public key, bound into the credential's
        ``cnf`` claim (RFC 7800).

        The customer is the retriever, but the credential is presentable only
        by the agent holding the matching private key. v1 pins the signature
        suite: Ed25519 OKP keys only. ``x`` must encode a well-formed Ed25519
        public key, so malformed key material is rejected as a payload
        validation error, never a mint-time surprise.
      properties:
        kty:
          const: OKP
          default: OKP
          description: JWK key type; v1 accepts OKP only.
          title: Kty
          type: string
        crv:
          const: Ed25519
          default: Ed25519
          description: JWK curve; v1 accepts Ed25519 only.
          title: Crv
          type: string
        x:
          description: Base64url-encoded Ed25519 public key bytes.
          minLength: 1
          title: X
          type: string
        kid:
          anyOf:
            - maxLength: 255
              type: string
            - type: 'null'
          default: null
          description: Optional key identifier.
          title: Kid
      required:
        - x
      title: CredentialAgentKey (v1)
      type: object
    v1.DisclosureMode:
      description: |-
        Per-mint selective-disclosure mode for L3 credentials.

        CLEARTEXT_AND_HASH (the default) discloses requested fields as
        cleartext alongside their recognition hashes; HASH_ONLY discloses only
        the recognition hashes, giving counterparties recognition without
        plaintext.

        Lives here rather than beside the L3 payload shapes because it is a
        stored column vocabulary as of ENG-7140
        (``issued_credentials.disclosure_mode``), and ``models.py`` cannot
        import ``osiris.identity.l3_payloads`` (circular through
        ``active_keys``).
      enum:
        - CLEARTEXT_AND_HASH
        - HASH_ONLY
      title: DisclosureMode
      type: string
    v1.IssuedCredentialType:
      description: |-
        The KYA credential layer.

        L2 is the audience-scoped pairwise DID ("same customer returning");
        L3 is the selectively disclosed verified-identity credential. Both ride
        the same SD-JWT-VC wire format; the layer decides what the issuer JWT
        carries. Counterparty is the counterparty-verification credential
        (ENG-6598): a domain-bound business entity attestation a merchant
        hosts for arriving agents — plain JWS, no selective disclosure, no
        agent key.
      enum:
        - L2
        - L3
        - COUNTERPARTY
      title: IssuedCredentialType
      type: string
  securitySchemes:
    APIKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key

````