Skip to main content
Documentation

Minolith Runbooks API

The Runbooks service stores multi-step procedures that agents execute with persistent progress tracking. An agent loads a runbook, works through each step, records outcomes, and picks up exactly where it left off if interrupted. The agent can't forget where it was.

A runbook is a reusable template. It defines a procedure — ordered steps with optional branching, variables, and checkpoints. Each time the procedure is followed, a run is created — a specific execution with its own state, variable values, and step-by-step progress.

Base URL: https://api.minolith.io/v1/runbooks

Authentication: All endpoints require an API key via the Authorization header:

Authorization: Bearer mlth_your_api_key_here

Pricing: Creating a runbook template costs 5 credits ($0.05). Starting a run is free. All other operations — reading, updating, step management, progression, filtering — are free.


Core Concepts

Runbook (Template)

A reusable procedure definition containing:

  • Steps — ordered instructions with optional branching
  • Variables — placeholders filled in when a run starts ({version}, {environment})
  • Metadata — name, description, category, tags

A runbook can be run many times. Each execution creates a Run.

Run (Execution)

A specific execution of a runbook containing:

  • Variable values — the actual values for this execution
  • Step states — which steps are pending, active, completed, skipped, or failed
  • Step outcomes — what happened at each step (notes, outputs, timestamps)
  • Overall statusrunning, paused, completed, failed, cancelled

Step Types

Type Purpose
action Do something. The default step type.
check Verify something. Use outcome values (pass/fail) to branch.
gate Wait for human input. The dashboard provides approve/reject buttons. The agent reads the outcome via get_current_step and then calls advance_step.
branch Conditional routing based on outcome. Routes to different steps depending on the result.

Branching

Steps can route to different next steps based on the outcome. Each step has:

  • next_default — the step to go to if no outcome-based routing matches (or for linear flow)
  • next_on_outcome — a map of outcome value → step ID for conditional routing
Step 2: "Run test suite" (type: check)
  → outcome "pass" → Step 4: "Deploy"
  → outcome "fail" → Step 3: "Fix failures"

Step 3: "Fix failures"
  → outcome "done" → Step 2: "Run test suite" (retry)

Important: When using next_on_outcome, you must provide explicit step targets for all outcomes. A null value in next_on_outcome means "end of runbook" — it does NOT mean "continue to next step." If you want an outcome to continue the default flow, specify the target step ID explicitly or use a step:ref reference.

Variables

Variables are placeholders in step instructions. They are defined on the runbook template and filled in when a run starts.

{
  "variables": [
    {"name": "version", "description": "Release version", "required": true},
    {"name": "environment", "required": false, "default": "production"}
  ]
}

In step instructions, use {variable_name}:

"Deploy {version} to {environment}"

When a run starts with {"version": "2.5.0"}, the instruction resolves to:

"Deploy 2.5.0 to production"

Step References

When creating a runbook with all steps in a single request, steps don't have IDs yet. Use ref labels to reference steps in next_on_outcome:

{
  "steps": [
    {"label": "Run tests", "type": "check", "next_on_outcome": {"pass": "step:deploy", "fail": "step:fix"}},
    {"label": "Fix failures", "ref": "fix", "next_on_outcome": {"done": "step:tests"}},
    {"label": "Deploy", "ref": "deploy"}
  ]
}

The API resolves step:ref_label to actual step IDs on creation. Once created, all routing uses step IDs.


Endpoints

Create Runbook

POST /v1/runbooks/

Creates a new runbook template with steps. Costs 1 credit.

Request body:

{
  "name": "Deploy to Production",
  "description": "Standard production deployment procedure.",
  "category": "deployment",
  "tags": ["production", "release"],
  "variables": [
    {"name": "version", "description": "Release version", "required": true},
    {"name": "branch", "description": "Git branch", "required": true, "default": "main"}
  ],
  "steps": [
    {"label": "Pull latest code", "instruction": "Pull the latest code from {branch}.", "type": "action"},
    {"label": "Run test suite", "instruction": "Run the full test suite.", "type": "check", "next_on_outcome": {"pass": "step:deploy", "fail": "step:fix"}},
    {"label": "Fix test failures", "instruction": "Review and fix failures.", "ref": "fix", "next_on_outcome": {"done": "step:tests"}},
    {"label": "Deploy application", "instruction": "Deploy {version} to production.", "ref": "deploy"},
    {"label": "Smoke test", "instruction": "Verify critical endpoints.", "type": "check"},
    {"label": "Confirm", "instruction": "Confirm deployment of {version}.", "type": "gate"}
  ]
}
Field Type Required Description
name string yes Max 255 characters
description string no Max 5,000 characters
category string no Max 100 characters, lowercase alphanumeric + hyphens
tags array no Up to 20 tags, each max 100 chars, lowercase alphanumeric + hyphens
variables array no Up to 20 variable definitions (see Variables)
steps array yes 1–100 steps (see Step Fields)

