---
title: "How do I pause and resume a playbook run?"
description: "TL;DR: Ballet can park a playbook run as Paused (suspended) and continue it later on the same run ID. Editors can pause between steps, or a Code step can call metaphor.waitForInput to wait for a human or external signal. Continue from Studio, or wake via the API with a server-issued requestId."
canonical_url: "https://docs.ballet.dev/articles/how-do-i-pause-and-resume-a-playbook-run-TK6ueiBF0d"
md_url: "https://docs.ballet.dev/articles/how-do-i-pause-and-resume-a-playbook-run-TK6ueiBF0d.md"
---
# How do I pause and resume a playbook run?

**TL;DR:** Ballet can park a playbook run as **Paused** (`suspended`) and continue it later on the **same run ID**. Editors can pause between steps, or a Code step can call `metaphor.waitForInput` to wait for a human or external signal. Continue from Studio, or wake via the API with a server-issued `requestId`.

## Who this is for

Builders who need human approval, long waits, or a mid-run pause without losing progress.

## What are the two pause modes?

In both cases:

* The run keeps the **same** `runId` (History shows one row; the badge flips Running → Pausing → Paused → Running).
* The sandbox is freed while parked so other runs keep processing.
* `suspended` is **not** a final status — you can Continue or Stop.

## How do I pause from Studio?


1. Start a run from the **Play** tab.
2. Click **Pause** while the run is running.
3. Ballet finishes the current step, then parks **before** the next one (`reason: operator_pause`).
4. Click **Continue** when you are ready. The run resumes from the next step — no reply payload is injected into that step.

Use **Stop** on a paused run to cancel it.

## How do I wait for approval inside a step?

In a Code step, checkpoint expensive work first, then park:

```javascript
const decision = await metaphor.waitForInput({
  prompt: 'Approve this invoice before posting?',
  details: extractedFields, // shown in Studio while waiting
  schema: {
    kind: 'choice',
    options: [
      { id: 'approve', label: 'Approve' },
      { id: 'reject', label: 'Reject' },
    ],
    multiSelect: false,
  },
});

if (decision?.id === 'reject') {
  const result = { ok: false, __next: 'abort' };
} else {
  const result = { ok: true, decision };
}
```

Rules:

* Do **not** busy-wait or poll Slack/email inside the step — that holds a sandbox.
* Always pass `details` so reviewers (and notifiers) can see what to approve.
* On wake, `waitForInput` returns the `reply` payload (for example `{ id: 'approve', label: 'Approve' }`).

## How does external data arrive on Continue?

For HITL parks, the wake payload is the `reply` body — not a new set of step `input` mappings.

* Studio Continue / choice → that choice becomes the return value of `waitForInput`.
* An external system (Slack button, webhook worker) sends the same payload via `POST /api/runs/:runId/reply`.
* Optionally pass `input` on wake to override the run's `flow.input` for the continued execution.

Discover wake parameters from **History → run detail** (or `GET /api/runs/:id`) while status is Paused:

Past plays also show an **API resume (curl)** snippet with `runId` and `requestId` filled in.

## What if I need Slack or email approval?

Slack and email are **notifiers** for the same park — they are not a second pause API. A notifier posts Approve/Reject, then calls the wake API with the parked `requestId`. Studio Continue uses that same path.

For the full HTTP contract, curl examples, and notifier pattern, see [How do I wake a suspended run with reply or resume?](/articles/how-do-i-wake-a-suspended-run-with-reply-or-resume-EDYuheV1x4).

## Related articles

* [How do I wake a suspended run with reply or resume?](/articles/how-do-i-wake-a-suspended-run-with-reply-or-resume-EDYuheV1x4)
* [How do I run a playbook?](/articles/how-do-i-run-a-playbook-dChtouCzok)
* [How do I read runs and run history?](/articles/how-do-i-read-runs-and-run-history-WukfYP5du3)
* [Recipe: Invoice and expense processing](/articles/recipe-invoice-and-expense-processing-MZMvhq3VlS)
* [Ballet glossary](/articles/ballet-glossary-uLRIjERYoU)
