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

# B2B2C Verification Flows

> How businesses issue credentials to consumers, who then share them with verifiers.

Truthlocks enables Business-to-Business-to-Consumer (B2B2C) flows where a business issues a credential to a consumer, who then selectively shares it with a third-party verifier. This pattern is common for employment verification, education credentials, professional certifications, and identity proofs.

## Architecture

<Steps>
  <Step title="Issuer mints a credential">
    The issuing business (e.g., an employer or university) mints an attestation for a specific consumer using the Issuer API. The attestation is signed with the issuer's key and anchored to the transparency log.
  </Step>

  <Step title="Credential is delivered">
    The credential is delivered to the consumer's inbox via their email address. If the consumer does not yet have a Truthlocks account, the delivery is held in a pending queue and claimed automatically when they sign up.
  </Step>

  <Step title="Consumer receives and accepts">
    The consumer logs into the verify portal, views the credential in their inbox, and accepts it. Accepted credentials appear in their portfolio.
  </Step>

  <Step title="Verifier requests proof">
    A third-party business (the verifier) requests proof from the consumer — for example, via a shared link, QR code, or direct API call.
  </Step>

  <Step title="Consumer shares proof">
    The consumer approves the request, releasing the cryptographic proof bundle to the verifier. The verifier can independently validate the proof without contacting Truthlocks.
  </Step>
</Steps>

## Issuing a credential

Use the [deliver endpoint](/api-reference/consumer/deliver) to issue a credential to a consumer's inbox:

```bash theme={null}
curl -X POST https://api.truthlocks.com/v1/consumer/inbox/deliver \
  -H "X-API-Key: tl_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "attestation_id": "att_a1b2c3d4",
    "consumer_reference": "employee@example.com",
    "safe_metadata": {
      "schema": "employment-v1",
      "issuer_name": "Acme Corp"
    }
  }'
```

The API returns one of two responses:

* **201 Delivered** — the consumer has an account and the credential is in their inbox.
* **202 Pending** — the consumer does not have an account yet. The delivery is queued and auto-claimed when they register.

```json 201 — Delivered theme={null}
{
  "id": "inbox_5f6g7h8i",
  "status": "delivered",
  "consumer_reference": "employee@example.com"
}
```

```json 202 — Pending theme={null}
{
  "status": "pending",
  "consumer_reference": "employee@example.com",
  "message": "Consumer not yet registered. Delivery will be claimed on signup."
}
```

## Issuing with the SDK

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { TruthlockClient } from '@truthlock/sdk';

  const client = new TruthlockClient({
    baseUrl: 'https://api.truthlocks.com',
    auth: { type: 'apiKey', apiKey: 'tl_live_...' },
  });

  // Step 1: Mint the attestation
  const attestation = await client.attestations.mint({
    issuer_id: 'iss_abc123',
    kid: 'ed-key-2026',
    alg: 'Ed25519',
    schema: 'employment-v1',
    claims: {
      employer: 'Acme Corp',
      role: 'Senior Engineer',
      status: 'Active',
      start_date: '2024-03-01',
    },
    recipient: 'employee@example.com',
  });

  // Step 2: Deliver to the consumer's inbox
  await client.consumer.deliver({
    attestation_id: attestation.id,
    consumer_reference: 'employee@example.com',
    safe_metadata: {
      schema: 'employment-v1',
      issuer_name: 'Acme Corp',
    },
  });
  ```

  ```go Go theme={null}
  att, _ := client.Attestations.Mint(ctx, truthlock.MintParams{
      IssuerID: "iss_abc123",
      KID:      "ed-key-2026",
      Alg:      "Ed25519",
      Schema:   "employment-v1",
      Claims: map[string]any{
          "employer":   "Acme Corp",
          "role":       "Senior Engineer",
          "status":     "Active",
          "start_date": "2024-03-01",
      },
      Recipient: "employee@example.com",
  })

  client.Consumer.Deliver(ctx, truthlock.DeliverParams{
      AttestationID:     att.ID,
      ConsumerReference: "employee@example.com",
      SafeMetadata: map[string]any{
          "schema":      "employment-v1",
          "issuer_name": "Acme Corp",
      },
  })
  ```
</CodeGroup>

## Consumer experience

Once delivered, the consumer interacts with the credential through the verify portal:

1. **Inbox** — view all delivered credentials with issuer name and schema type. Unread items are highlighted.
2. **Accept** — accept a credential to add it to your portfolio.
3. **Portfolio** — manage accepted credentials and control which are public or private.
4. **Share** — generate a shareable link or QR code for a specific credential's proof bundle.

Consumers can also query their inbox programmatically:

```bash theme={null}
curl https://api.truthlocks.com/v1/consumer/inbox?read_state=UNREAD \
  -H "Authorization: Bearer <consumer_token>"
```

## Verification by the relying party

The verifier receives a proof bundle (either via a shared link or directly from the consumer). They can verify it using the [verify endpoint](/api-reference/verify) or offline using the [proof bundle specification](/specification/proof-bundle):

```bash theme={null}
curl -X POST https://api.truthlocks.com/v1/verify \
  -H "Content-Type: application/json" \
  -d '{
    "proof_bundle": "<base64-encoded proof bundle>"
  }'
```

The response includes a verdict and the original claims:

```json theme={null}
{
  "verdict": "VALID",
  "attestation_id": "att_a1b2c3d4",
  "issuer": {
    "id": "iss_abc123",
    "name": "Acme Corp",
    "trust_tier": "verified_org"
  },
  "claims": {
    "employer": "Acme Corp",
    "role": "Senior Engineer",
    "status": "Active"
  }
}
```

For offline verification, resolve the issuer's signing keys via [DID](/specification/did-jwks) or [JWKS](/specification/did-jwks) and validate the proof bundle signature locally.

## Use cases

| Use case                   | Issuer              | Consumer     | Verifier                  |
| :------------------------- | :------------------ | :----------- | :------------------------ |
| Employment verification    | Employer            | Employee     | Background check provider |
| Education credential       | University          | Graduate     | Hiring company            |
| Professional certification | Certification body  | Professional | Client or employer        |
| Identity proof             | Government agency   | Citizen      | Financial institution     |
| Health credential          | Healthcare provider | Patient      | Insurance company         |

## Related

<CardGroup cols={2}>
  <Card title="Consumer portal" icon="inbox" href="/guides/consumer-portal">
    Managing credentials from the consumer side.
  </Card>

  <Card title="Deliver to inbox" icon="paper-plane" href="/api-reference/consumer/deliver">
    API reference for credential delivery.
  </Card>

  <Card title="Verify endpoint" icon="shield-check" href="/api-reference/verify">
    Verify a proof bundle.
  </Card>

  <Card title="Proof bundle spec" icon="file-code" href="/specification/proof-bundle">
    Offline verification specification.
  </Card>
</CardGroup>