Step fields:

Field Type Required Description
label string yes Short name, max 255 characters
instruction string yes Full instruction, max 5,000 characters. May contain {variable} placeholders.
type string no action (default), check, gate, branch
required boolean no Whether the step can be skipped. Default true.
ref string no Reference label for targeting from other steps' next_on_outcome
next_on_outcome object no Map of outcome value → step ref or step ID
metadata object no Step-specific configuration

Response (201 Created):

{
  "data": {
    "id": "rnb_a1b2c3d4e5f6",
    "name": "Deploy to Production",
    "description": "Standard production deployment procedure.",
    "category": "deployment",
    "tags": ["production", "release"],
    "variables": [...],
    "steps": [
      {"id": "rbs_001", "position": 1, "label": "Pull latest code", "type": "action", "required": true, "next_default": "rbs_002", "next_on_outcome": null},
      {"id": "rbs_002", "position": 2, "label": "Run test suite", "type": "check", "required": true, "next_default": "rbs_003", "next_on_outcome": {"pass": "rbs_004", "fail": "rbs_003"}}
    ],
    "is_archived": false,
    "created_at": "2026-03-17 10:00:00",
    "updated_at": "2026-03-17 10:00:00"
  }
}

Default step wiring: Steps without explicit next_default are automatically wired to the next step by position. The last step has next_default: null (end of procedure).

Error responses:

  • 402 — Spending cap exceeded.
  • 422 — Validation error.

List Runbooks

GET /v1/runbooks/

Returns runbook templates. Excludes archived runbooks by default.

Query parameters:

Parameter Type Description
category string Filter by category
tags string Filter by tags (comma-separated, matches ANY)
is_archived boolean Include archived runbooks (true to show only archived)
limit integer 1–100, default 20
cursor string Cursor for pagination

Response (200 OK):

{
  "data": [
    {
      "id": "rnb_a1b2c3d4e5f6",
      "name": "Deploy to Production",
      "description": "...",
      "category": "deployment",
      "tags": ["production"],
      "step_count": 6,
      "is_archived": false,
      "created_at": "2026-03-17 10:00:00",
      "updated_at": "2026-03-17 10:00:00"
    }
  ],
  "pagination": {"has_more": false, "next_cursor": null, "limit": 20}
}

Get Runbook

GET /v1/runbooks/:id

Returns a runbook with all its steps.

Response (200 OK): Same format as the create response.

Error responses:

  • 404 — Runbook not found.

Update Runbook

PUT /v1/runbooks/:id

Updates runbook metadata. Name, description, category, tags, and variables are always editable. Only include fields you want to change.

Steps cannot be added, removed, or reordered if any runs exist. Step labels and instructions can always be edited via the step endpoints.

Request body (partial update):

{
  "name": "Updated name",
  "category": "new-category",
  "tags": ["updated", "tags"]
}

Response (200 OK): Returns the full updated runbook.


Delete Runbook

DELETE /v1/runbooks/:id

Permanently deletes a runbook, its steps, and all runs. Cannot delete a runbook with active runs (status running or paused) — archive it instead.

Response (204 No Content).

Error responses:

  • 404 — Runbook not found.
  • 409 — Runbook has active runs.
{
  "error": {
    "code": "conflict",
    "message": "Runbook 'rnb_xxx' cannot be deleted — it has 2 active run(s). Archive it instead.",
    "docs": "https://docs.minolith.io/api/runbooks#delete-runbook"
  }
}

Archive Runbook

POST /v1/runbooks/:id/archive

Archives a runbook. Archived runbooks are excluded from list results by default and cannot have new runs started.

Response (200 OK):

{"data": {"message": "Runbook archived."}}

Add Step

POST /v1/runbooks/:id/steps

Adds a step to a runbook. Blocked if any runs exist.

Request body:

{
  "label": "New step",
  "instruction": "Do this thing.",
  "type": "action",
  "required": true
}

