> ## 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 test credential for a person or a business operator

> Takes the `POST /issuance/credentials` body and mints the same credential, with the same claims, for a person or business your current environment's refs name, signed by the sandbox issuer and recorded in your Sandbox environment, from Production or Sandbox alike. Verifiers accept it only when they allow sandbox credentials. Its `sub` is a pairwise DID of its own, never the one a `POST /issuance/credentials` mint signs for the same audience. Send an `Idempotency-Key`, as for `POST /issuance/credentials`.



## OpenAPI

````yaml /api-reference/openapi.json post /issuance/credentials/test
openapi: 3.1.0
info:
  title: baselayer-api-service
  version: 0.1.0
servers:
  - url: https://api.baselayer.com/
security: []
paths:
  /issuance/credentials/test:
    post:
      tags:
        - Credentials
      summary: Mint a test credential for a person or a business operator
      description: >-
        Takes the `POST /issuance/credentials` body and mints the same
        credential, with the same claims, for a person or business your current
        environment's refs name, signed by the sandbox issuer and recorded in
        your Sandbox environment, from Production or Sandbox alike. Verifiers
        accept it only when they allow sandbox credentials. Its `sub` is a
        pairwise DID of its own, never the one a `POST /issuance/credentials`
        mint signs for the same audience. Send an `Idempotency-Key`, as for
        `POST /issuance/credentials`.
      operationId: issuance_credentials_test_create
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            description: >-
              An opaque key, ideally a UUID, that makes this request safe to
              retry. A second request with the same key and body within 24 hours
              answers with the first one's response, marked
              `Idempotent-Replayed: true`, without minting again. The same key
              with a different body is refused with 422, and a retry that
              arrives while the first is still running with 409. Keys are scoped
              to your application.
            title: Idempotency-Key
          description: >-
            An opaque key, ideally a UUID, that makes this request safe to
            retry. A second request with the same key and body within 24 hours
            answers with the first one's response, marked `Idempotent-Replayed:
            true`, without minting again. The same key with a different body is
            refused with 422, and a retry that arrives while the first is still
            running with 409. Keys are scoped to your application.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/v1.CredentialMintRequest'
          application/vnd.baselayer.v1+json:
            schema:
              $ref: '#/components/schemas/v1.CredentialMintRequest'
      responses:
        '201':
          description: The minted test credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/v1.CredentialMintResponse'
            application/vnd.baselayer.v1+json:
              schema:
                $ref: '#/components/schemas/v1.CredentialMintResponse'
          headers:
            Location:
              description: >-
                The minted credential's record,
                `/issuance/credentials/{credential_id}`, read in your Sandbox
                environment; for a pair, the subject's.
              schema:
                type: string
        '404':
          description: >-
            The individual_ref or business_ref is unknown, was issued to another
            organization or to your other environment — the cases are
            indistinguishable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
                title: ResourceNotFound
                description: Could not locate the resource for the given URI.
                examples:
                  - type: resource_not_found
                    code: 1
                    message: Could not locate the resource for the given URI.
                    metadata: {}
        '409':
          description: >-
            Your organization has no Sandbox environment, the person's
            verified-identity snapshot is superseded or expired, or (business)
            no verified operator link exists, or a request with the same
            `Idempotency-Key` is still running.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: >-
            The mint payload failed validation, the audience cannot be
            canonicalized, a requested disclosure field is outside the vault
            schema, the `Idempotency-Key` is missing, or it was already used
            with a different request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
                title: InvalidCredentialMintPayload
                description: The credential mint payload failed validation.
                examples:
                  - type: invalid_credential_mint_payload
                    code: 6303
                    message: The credential mint payload failed validation.
                    metadata: {}
      security:
        - APIKeyHeader: []
components:
  schemas:
    v1.CredentialMintRequest:
      description: >-
        Body for ``POST /issuance/credentials``: mint an L2 or L3 credential for
        a

        verified person as themselves (``type: INDIVIDUAL``), or as the operator

        of a specific business (``type: BUSINESS``, which also names the

        business's ``business_ref``).
      discriminator:
        mapping:
          BUSINESS: '#/components/schemas/v1.BusinessCredentialMintRequest'
          INDIVIDUAL: '#/components/schemas/v1.IndividualCredentialMintRequest'
        propertyName: type
      oneOf:
        - $ref: '#/components/schemas/v1.IndividualCredentialMintRequest'
        - $ref: '#/components/schemas/v1.BusinessCredentialMintRequest'
      title: CredentialMintRequest
    v1.CredentialMintResponse:
      description: >-
        Body of ``POST /issuance/credentials``: one credential for an
        individual, and

        for a business L3 mint the subject's followed by the actor's.
      properties:
        environment:
          $ref: '#/components/schemas/v1.ApplicationType'
          description: The environment the credentials were minted in.
        ttl_capped:
          description: >-
            Whether supporting evidence expiry shortened the requested validity;
            each entry's `expires_at` is the instant it ends.
          title: Ttl Capped
          type: boolean
        credentials:
          description: The minted credentials, subject first.
          items:
            $ref: '#/components/schemas/v1.CredentialMintEntry'
          title: Credentials
          type: array
      required:
        - environment
        - ttl_capped
        - credentials
      title: CredentialMintResponse (v1)
      type: object
    Error:
      properties:
        type:
          type: string
          title: Type
          description: >-
            Stable snake_case name of the error. Branch on this, never on
            `message`.
        code:
          type: integer
          title: Code
          description: Integer catalog code of the error.
        message:
          type: string
          title: Message
          description: For a human reading a log; not stable and not localized.
        metadata:
          additionalProperties: true
          type: object
          title: Metadata
          description: Context documented per `type`.
        request_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Request Id
          description: The `X-Request-ID` of the failed request.
      type: object
      required:
        - type
        - code
        - message
      title: Error
      description: The one body of every error a KYA route answers.
    v1.BusinessCredentialMintRequest:
      additionalProperties: false
      description: |-
        ``type: BUSINESS``: mint for a verified person as the operator of the
        business ``business_ref`` names.
      properties:
        format:
          $ref: '#/components/schemas/v1.CredentialWireFormat'
          default: dc+sd-jwt
          description: >-
            Credential wire format. `dc+sd-jwt` (media type
            `application/dc+sd-jwt`, draft-ietf-oauth-sd-jwt-vc-19 §2.1) is the
            only format issued.
        level:
          $ref: '#/components/schemas/v1.CredentialMintLevel'
          default: L3
          description: >-
            Credential layer to mint (defaults to `L3`): `L2` (audience-scoped
            pairwise DID) or `L3` (selectively disclosed verified identity).
        ttl_seconds:
          anyOf:
            - exclusiveMinimum: 0
              type: integer
            - type: 'null'
          default: null
          description: >-
            Maximum credential validity in seconds, capped at supporting
            evidence expiry. Omitted or null uses the server default (3600
            seconds). Must not exceed the configured maximum (86400 seconds by
            default). Applies to L2 and L3.
          title: Ttl Seconds
        audience:
          description: >-
            The counterparty the credential is scoped to: a bare domain
            (`login.example.com`), or an https authorization-server identifier
            (`https://login.example.com`) kept whole, which derives a different
            pairwise subject than the bare host. Paths, queries, fragments and
            non-default ports are refused.
          maxLength: 512
          minLength: 1
          title: Audience
          type: string
        disclosed_fields:
          description: >-
            `L3` only: the dotted disclosure paths the subject credential should
            carry, e.g. `email` or `hashes.email`. A business mint lists
            business paths here and the actor credential's paths, e.g.
            `given_name`, in `actor_disclosed_fields`.
          items:
            type: string
          maxItems: 64
          title: Disclosed Fields
          type: array
        preset:
          anyOf:
            - $ref: '#/components/schemas/v1.CredentialPreset'
            - type: 'null'
          default: null
          description: >-
            L3 only: disclose a use case's fields instead of listing
            `disclosed_fields`; never both. `GET /issuance/credentials/presets`
            lists each preset's paths. A preset always shares values in the
            clear, and B2B presets need a business mint.
        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.
        agent_key:
          $ref: '#/components/schemas/v1.CredentialAgentKey'
          description: >-
            Public JWK of the agent that will present the credential; becomes
            the credential's cnf binding.
        individual_ref:
          description: >-
            Pairwise reference to the verified individual, as issued to the
            calling organization at verification completion.
          maxLength: 255
          minLength: 1
          title: Individual Ref
          type: string
        type:
          const: BUSINESS
          description: >-
            `BUSINESS`: a person acting as the operator of the business
            `business_ref` names.
          title: Type
          type: string
        business_ref:
          description: >-
            Pairwise reference to the verified business whose identity the
            individual assumes, as issued to the calling organization.
          maxLength: 255
          minLength: 1
          title: Business Ref
          type: string
        actor_disclosed_fields:
          description: >-
            `L3` only: the dotted paths the separate actor credential should
            carry, unprefixed, e.g. `given_name` or `hashes.email` — the
            individual vocabulary `/vct/kya/individual/v1` lists. Never with
            `preset`.
          items:
            type: string
          maxItems: 64
          title: Actor Disclosed Fields
          type: array
      required:
        - audience
        - agent_key
        - individual_ref
        - type
        - business_ref
      title: BusinessCredentialMintRequest (v1)
      type: object
    v1.IndividualCredentialMintRequest:
      additionalProperties: false
      description: '``type: INDIVIDUAL``: mint for a verified person as themselves.'
      properties:
        format:
          $ref: '#/components/schemas/v1.CredentialWireFormat'
          default: dc+sd-jwt
          description: >-
            Credential wire format. `dc+sd-jwt` (media type
            `application/dc+sd-jwt`, draft-ietf-oauth-sd-jwt-vc-19 §2.1) is the
            only format issued.
        level:
          $ref: '#/components/schemas/v1.CredentialMintLevel'
          default: L3
          description: >-
            Credential layer to mint (defaults to `L3`): `L2` (audience-scoped
            pairwise DID) or `L3` (selectively disclosed verified identity).
        ttl_seconds:
          anyOf:
            - exclusiveMinimum: 0
              type: integer
            - type: 'null'
          default: null
          description: >-
            Maximum credential validity in seconds, capped at supporting
            evidence expiry. Omitted or null uses the server default (3600
            seconds). Must not exceed the configured maximum (86400 seconds by
            default). Applies to L2 and L3.
          title: Ttl Seconds
        audience:
          description: >-
            The counterparty the credential is scoped to: a bare domain
            (`login.example.com`), or an https authorization-server identifier
            (`https://login.example.com`) kept whole, which derives a different
            pairwise subject than the bare host. Paths, queries, fragments and
            non-default ports are refused.
          maxLength: 512
          minLength: 1
          title: Audience
          type: string
        disclosed_fields:
          description: >-
            `L3` only: the dotted disclosure paths the subject credential should
            carry, e.g. `email` or `hashes.email`. A business mint lists
            business paths here and the actor credential's paths, e.g.
            `given_name`, in `actor_disclosed_fields`.
          items:
            type: string
          maxItems: 64
          title: Disclosed Fields
          type: array
        preset:
          anyOf:
            - $ref: '#/components/schemas/v1.CredentialPreset'
            - type: 'null'
          default: null
          description: >-
            L3 only: disclose a use case's fields instead of listing
            `disclosed_fields`; never both. `GET /issuance/credentials/presets`
            lists each preset's paths. A preset always shares values in the
            clear, and B2B presets need a business mint.
        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.
        agent_key:
          $ref: '#/components/schemas/v1.CredentialAgentKey'
          description: >-
            Public JWK of the agent that will present the credential; becomes
            the credential's cnf binding.
        individual_ref:
          description: >-
            Pairwise reference to the verified individual, as issued to the
            calling organization at verification completion.
          maxLength: 255
          minLength: 1
          title: Individual Ref
          type: string
        type:
          const: INDIVIDUAL
          description: '`INDIVIDUAL`: the person as themselves.'
          title: Type
          type: string
      required:
        - audience
        - agent_key
        - individual_ref
        - type
      title: IndividualCredentialMintRequest (v1)
      type: object
    v1.ApplicationType:
      enum:
        - sandbox
        - production
      title: ApplicationType
      type: string
    v1.CredentialMintEntry:
      description: |-
        One minted credential: the subject's, or on a business L3 mint the
        actor's beside it.

        ``credential`` is the SD-JWT presentation without a Key Binding JWT: the
        presenting agent appends the KB-JWT at request time.
      properties:
        role:
          $ref: '#/components/schemas/v1.CredentialRole'
          description: Whether this is the subject's or the actor's.
        credential_id:
          description: 'The credential''s unique id: exactly the `jti` its token carries.'
          title: Credential Id
          type: string
        credential:
          description: The SD-JWT-VC wire string.
          title: Credential
          type: string
        disclosed_fields:
          description: The dotted disclosure paths this credential carries.
          items:
            type: string
          title: Disclosed Fields
          type: array
        expires_at:
          description: Expiry instant (the issuer JWT's exp).
          format: date-time
          title: Expires At
          type: string
        active_keys:
          description: >-
            Names of the verification checks that passed (e.g.
            `phone_possession` for an individual, `tax_id_match` for a
            business), from the token-exchange profile's key vocabulary; the
            verification level is derived from them.
          items:
            type: string
          title: Active Keys
          type: array
      required:
        - role
        - credential_id
        - credential
        - expires_at
      title: CredentialMintEntry (v1)
      type: object
    v1.CredentialWireFormat:
      description: |-
        The credential formats issued. The value is the SD-JWT VC media-type
        subtype, a standard code kept verbatim. Validation accepts the stored
        ``SD_JWT_VC`` member, never that string.
      enum:
        - dc+sd-jwt
      title: CredentialWireFormat
      type: string
    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.CredentialPreset:
      description: |-
        A named use case an L3 mint can disclose by instead of listing paths.

        The paths each preset shares live in
        ``osiris.identity.credential_presets``; this is the stored vocabulary
        (``issued_credentials.preset``). Retiring a preset is deleting its
        member: every read of a stored record types the key as text.
      enum:
        - consumer_ecommerce
        - age_gated
        - consumer_regulated
        - b2b_ecommerce
        - b2b_regulated
      title: CredentialPreset
      type: string
    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.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.CredentialRole:
      description: |-
        What a credential in a mint or preview response is for: the subject
        it names, or the individual who acts for a business subject.
      enum:
        - subject
        - actor
      title: CredentialRole
      type: string
  securitySchemes:
    APIKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.