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

# Minting Credentials

Once a consumer or business identity is verified, you can securely delegate it to an agent using short-lived, cryptographically signed credentials. A credential is minted on demand and is scoped to one counterparty and agent, so that a stolen credential is useless without the agent’s private key, and so is a stolen merchant session.

<Info>
  ### Before you start

  You need a `principal_ref` (or `business_ref`) in `CURRENT` state (see [Verifying an Identity](/docs/verifying-an-identity)), and an Ed25519 keypair the presenting agent generates on its own hardware. Baselayer only ever sees the public JWK.
</Info>

### Credential parameters

| Parameter | Notes |
| - | - |
| **`level`** | `L2` (pairwise DID only) or `L3` (selective disclosure). |
| **`audience`** | The counterparty the credential is scoped to — a bare domain or a URL reduced to its hostname. |
| **`agent_key`** | The presenting agent's public JWK (`kty: "OKP"`, `crv: "Ed25519"`). Malformed key material is a `422`, never a mint-time surprise. |
| **`disclosed_fields`** | L3 only. Dotted claim paths (e.g. `user.name.first`), up to 64. Must be empty for L2 — sending any is a `422`. |
| **`disclosure_mode`** | `CLEARTEXT_AND_HASH` (default) or `HASH_ONLY` — see "Selective disclosure modes" below. |

### Mint an individual credential

`POST /credentials/individual` — mints for a verified person as a consumer.

* **L2** — an audience-scoped pairwise DID ("same customer returning"), discloses nothing else. Stable for the same person and audience even across different agent keys. The same customer gets the same ID at that merchant every time, across agents, sessions, and re-verification. At a different merchant, they get an unrelated ID, so merchants cannot pool IDs to track a customer across sites.
* **L3** — discloses exactly the fields you request under the `user.` prefix (name, email, phone, address, DOB, SSN, residency — see the [API Reference](/api-reference) for the full attribute list). Logging in a returning customer receives a verified email hash. Age-gated sites receive birth year. Account opening receives name, DOB, the last four digits of SSN, and address. A field outside the vault schema is a `422`; a field that is unpopulated for that identity is silently omitted.

### Mint a business operator credential

`POST /credentials/business` — the individual mint body plus `business_ref`. Requires a `VERIFIED` link between the person and that business; anything short of `VERIFIED` is a `409`. L3 disclosure paths split across `business.*` (the business's own attested fields) and `actor.user.*` (the authorized person's fields).

### Mint a counterparty credential

`POST /credentials/counterparty` — a domain-bound business attestation a merchant hosts at its own `/.well-known/baselayer-counterparty-credential`, so arriving agents can verify the business behind the site. No agent key, no disclosure selection — every claim is public-record fact, and the `domain` must match the business's verified website domain.

### Selective disclosure modes

* **`CLEARTEXT_AND_HASH`** (default) — each requested leaf is disclosed as cleartext *and* its family's recognition hash, so a counterparty can both read the value and recognize the same person later.
* **`HASH_ONLY`** — no cleartext crosses the wire; each leaf collapses to its family's hash (`name.*` → `name.full_hash`, `email.*` → `email.hash`, etc.). Families with no hash (`dob`, `residency`) drop entirely rather than leaking a matchable identifier.

For exactly how the credential is signed and how a counterparty checks it for tampering, see the [Credential Format Reference](/docs/credential-format-reference).

### Troubleshooting

| Problem | Fix |
| - | - |
| `422` on an L2 mint | You sent `disclosed_fields` — L2 discloses nothing beyond the pairwise DID; omit the field entirely. |
| `422` — disclosure field outside the vault schema (code `6302`) | Check the field is a real leaf under `user.` / `business.` / `actor.user.` in the [API Reference](/api-reference); a typo or an invented field name both 422. |
| `409` — snapshot superseded or expired (code `6301`) | Re-verify the identity (see [Verifying an Identity](/docs/verifying-an-identity)), then re-mint. |
| `409` — business credential needs a `VERIFIED` operator link (code `6300`) | Check `business_operator_link_status` via the identity lookup; the business submission likely needs a matching TIN. |
| `422` — audience not canonicalizable (code `6304`) | Pass a bare domain or a full URL that reduces cleanly to one; free-text strings won't resolve. |


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