Response (201 Created): Returns the created step.


Update Step

PUT /v1/runbooks/:id/steps/:step_id

Updates a step. Label and instruction are always editable. Structural fields (type, required, ref, next_default, next_on_outcome, metadata) are only editable if no runs exist.

Response (200 OK): Returns the updated step.


Delete Step

DELETE /v1/runbooks/:id/steps/:step_id

Removes a step. Blocked if any runs exist.

Response (204 No Content).


Reorder Steps

PUT /v1/runbooks/:id/steps/reorder

Reorders steps. Blocked if any runs exist.

Request body:

{
  "step_ids": ["rbs_003", "rbs_001", "rbs_002"]
}

Response (200 OK): Returns the reordered steps.


Start Run

POST /v1/runbooks/:id/runs

Starts a new execution of a runbook. Costs 1 credit. Provide variable values for this run. Returns the first step to execute.

Request body:

{
  "variables": {
    "version": "2.5.0",
    "branch": "release/2.5.0"
  }
}

Response (201 Created):

{
  "data": {
    "id": "run_x1y2z3w4",
    "runbook_id": "rnb_a1b2c3d4e5f6",
    "runbook_name": "Deploy to Production",
    "status": "running",
    "variables": {"version": "2.5.0", "branch": "release/2.5.0"},
    "current_step": {
      "id": "rbs_001",
      "label": "Pull latest code",
      "instruction": "Pull the latest code from release/2.5.0.",
      "type": "action",
      "required": true,
      "status": "active"
    },
    "progress": {
      "total_steps": 6,
      "completed": 0,
      "skipped": 0,
      "failed": 0,
      "remaining": 6
    },
    "started_at": "2026-03-17 14:00:00"
  }
}

Error responses:

  • 402 — Spending cap exceeded.
  • 404 — Runbook not found.
  • 409 — Runbook is archived or has no steps.
  • 422 — Missing required variable.

List Runs

GET /v1/runbooks/runs

Lists runs across all runbooks.

Query parameters:

Parameter Type Description
status string Filter by status (comma-separated): running, paused, completed, failed, cancelled
runbook_id string Filter by runbook template
started_after string ISO date/datetime
limit integer 1–100, default 20
cursor string Cursor for pagination

Response (200 OK):

{
  "data": [
    {
      "id": "run_x1y2z3w4",
      "runbook_id": "rnb_a1b2c3d4e5f6",
      "runbook_name": "Deploy to Production",
      "status": "running",
      "progress": {"total_steps": 6, "completed": 3, "skipped": 0, "failed": 0, "remaining": 3},
      "started_at": "2026-03-17 14:00:00",
      "completed_at": null
    }
  ],
  "pagination": {"has_more": false, "next_cursor": null, "limit": 20}
}

Get Run

GET /v1/runbooks/runs/:run_id

Returns a run with all step states, instructions (with resolved variables), outcomes, notes, and outputs.

Response (200 OK):

{
  "data": {
    "id": "run_x1y2z3w4",
    "runbook_id": "rnb_a1b2c3d4e5f6",
    "runbook_name": "Deploy to Production",
    "status": "running",
    "variables": {"version": "2.5.0"},
    "steps": [
      {
        "step_id": "rbs_001",
        "label": "Pull latest code",
        "instruction": "Pull the latest code from release/2.5.0.",
        "type": "action",
        "required": true,
        "position": 1,
        "status": "completed",
        "outcome": "done",
        "notes": "Pulled commit abc123.",
        "output": null,
        "started_at": "2026-03-17 14:00:00",
        "completed_at": "2026-03-17 14:02:00"
      }
    ],
    "progress": {"total_steps": 6, "completed": 3, "skipped": 0, "failed": 0, "remaining": 3},
    "started_at": "2026-03-17 14:00:00",
    "completed_at": null
  }
}

Get Current Step

GET /v1/runbooks/runs/:run_id/current

This is the primary resume endpoint. Call this at the start of any session to know exactly where you are in a procedure and what to do next. Returns the current step instruction, progress summary, completed steps, and run variables.

Response (200 OK):

