# Runs

A run is a single recording session. Slideshot drives a real browser through the `target_url` to satisfy your `goal`, records the workflow, and renders a polished demo video. Runs are created by an agent or by the CLI on your behalf and move through a small set of lifecycle states.

## Lifecycle

A run's `status` is one of:

- `queued`: The run was accepted and is waiting to be picked up.
- `running`: The run is actively executing the workflow.
- `awaiting_input`: The run paused mid-execution to ask for input (typically an OTP). It will resume once you submit a value, or fail when the input window expires.
- `succeeded`: Terminal. Artifacts are ready to download.
- `failed`: Terminal. The run could not complete the goal.
- `cancelled`: Terminal. The run was cancelled by you or by your agent.

While a run is active, it also surfaces a `progress_stage` you can show in a UI:

- `null`
- `normalizing_goal`
- `executing`
- `rendering_demo_video`
- `rendering_intro`
- `rendering_gif`

`progress_stage` is for display only. It never changes lifecycle semantics.

## Endpoints

- `POST /v1/agent/runs`: Create a recording run.
- `GET /v1/agent/runs/:id`: Read status, `progress_stage`, and the current `awaiting_input` prompt if any.
- `POST /v1/agent/runs/:id/input`: Submit requested input such as an OTP.
- `POST /v1/agent/runs/:id/cancel`: Cancel a queued or running run.
- `GET /v1/agent/runs/:id/artifacts`: List output files. See [Artifacts](/docs/api/artifacts).

## Create a run

The minimum payload is `target_url` and `goal`:

```bash
curl -X POST https://api.slideshot.ai/v1/agent/runs \
  -H "x-api-key: $SLIDESHOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "target_url": "https://app.example.com",
    "goal": "Create a new project and open the analytics dashboard.",
    "options": {
      "artifacts": { "gif": true }
    }
  }'
```

```json
{ "run_id": "11111111-2222-3333-4444-555555555555" }
```

`options` is optional. Each sub-object is independent: you can pass only `video`, only `auth`, etc.

## Run options

### `auth`

Controls how Slideshot signs into the target app during the recording. See [Credentials](/docs/api/credentials) and [Login to any web app](/docs/authentication).

- `{ "source": "none" }`: Do not log in.
- `{ "source": "default" }`: Use the default credential for the target domain.
- `{ "source": "saved", "id": "<credential_uuid>" }`: Use a specific saved credential.

### `video`

Visual controls applied at recording and render time. See [Customize video](/docs/customizing-video).

- `blur_emails`: `true` masks email-shaped strings during capture so they never appear in any artifact.
- `shortcuts`: `true` overlays mac-style key chips on completed keyboard actions.
- `cursor`: `"small" | "default" | "large" | "none"`. Controls the synthetic cursor rendered in the polished demo only; `raw.mp4` is unaffected.
- `size`: Output dimensions and inner framing. See [Video and content size](/docs/customizing-video/video-and-content-size).
- `background`: Solid or gradient canvas to frame the captured content on. See [Background](/docs/customizing-video/background).

### `artifacts`

- `gif`: `true` renders `demo.gif` from the final `demo.mp4`. Default `false`.

### `intro`

Prepends a branded title card to `demo.mp4`. See [Intro templates](/docs/customizing-video/intro-templates).

```json
{
  "intro": {
    "template": "simple-line-by-line-slide",
    "content": { "text": "Analytics, now in 60 seconds" },
    "style": {
      "background": { "type": "gradient", "from": "#0B1220", "to": "#101A33", "direction": "diagonal" },
      "textColor": "#FFFFFF"
    }
  }
}
```

The intro stage is best-effort: if it fails, the run still ships `demo.mp4` without the card.

## Poll for status

```bash
curl https://api.slideshot.ai/v1/agent/runs/$RUN_ID \
  -H "x-api-key: $SLIDESHOT_API_KEY"
```

Sample response while running:

```json
{
  "id": "11111111-2222-3333-4444-555555555555",
  "status": "running",
  "progress_stage": "executing",
  "awaiting_input": null,
  "target_url": "https://app.example.com",
  "goal": "Create a new project and open the analytics dashboard.",
  "created_at": "2026-05-11T12:00:00Z",
  "updated_at": "2026-05-11T12:01:14Z"
}
```

Poll at most every two seconds. From the CLI, `slideshot runs wait <RUN_ID>` handles polling for you.

## Handling awaiting input

When the recording browser reaches an OTP or magic-link step, the run pauses with `status="awaiting_input"` and the response includes an `awaiting_input` object:

```json
{
  "status": "awaiting_input",
  "awaiting_input": {
    "prompt": "Enter the 6-digit code from your email",
    "requested_at": "2026-05-11T12:02:00Z",
    "expires_at": "2026-05-11T12:07:00Z"
  }
}
```

Submit the value before `expires_at`:

```bash
curl -X POST https://api.slideshot.ai/v1/agent/runs/$RUN_ID/input \
  -H "x-api-key: $SLIDESHOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "value": "123456" }'
```

The endpoint returns `204` and the run resumes from where it paused. Submitting input to a run that is not in `awaiting_input` returns `409`.

The wait window itself is cut out of the final `demo.mp4` so viewers do not see it.

## Cancel a run

```bash
curl -X POST https://api.slideshot.ai/v1/agent/runs/$RUN_ID/cancel \
  -H "x-api-key: $SLIDESHOT_API_KEY"
```

Returns `204` on success. Returns `409` if the run has already reached a terminal state, and `404` if the run was not created by your API key.

The runner cancels cooperatively at checkpoint boundaries. Active recordings stop at the next safe point, terminate, and surface as `cancelled`.

## After the run succeeds

Once `status="succeeded"`, list artifacts:

```bash
curl https://api.slideshot.ai/v1/agent/runs/$RUN_ID/artifacts \
  -H "x-api-key: $SLIDESHOT_API_KEY"
```

See [Artifacts](/docs/api/artifacts) for the shape of the response and what each artifact contains.

## CLI shortcuts

The CLI maps each endpoint to a command. Use these when scripting:

```bash
slideshot runs create https://app.example.com \
  --goal "Open the analytics dashboard" \
  --options '{"artifacts":{"gif":true}}'

slideshot runs wait <RUN_ID>
slideshot runs artifacts <RUN_ID>
slideshot runs download <RUN_ID> --artifact demo.mp4 --dir ./artifacts
slideshot runs cancel <RUN_ID>
```

## Related

- [Credentials](/docs/api/credentials): save target-app credentials so runs can log in.
- [Artifacts](/docs/api/artifacts): list and download outputs after a run succeeds.
- [Feedback](/docs/api/feedback): send feedback tied to specific runs.
