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

# Public Shares

> Issue and revoke time-limited public share tokens for report runs and decision traces. The token is the credential.

Share links let a report run or decision trace be viewed at a `/share/{token}` URL without a
login — the token itself is the credential, like a password. Management endpoints are tenant-scoped
and RBAC-gated; the public read endpoint is auth-free and validates the token itself.

## POST /api/v1/shares

Issue a new share token. **Editor or admin.**

### Request body

| Field        | Type              | Required | Description                                                               |
| ------------ | ----------------- | -------- | ------------------------------------------------------------------------- |
| `kind`       | enum              | Yes      | `"report_run"` or `"decision_trace"`.                                     |
| `resourceId` | string (1-256)    | Yes      | Id of the report run or decision trace to share.                          |
| `expiresAt`  | string (ISO-8601) | Yes      | When the link expires. Must be in the future and at most **90 days** out. |
| `label`      | string (max 256)  | No       | Human label for the link list. Defaults to `""`.                          |

<Note>
  `kind` does **not** accept `"dashboard"`. Dashboards are config-driven (there is no Dashboard
  entity to resolve), so a dashboard token would always 404. The value is intentionally excluded
  from the create schema.
</Note>

### Response `201`

The token is returned **only once**, at creation time. Store it — list responses omit it.

```json theme={null}
{
  "id": "shl_...",
  "kind": "report_run",
  "resourceId": "rr_...",
  "token": "9f2c...<64 hex chars>",
  "label": "Q3 board deck",
  "expiresAt": "2026-08-01T00:00:00.000Z",
  "createdAt": "2026-07-03T12:00:00.000Z",
  "publicUrl": "/share/9f2c..."
}
```

### Errors

| Code  | Reason                                                                                     |
| ----- | ------------------------------------------------------------------------------------------ |
| `400` | Invalid payload, `expiresAt` not a valid timestamp, in the past, or more than 90 days out. |
| `403` | Caller is not editor/admin.                                                                |

## GET /api/v1/shares

List this tenant's share links. **Viewer, editor, or admin.**

The token is **never** returned here — only metadata and usage counters.

### Response `200`

```json theme={null}
{
  "data": [
    {
      "id": "shl_...",
      "kind": "report_run",
      "resourceId": "rr_...",
      "label": "Q3 board deck",
      "expiresAt": "2026-08-01T00:00:00.000Z",
      "createdBy": "user_...",
      "revoked": false,
      "viewCount": 12,
      "lastViewedAt": "2026-07-03T18:30:00.000Z",
      "createdAt": "2026-07-03T12:00:00.000Z",
      "updatedAt": "2026-07-03T18:30:00.000Z"
    }
  ]
}
```

## DELETE /api/v1/shares/:id

Revoke a share link. **Editor or admin.** Revocation is soft — the row stays with `revoked: true`
so the audit trail is preserved, and the public read endpoint immediately refuses the token.

### Response `200`

```json theme={null}
{ "ok": true, "revoked": true }
```

## GET /api/v1/public/shares/:token

Auth-free read of a previously issued share. No tenant header, no API key — the token in the path
is the credential. Per-IP rate limited (60 requests / 60 s, fail-open).

### Response `200`

```json theme={null}
{
  "kind": "report_run",
  "label": "Q3 board deck",
  "expiresAt": "2026-08-01T00:00:00.000Z",
  "payload": { "...": "the report-run or decision-trace record" }
}
```

For `report_run` the payload excludes raw artifact bytes (metadata, section data, and narrative
only). Each successful read increments the link's `viewCount`.

<Warning>
  Every failure mode returns `404` — token not found, revoked, expired, or the underlying resource
  deleted — so a caller can never enumerate which tokens exist.
</Warning>