{
  "data": {
    "run_id": "run_x1y2z3w4",
    "run_status": "running",
    "current_step": {
      "id": "rbs_004",
      "label": "Deploy application",
      "instruction": "Deploy 2.5.0 to production.",
      "type": "action",
      "required": true,
      "status": "active",
      "outcome": null
    },
    "progress": {"total_steps": 6, "completed": 3, "skipped": 0, "failed": 0, "remaining": 3},
    "completed_steps": [
      {"id": "rbs_001", "label": "Pull latest code", "status": "completed", "outcome": "done", "completed_at": "2026-03-17 14:02:00"},
      {"id": "rbs_002", "label": "Run test suite", "status": "completed", "outcome": "pass", "completed_at": "2026-03-17 14:05:00"}
    ],
    "variables": {"version": "2.5.0", "branch": "release/2.5.0"}
  }
}

When the run is completed, current_step is null.


Advance Step

POST /v1/runbooks/runs/:run_id/advance

Marks the current step as completed and advances to the next step. The outcome value determines which step comes next when branching is configured.

Request body:

{
  "outcome": "pass",
  "notes": "All 247 tests passed. No warnings.",
  "output": {
    "test_count": 247,
    "failures": 0,
    "duration_seconds": 34
  }
}
Field Type Required Description
outcome string no Step outcome, used for branching. Default "done". Max 100 characters.
notes string no What happened during this step. Max 10,000 characters.
output object no Structured output data (command results, file paths, etc.). Max 50KB serialised.

Response (200 OK): Same format as Get Current Step, showing the next step.

Advance logic:

  1. Mark current step as completed with the provided outcome, notes, and output
  2. Check next_on_outcome — if the outcome matches a key, go to that step
  3. If no match (or no next_on_outcome), go to next_default
  4. If next step is null, the run is complete
  5. Return the updated run state

Error responses:

  • 404 — Run not found.
  • 409 — Run is not active (paused, completed, failed, or cancelled).

Skip Step

POST /v1/runbooks/runs/:run_id/skip

Skips the current step. Only works if the step is not required. Advances to the next step via the default route.

Request body:

{
  "notes": "Skipping database backup — no schema changes in this release."
}

Response (200 OK): Same format as Get Current Step.

Error responses:

  • 409 — Run is not active.
  • 422 — Step is required and cannot be skipped.

Fail Step

POST /v1/runbooks/runs/:run_id/fail

Marks the current step as failed. This also sets the run status to failed. The failure is recorded in the step's notes and output. The run can be resumed later.

Request body:

{
  "notes": "Migration failed: column already exists.",
  "output": {"error": "SQLSTATE[42S21]", "migration": "2026_03_17_add_column"}
}

Response (200 OK): Same format as Get Current Step.


Update Run

PUT /v1/runbooks/runs/:run_id

Updates run status. Use to pause, resume, or cancel a run.

Request body:

{"status": "paused"}

Valid status transitions:

From Allowed To
running paused, cancelled
paused running, cancelled
failed running (resumes — reactivates the failed step for retry)
completed (none)
cancelled (none)

Response (200 OK):

{"data": {"id": "run_x1y2z3w4", "status": "paused"}}

Error responses:

  • 409 — Invalid status transition.

Validation Rules

Field Constraints
name Required, max 255 characters
description Max 5,000 characters
category Max 100 characters, lowercase alphanumeric + hyphens
steps 1–100 steps per runbook
step.label Required, max 255 characters
step.instruction Required, max 5,000 characters
step.type action, check, gate, branch (default: action)
variables Max 20 per runbook
variable.name Required, max 50 characters, alphanumeric + underscore
tags Max 20, each max 100 characters, lowercase alphanumeric + hyphens
outcome Max 100 characters
notes Max 10,000 characters
output Max 50KB serialised

Editing Runbooks With Existing Runs

Once a runbook has any runs (regardless of status), structural changes are restricted to protect run integrity:

Always editable: name, description, category, tags, variables, step labels, step instructions.

Blocked if runs exist: adding steps, removing steps, reordering steps, changing step type/required/ref/next_default/next_on_outcome.

To make structural changes, delete all runs first, or create a new runbook.


Gate Steps

