# Create Share Link

- **Method:** `POST`
- **Path:** `/api/v1/runs/{run_id}/sessions/{session_id}/shares`
- **Operation ID:** `create_share_link`
- **Tags:** shares

Publish one finished session's replay by a link anyone holding it can open, with no sign-in.

The link plays the session's recording with the persona's steps and narration beside it. Whatever the browser
showed that is not masked - the test account's email, any text the product rendered - anyone with the link
sees, and `warning` in the answer says what that is: show it to whoever posts the link. Revoke it with
`POST /api/v1/shares/{share_id}/revoke`, and it stops playing on the next request.

The `url` is shown once, in this answer: only a hash of it is kept, so a lost link is replaced by minting
another and revoking the first. It expires after `expires_in_days` (30 unless you ask for 1 to 90), and never
later than the run's evidence does. A session that has not ended yet is a 409, as is a run whose evidence
has expired, and a session the browser pool did not record under its mask (`masked` in the answer says the
session's was). Sharing is off for every tenant until Saram turns it on, and a 403 says so.

## Effective servers

- `https://api.saram.sh`

  Saram

## Authentication

- **HTTPBearer**: HTTP bearer

  a Saram API key (`sk_saram_<env>_...`) or a person's AuthKit access token, as `Authorization: Bearer <credential>`. Both are told apart by shape and produce the same principal.

## Path parameters

- **`run_id` (required)**: `string`
- **`session_id` (required)**: `string`

## Request body

**Content type:** `application/json`

`object | null`, schema: `ShareWrite`, no additional properties

The optional body of `POST /runs/{run_id}/sessions/{session_id}/shares`.

- **`expires_in_days`**: `integer | null`, minimum: `1`, maximum: `90`

  How many days the link plays, 1 to 90; 30 when omitted. Never past the run's evidence\_expires\_at, whatever you ask for: a link ends when the recording it plays is deleted. There is no link that does not expire, and no extending one: mint a new link instead.

**Example:**

```json
{
  "expires_in_days": 1
}
```

## Responses

### 201 The link is minted. Its URL is in this answer and in no other.

**Content type:** `application/json`

schema: `ShareCreated`, no additional properties

A new public link to one session's replay, and the one and only sight of its URL.

Anyone holding `url` can watch the session's recording, which hides only what the browser pool masked when it
recorded it (`masked`): whatever else the browser showed is in it. Only a hash of the link's token is stored, so
no route shows the URL again; a lost link is replaced by minting another and revoking this one with
`POST /api/v1/shares/{id}/revoke`.

- **`capped_by_evidence` (required)**: `boolean`

  True when the run's evidence lifetime, and not the days asked for, set expires\_at: the link ends with the recording.
- **`created_at` (required)**: `string`, format: `date-time`
- **`created_by` (required)**: `string`

  key\_... for an API key, usr\_... for a person, operator for the operator.
- **`expires_at` (required)**: `string`, format: `date-time`
- **`id` (required)**: `string`

  shr\_...: the link's id, for listing and revoking it. Not the link itself.
- **`masked` (required)**: `boolean`

  True when the browser pool recorded the session under its mask: the value of every field the persona typed into, every one-time-code field and every data-saram-mask element are painted over in every frame. False only for a session of Saram's own, which is shared unmasked.
- **`run_id` (required)**: `string`
- **`session_id` (required)**: `string`
- **`url` (required)**: `string`

  The public link. Shown once, here, and never again by any route. Anyone who has it can watch this session until it expires or is revoked, with no sign-in.
- **`warning` (required)**: `string`

  What anyone holding the link will see, what in the recording is masked and what is not, and how to revoke it. Show it to whoever posts the link.

**Example:**

```json
{
  "id": "",
  "url": "",
  "run_id": "",
  "session_id": "",
  "created_at": "",
  "created_by": "",
  "expires_at": "",
  "capped_by_evidence": true,
  "masked": true,
  "warning": ""
}
```

### 403 the API key lacks the required scope, or public sharing is off for this tenant: only Saram turns it on, because a recording shows what the browser showed, but for what the pool masked

### 404 no such run or session of yours - the same answer for another tenant's as for none

### 409 the session has not ended, so its recording is not stored yet; the run's evidence has expired and there is no recording left to share; or the browser pool did not record the session under its mask, which paints over what the persona typed

### 422 Validation Error

**Content type:** `application/json`

schema: `HTTPValidationError`

- **`detail`**: `array`

  **Items:**

  schema: `ValidationError`
  - **`loc` (required)**: `array of (string | integer)`
  - **`msg` (required)**: `string`
  - **`type` (required)**: `string`
  - **`ctx`**: `object`
  - **`input`**: `any`

**Example:**

```json
{
  "detail": [
    {
      "loc": [
        ""
      ],
      "msg": "",
      "type": "",
      "input": null,
      "ctx": {}
    }
  ]
}
```

### 503 this deployment has no share host to open a link on

## Schemas

- `HTTPValidationError` — shown above.
- `ShareCreated` — shown above.
- `ShareWrite` — shown above.
- `ValidationError` — shown above.