Gate steps are the human-in-the-loop mechanism. When a run reaches a gate step:

  1. The step becomes active — the agent sees it via get_current_step
  2. A human approves or rejects via the dashboard (sets the step's outcome to approved or rejected)
  3. The agent calls get_current_step and sees the outcome on the active step
  4. The agent calls advance_step with that outcome to continue

The dashboard does NOT advance the run — the agent does. The dashboard just records the human's decision. This keeps the agent autonomous and in control of the execution flow.


Error Responses

All errors follow the standard Minolith error format. Runbooks-specific error codes:

Code HTTP Message
not_found 404 Runbook or run not found in this project.
conflict 409 Run is not active, runbook has active runs, or runbook is archived.
validation_error 422 Step is required (can't skip), missing variable, invalid step type, too many steps.
spending_cap_exceeded 402 Creating runbook or starting run would exceed spending cap.

ID Formats

Entity Prefix Example
Runbook rnb_ rnb_a1b2c3d4e5f6
Step rbs_ rbs_a1b2c3d4e5f6
Run run_ run_a1b2c3d4e5f6
Run Step rrs_ rrs_a1b2c3d4e5f6

Credit Costs

Action Credits Cost
Create runbook template 5 $0.05
Start run 0 Free
All other operations 0 Free

Rate Limiting

All API endpoints are rate-limited to 100 requests per minute per API key. See Platform API — Rate Limiting.


MCP Tools

The Runbooks service is available via MCP for direct integration with AI coding tools.

create_runbook

Create a new runbook template. Define the procedure name, steps, and optional variables. Steps are wired linearly by default — only specify next_on_outcome for branching steps.

Parameters:

Parameter Type Required Description
name string yes Runbook name
description string no What this procedure does
category string no Category for grouping
tags array no Tags for filtering
variables array no Variable definitions
steps array yes Step definitions

list_runbooks

List available runbook templates. Use to find an existing procedure before creating a new one.

Parameters:

Parameter Type Required Description
category string no Filter by category
tags array no Filter by tags
limit integer no Max results (default 20, max 100)

start_run

Start a new execution of a runbook. Provide variable values. Returns the first step to execute.

Parameters:

Parameter Type Required Description
runbook_id string yes Runbook template ID
variables object no Variable values for this run

get_current_step

The primary resume endpoint. Call this at session start to know where you are and what to do next. Returns current step, progress, completed steps, and variables.

Parameters:

Parameter Type Required Description
run_id string yes Run ID

advance_step

Complete the current step and advance. Provide outcome (for branching), notes, and optional output.

Parameters:

Parameter Type Required Description
run_id string yes Run ID
outcome string no Step outcome for branching. Default "done".
notes string no What happened during this step.
output object no Structured output data.

skip_step

Skip the current step. Only works for non-required steps.

Parameters:

Parameter Type Required Description
run_id string yes Run ID
notes string no Why this step is being skipped.

fail_step

Mark the current step as failed. Also marks the run as failed. The run can be resumed later.

Parameters:

Parameter Type Required Description
run_id string yes Run ID
notes string no What went wrong.
output object no Error details or diagnostics.

pause_run

Pause a running run. Use when ending a session mid-procedure or when waiting for an external dependency. The run can be resumed later by calling get_current_step and continuing to advance.

Parameters:

Parameter Type Required Description
run_id string yes Run ID
reason string no Why the run is being paused (e.g. "session ending", "waiting for approval").

list_runs

List runs. Filter by status to find active, paused, or failed runs. Use at session start to check for in-progress procedures.

Parameters:

Parameter Type Required Description
status string no Filter by status (comma-separated)
runbook_id string no Filter by runbook template
limit integer no Max results (default 20, max 100)

Example Workflows

Agent executes a deployment

1. Agent calls list_runbooks with category: "deployment"
2. Finds "Deploy to Production" (rnb_xxx)
3. Agent calls start_run with variables: {version: "2.5.0"}
4. API returns first step: "Pull latest code"
5. Agent executes the step
6. Agent calls advance_step with outcome: "done"
7. API returns next step: "Run test suite"
8. Agent runs tests, they pass
9. Agent calls advance_step with outcome: "pass"
10. API routes to "Deploy" (skipping the failure branch)
11. Agent deploys, advances through remaining steps
12. At the gate step, agent checks get_current_step — sees outcome from dashboard
13. Agent calls advance_step, run completes

Agent resumes an interrupted run

1. New session starts
2. Agent calls list_runs with status: "running,paused"
3. Finds an active run at step 5
4. Agent calls get_current_step — gets full context: what's done, what's next, variables
5. Agent picks up exactly where it left off

Agent creates a runbook from experience

1. Developer walks through a process with the agent
2. At the end: "create a runbook from what we just did"
3. Agent constructs steps from the conversation
4. Agent calls create_runbook with the structured procedure
5. Next time: agent loads and follows the runbook consistently

Last updated: 6 Apr 2026