{
  "slug": "pilot/sdk/rust",
  "title": "Pilot Rust SDK",
  "description": "Async Rust client for the Cuitty Pilot API — manage playbooks, runs, and providers with reqwest and serde.",
  "url": "https://cuitty.com/docs/pilot/sdk/rust",
  "markdown_url": "https://cuitty.com/docs/pilot/sdk/rust.md",
  "json_url": "https://cuitty.com/docs/pilot/sdk/rust.json",
  "frontmatter": {
    "title": "Pilot Rust SDK",
    "description": "Async Rust client for the Cuitty Pilot API — manage playbooks, runs, and providers with reqwest and serde.",
    "order": 14,
    "section": "Pilot",
    "updatedAt": "2026-06-01"
  },
  "headings": [
    {
      "depth": 1,
      "slug": "pilot-rust-sdk",
      "text": "Pilot Rust SDK"
    },
    {
      "depth": 2,
      "slug": "install",
      "text": "Install"
    },
    {
      "depth": 2,
      "slug": "quick-start",
      "text": "Quick start"
    },
    {
      "depth": 2,
      "slug": "pilotclient",
      "text": "PilotClient"
    },
    {
      "depth": 2,
      "slug": "playbooks",
      "text": "Playbooks"
    },
    {
      "depth": 2,
      "slug": "runs",
      "text": "Runs"
    },
    {
      "depth": 2,
      "slug": "types",
      "text": "Types"
    },
    {
      "depth": 3,
      "slug": "core-structs",
      "text": "Core structs"
    },
    {
      "depth": 3,
      "slug": "request-structs",
      "text": "Request structs"
    },
    {
      "depth": 2,
      "slug": "error-handling",
      "text": "Error handling"
    },
    {
      "depth": 2,
      "slug": "see-also",
      "text": "See also"
    }
  ],
  "body_markdown": "# Pilot Rust SDK\n\n`cuitty-pilot-sdk` is an async Rust client for the Pilot API. It uses `reqwest` for HTTP, `serde` for JSON serialization, and `thiserror` for typed errors.\n\n## Install\n\nAdd to your `Cargo.toml`:\n\n```toml\n[dependencies]\ncuitty-pilot-sdk = { path = \"../packages/sdk-rust\" }\n# or when published:\n# cuitty-pilot-sdk = \"0.1\"\ntokio = { version = \"1\", features = [\"rt-multi-thread\", \"macros\"] }\n```\n\n## Quick start\n\n```rust\nuse cuitty_pilot_sdk::{PilotClient, StartRunRequest, PilotError};\n\n#[tokio::main]\nasync fn main() -> Result<(), PilotError> {\n    let client = PilotClient::new(\n        \"http://localhost:4320\",\n        Some(\"your-auth-token\".into()),\n    );\n\n    // List all playbooks\n    let playbooks = client.list_playbooks(None).await?;\n\n    // Start a run\n    let resp = client.start_run(&StartRunRequest {\n        playbook_id: \"cloudflare.dns.add-a-record\".into(),\n        mode: Some(\"autonomous\".into()),\n        inputs: Some(serde_json::json!({\n            \"zone\": \"example.com\",\n            \"record_name\": \"app\",\n            \"ip_address\": \"1.2.3.4\"\n        })),\n        ..Default::default()\n    }).await?;\n\n    println!(\"Run started: {} ({})\", resp.id, resp.status);\n\n    // Get run details\n    let run = client.get_run(&resp.id).await?;\n    println!(\"Run status: {}\", run.status);\n\n    Ok(())\n}\n```\n\n## PilotClient\n\nThe main entry point. All methods are `async` and return `Result<T, PilotError>`.\n\n```rust\n// Without auth\nlet client = PilotClient::new(\"http://localhost:4320\", None);\n\n// With bearer token\nlet client = PilotClient::new(\n    \"http://localhost:4320\",\n    Some(\"ey...\".into()),\n);\n```\n\n| Method | Returns | Description |\n|--------|---------|-------------|\n| `health()` | `HealthStatus` | Check server health |\n| `list_playbooks(target)` | `Vec<PlaybookSummary>` | List playbooks, optionally filtered |\n| `get_playbook(id)` | `Playbook` | Get playbook by ID (latest version) |\n| `create_playbook(req)` | `CreatePlaybookResponse` | Create a new playbook |\n| `update_playbook(id, req)` | `UpdatePlaybookResponse` | Update (version-bump) a playbook |\n| `delete_playbook(id)` | `DeletePlaybookResponse` | Delete all versions |\n| `start_run(req)` | `StartRunResponse` | Start a new run |\n| `list_runs(status, playbook_id, limit)` | `Vec<Run>` | List runs with optional filters |\n| `get_run(id)` | `Run` | Get run details including steps |\n| `abort_run(id)` | `AbortRunResponse` | Abort a running or queued run |\n| `approve_run(id, req)` | `ApproveResponse` | Submit approval decision for a step |\n| `list_providers()` | `Vec<Provider>` | List all provider profiles |\n\n## Playbooks\n\n```rust\n// List all\nlet playbooks = client.list_playbooks(None).await?;\n\n// Filter by target\nlet cf = client.list_playbooks(Some(\"cloudflare\")).await?;\n\n// Get one\nlet pb = client.get_playbook(\"cloudflare.dns.add-a-record\").await?;\n\n// Create\nlet resp = client.create_playbook(&CreatePlaybookRequest {\n    target: \"cloudflare\".into(),\n    title: \"Add CNAME record\".into(),\n    yaml: playbook_yaml,\n    authored_by: Some(\"human\".into()),\n}).await?;\n\n// Update\nclient.update_playbook(\"cloudflare.dns.add-cname\", &UpdatePlaybookRequest {\n    yaml: updated_yaml,\n    target: None,\n    title: None,\n    authored_by: None,\n}).await?;\n\n// Delete\nclient.delete_playbook(\"cloudflare.dns.add-cname\").await?;\n```\n\n## Runs\n\n```rust\n// Start a run\nlet resp = client.start_run(&StartRunRequest {\n    playbook_id: \"cloudflare.dns.add-a-record\".into(),\n    mode: Some(\"interactive\".into()),\n    inputs: Some(serde_json::json!({\n        \"zone\": \"example.com\",\n        \"record_name\": \"api\",\n        \"ip_address\": \"1.2.3.4\"\n    })),\n    provider_profile_id: Some(\"cf-prod\".into()),\n    ..Default::default()\n}).await?;\n\n// Get run with steps\nlet run = client.get_run(&resp.id).await?;\nif let Some(steps) = &run.steps {\n    for step in steps {\n        println!(\"{}: {} ({}ms)\", step.step_id, step.status,\n            step.duration_ms.unwrap_or(0));\n    }\n}\n\n// List recent running runs\nlet running = client.list_runs(Some(\"running\"), None, Some(10)).await?;\n\n// Abort\nclient.abort_run(&resp.id).await?;\n\n// Approve a step\nclient.approve_run(&resp.id, &ApproveRequest {\n    step_id: \"save\".into(),\n    decision: Some(\"approve\".into()),\n}).await?;\n```\n\n## Types\n\n### Core structs\n\n| Struct | Key fields |\n|--------|-----------|\n| `Playbook` | `id`, `version`, `target`, `title`, `document_yaml`, `authored_by`, `created_at` |\n| `PlaybookSummary` | `id`, `version`, `target`, `title`, `authored_by` |\n| `Run` | `id`, `project_id`, `playbook_id`, `mode`, `status`, `inputs_json`, `outputs_json`, `steps: Option<Vec<RunStep>>` |\n| `RunStep` | `id`, `run_id`, `step_id`, `action`, `status`, `ai_used`, `duration_ms`, `error_message` |\n| `Provider` | `id`, `project_id`, `provider`, `label`, `base_url`, `last_authenticated`, `expires_at` |\n| `HealthStatus` | `status`, `database`, `driver_pool`, `provider_sessions`, `last_checked` |\n\n### Request structs\n\n| Struct | Fields |\n|--------|--------|\n| `StartRunRequest` | `playbook_id`, `version?`, `mode?`, `inputs?` (`serde_json::Value`), `provider_profile_id?`, `project_id?` |\n| `CreatePlaybookRequest` | `target`, `title`, `yaml`, `authored_by?` |\n| `UpdatePlaybookRequest` | `yaml`, `target?`, `title?`, `authored_by?` |\n| `ApproveRequest` | `step_id`, `decision?` |\n\nAll structs derive `Debug`, `Clone`, `Serialize`, and `Deserialize`.\n\n## Error handling\n\nThe SDK uses a single `PilotError` enum with three variants:\n\n```rust\nuse cuitty_pilot_sdk::PilotError;\n\nmatch client.start_run(&req).await {\n    Ok(resp) => println!(\"Started: {}\", resp.id),\n    Err(PilotError::Api { status, message }) => {\n        eprintln!(\"API error {}: {}\", status, message);\n    }\n    Err(PilotError::Connection(err)) => {\n        eprintln!(\"Network error: {}\", err);\n    }\n    Err(PilotError::Other(msg)) => {\n        eprintln!(\"Unexpected: {}\", msg);\n    }\n}\n```\n\n| Variant | Fields | When |\n|---------|--------|------|\n| `Api` | `status: u16`, `message: String` | Non-2xx HTTP response |\n| `Connection` | wraps `reqwest::Error` | Network or timeout failure |\n| `Other` | `String` | Any other error |\n\n## See also\n\n- [JavaScript SDK](/docs/pilot/sdk/javascript) — TypeScript client with event streaming\n- [Playbook reference](/docs/pilot/playbook-reference) — YAML schema for playbook documents\n- [Quickstart](/docs/pilot/quickstart) — record and replay your first workflow",
  "body_html": "<h1 id=\"pilot-rust-sdk\">Pilot Rust SDK</h1>\n<p><code>cuitty-pilot-sdk</code> is an async Rust client for the Pilot API. It uses <code>reqwest</code> for HTTP, <code>serde</code> for JSON serialization, and <code>thiserror</code> for typed errors.</p>\n<h2 id=\"install\">Install</h2>\n<p>Add to your <code>Cargo.toml</code>:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"toml\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">[</span><span style=\"color:#B392F0\">dependencies</span><span style=\"color:#E1E4E8\">]</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">cuitty-pilot-sdk = { path = </span><span style=\"color:#9ECBFF\">\"../packages/sdk-rust\"</span><span style=\"color:#E1E4E8\"> }</span></span>\n<span class=\"line\"><span style=\"color:#6A737D\"># or when published:</span></span>\n<span class=\"line\"><span style=\"color:#6A737D\"># cuitty-pilot-sdk = \"0.1\"</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">tokio = { version = </span><span style=\"color:#9ECBFF\">\"1\"</span><span style=\"color:#E1E4E8\">, features = [</span><span style=\"color:#9ECBFF\">\"rt-multi-thread\"</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#9ECBFF\">\"macros\"</span><span style=\"color:#E1E4E8\">] }</span></span></code></pre>\n<h2 id=\"quick-start\">Quick start</h2>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"rust\"><code><span class=\"line\"><span style=\"color:#F97583\">use</span><span style=\"color:#B392F0\"> cuitty_pilot_sdk</span><span style=\"color:#F97583\">::</span><span style=\"color:#E1E4E8\">{</span><span style=\"color:#B392F0\">PilotClient</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#B392F0\">StartRunRequest</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#B392F0\">PilotError</span><span style=\"color:#E1E4E8\">};</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">#[tokio</span><span style=\"color:#F97583\">::</span><span style=\"color:#E1E4E8\">main]</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">async</span><span style=\"color:#F97583\"> fn</span><span style=\"color:#B392F0\"> main</span><span style=\"color:#E1E4E8\">() </span><span style=\"color:#F97583\">-></span><span style=\"color:#B392F0\"> Result</span><span style=\"color:#E1E4E8\">&#x3C;(), </span><span style=\"color:#B392F0\">PilotError</span><span style=\"color:#E1E4E8\">> {</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">    let</span><span style=\"color:#E1E4E8\"> client </span><span style=\"color:#F97583\">=</span><span style=\"color:#B392F0\"> PilotClient</span><span style=\"color:#F97583\">::</span><span style=\"color:#B392F0\">new</span><span style=\"color:#E1E4E8\">(</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">        \"http://localhost:4320\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">        Some</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"your-auth-token\"</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">into</span><span style=\"color:#E1E4E8\">()),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    );</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6A737D\">    // List all playbooks</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">    let</span><span style=\"color:#E1E4E8\"> playbooks </span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\"> client</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">list_playbooks</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#B392F0\">None</span><span style=\"color:#E1E4E8\">)</span><span style=\"color:#F97583\">.await?</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6A737D\">    // Start a run</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">    let</span><span style=\"color:#E1E4E8\"> resp </span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\"> client</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">start_run</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#F97583\">&#x26;</span><span style=\"color:#B392F0\">StartRunRequest</span><span style=\"color:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">        playbook_id</span><span style=\"color:#F97583\">:</span><span style=\"color:#9ECBFF\"> \"cloudflare.dns.add-a-record\"</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">into</span><span style=\"color:#E1E4E8\">(),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">        mode</span><span style=\"color:#F97583\">:</span><span style=\"color:#B392F0\"> Some</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"autonomous\"</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">into</span><span style=\"color:#E1E4E8\">()),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">        inputs</span><span style=\"color:#F97583\">:</span><span style=\"color:#B392F0\"> Some</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#B392F0\">serde_json</span><span style=\"color:#F97583\">::</span><span style=\"color:#B392F0\">json!</span><span style=\"color:#E1E4E8\">({</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">            \"zone\"</span><span style=\"color:#F97583\">:</span><span style=\"color:#9ECBFF\"> \"example.com\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">            \"record_name\"</span><span style=\"color:#F97583\">:</span><span style=\"color:#9ECBFF\"> \"app\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">            \"ip_address\"</span><span style=\"color:#F97583\">:</span><span style=\"color:#9ECBFF\"> \"1.2.3.4\"</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">        })),</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">        ..</span><span style=\"color:#B392F0\">Default</span><span style=\"color:#F97583\">::</span><span style=\"color:#B392F0\">default</span><span style=\"color:#E1E4E8\">()</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    })</span><span style=\"color:#F97583\">.await?</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#B392F0\">    println!</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"Run started: {} ({})\"</span><span style=\"color:#E1E4E8\">, resp</span><span style=\"color:#F97583\">.</span><span style=\"color:#E1E4E8\">id, resp</span><span style=\"color:#F97583\">.</span><span style=\"color:#E1E4E8\">status);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6A737D\">    // Get run details</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">    let</span><span style=\"color:#E1E4E8\"> run </span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\"> client</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">get_run</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#F97583\">&#x26;</span><span style=\"color:#E1E4E8\">resp</span><span style=\"color:#F97583\">.</span><span style=\"color:#E1E4E8\">id)</span><span style=\"color:#F97583\">.await?</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">    println!</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"Run status: {}\"</span><span style=\"color:#E1E4E8\">, run</span><span style=\"color:#F97583\">.</span><span style=\"color:#E1E4E8\">status);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#B392F0\">    Ok</span><span style=\"color:#E1E4E8\">(())</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}</span></span></code></pre>\n<h2 id=\"pilotclient\">PilotClient</h2>\n<p>The main entry point. All methods are <code>async</code> and return <code>Result&#x3C;T, PilotError></code>.</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"rust\"><code><span class=\"line\"><span style=\"color:#6A737D\">// Without auth</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">let</span><span style=\"color:#E1E4E8\"> client </span><span style=\"color:#F97583\">=</span><span style=\"color:#B392F0\"> PilotClient</span><span style=\"color:#F97583\">::</span><span style=\"color:#B392F0\">new</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"http://localhost:4320\"</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#B392F0\">None</span><span style=\"color:#E1E4E8\">);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6A737D\">// With bearer token</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">let</span><span style=\"color:#E1E4E8\"> client </span><span style=\"color:#F97583\">=</span><span style=\"color:#B392F0\"> PilotClient</span><span style=\"color:#F97583\">::</span><span style=\"color:#B392F0\">new</span><span style=\"color:#E1E4E8\">(</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    \"http://localhost:4320\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">    Some</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"ey...\"</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">into</span><span style=\"color:#E1E4E8\">()),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">);</span></span></code></pre>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Method</th><th>Returns</th><th>Description</th></tr></thead><tbody><tr><td><code>health()</code></td><td><code>HealthStatus</code></td><td>Check server health</td></tr><tr><td><code>list_playbooks(target)</code></td><td><code>Vec&#x3C;PlaybookSummary></code></td><td>List playbooks, optionally filtered</td></tr><tr><td><code>get_playbook(id)</code></td><td><code>Playbook</code></td><td>Get playbook by ID (latest version)</td></tr><tr><td><code>create_playbook(req)</code></td><td><code>CreatePlaybookResponse</code></td><td>Create a new playbook</td></tr><tr><td><code>update_playbook(id, req)</code></td><td><code>UpdatePlaybookResponse</code></td><td>Update (version-bump) a playbook</td></tr><tr><td><code>delete_playbook(id)</code></td><td><code>DeletePlaybookResponse</code></td><td>Delete all versions</td></tr><tr><td><code>start_run(req)</code></td><td><code>StartRunResponse</code></td><td>Start a new run</td></tr><tr><td><code>list_runs(status, playbook_id, limit)</code></td><td><code>Vec&#x3C;Run></code></td><td>List runs with optional filters</td></tr><tr><td><code>get_run(id)</code></td><td><code>Run</code></td><td>Get run details including steps</td></tr><tr><td><code>abort_run(id)</code></td><td><code>AbortRunResponse</code></td><td>Abort a running or queued run</td></tr><tr><td><code>approve_run(id, req)</code></td><td><code>ApproveResponse</code></td><td>Submit approval decision for a step</td></tr><tr><td><code>list_providers()</code></td><td><code>Vec&#x3C;Provider></code></td><td>List all provider profiles</td></tr></tbody></table>\n<h2 id=\"playbooks\">Playbooks</h2>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"rust\"><code><span class=\"line\"><span style=\"color:#6A737D\">// List all</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">let</span><span style=\"color:#E1E4E8\"> playbooks </span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\"> client</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">list_playbooks</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#B392F0\">None</span><span style=\"color:#E1E4E8\">)</span><span style=\"color:#F97583\">.await?</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6A737D\">// Filter by target</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">let</span><span style=\"color:#E1E4E8\"> cf </span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\"> client</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">list_playbooks</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#B392F0\">Some</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"cloudflare\"</span><span style=\"color:#E1E4E8\">))</span><span style=\"color:#F97583\">.await?</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6A737D\">// Get one</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">let</span><span style=\"color:#E1E4E8\"> pb </span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\"> client</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">get_playbook</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"cloudflare.dns.add-a-record\"</span><span style=\"color:#E1E4E8\">)</span><span style=\"color:#F97583\">.await?</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6A737D\">// Create</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">let</span><span style=\"color:#E1E4E8\"> resp </span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\"> client</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">create_playbook</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#F97583\">&#x26;</span><span style=\"color:#B392F0\">CreatePlaybookRequest</span><span style=\"color:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    target</span><span style=\"color:#F97583\">:</span><span style=\"color:#9ECBFF\"> \"cloudflare\"</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">into</span><span style=\"color:#E1E4E8\">(),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    title</span><span style=\"color:#F97583\">:</span><span style=\"color:#9ECBFF\"> \"Add CNAME record\"</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">into</span><span style=\"color:#E1E4E8\">(),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    yaml</span><span style=\"color:#F97583\">:</span><span style=\"color:#E1E4E8\"> playbook_yaml,</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    authored_by</span><span style=\"color:#F97583\">:</span><span style=\"color:#B392F0\"> Some</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"human\"</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">into</span><span style=\"color:#E1E4E8\">()),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">})</span><span style=\"color:#F97583\">.await?</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6A737D\">// Update</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">client</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">update_playbook</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"cloudflare.dns.add-cname\"</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#F97583\">&#x26;</span><span style=\"color:#B392F0\">UpdatePlaybookRequest</span><span style=\"color:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    yaml</span><span style=\"color:#F97583\">:</span><span style=\"color:#E1E4E8\"> updated_yaml,</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    target</span><span style=\"color:#F97583\">:</span><span style=\"color:#B392F0\"> None</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    title</span><span style=\"color:#F97583\">:</span><span style=\"color:#B392F0\"> None</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    authored_by</span><span style=\"color:#F97583\">:</span><span style=\"color:#B392F0\"> None</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">})</span><span style=\"color:#F97583\">.await?</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6A737D\">// Delete</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">client</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">delete_playbook</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"cloudflare.dns.add-cname\"</span><span style=\"color:#E1E4E8\">)</span><span style=\"color:#F97583\">.await?</span><span style=\"color:#E1E4E8\">;</span></span></code></pre>\n<h2 id=\"runs\">Runs</h2>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"rust\"><code><span class=\"line\"><span style=\"color:#6A737D\">// Start a run</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">let</span><span style=\"color:#E1E4E8\"> resp </span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\"> client</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">start_run</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#F97583\">&#x26;</span><span style=\"color:#B392F0\">StartRunRequest</span><span style=\"color:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    playbook_id</span><span style=\"color:#F97583\">:</span><span style=\"color:#9ECBFF\"> \"cloudflare.dns.add-a-record\"</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">into</span><span style=\"color:#E1E4E8\">(),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    mode</span><span style=\"color:#F97583\">:</span><span style=\"color:#B392F0\"> Some</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"interactive\"</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">into</span><span style=\"color:#E1E4E8\">()),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    inputs</span><span style=\"color:#F97583\">:</span><span style=\"color:#B392F0\"> Some</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#B392F0\">serde_json</span><span style=\"color:#F97583\">::</span><span style=\"color:#B392F0\">json!</span><span style=\"color:#E1E4E8\">({</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">        \"zone\"</span><span style=\"color:#F97583\">:</span><span style=\"color:#9ECBFF\"> \"example.com\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">        \"record_name\"</span><span style=\"color:#F97583\">:</span><span style=\"color:#9ECBFF\"> \"api\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">        \"ip_address\"</span><span style=\"color:#F97583\">:</span><span style=\"color:#9ECBFF\"> \"1.2.3.4\"</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    })),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    provider_profile_id</span><span style=\"color:#F97583\">:</span><span style=\"color:#B392F0\"> Some</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"cf-prod\"</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">into</span><span style=\"color:#E1E4E8\">()),</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">    ..</span><span style=\"color:#B392F0\">Default</span><span style=\"color:#F97583\">::</span><span style=\"color:#B392F0\">default</span><span style=\"color:#E1E4E8\">()</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">})</span><span style=\"color:#F97583\">.await?</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6A737D\">// Get run with steps</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">let</span><span style=\"color:#E1E4E8\"> run </span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\"> client</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">get_run</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#F97583\">&#x26;</span><span style=\"color:#E1E4E8\">resp</span><span style=\"color:#F97583\">.</span><span style=\"color:#E1E4E8\">id)</span><span style=\"color:#F97583\">.await?</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">if</span><span style=\"color:#F97583\"> let</span><span style=\"color:#B392F0\"> Some</span><span style=\"color:#E1E4E8\">(steps) </span><span style=\"color:#F97583\">=</span><span style=\"color:#F97583\"> &#x26;</span><span style=\"color:#E1E4E8\">run</span><span style=\"color:#F97583\">.</span><span style=\"color:#E1E4E8\">steps {</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">    for</span><span style=\"color:#E1E4E8\"> step </span><span style=\"color:#F97583\">in</span><span style=\"color:#E1E4E8\"> steps {</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">        println!</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"{}: {} ({}ms)\"</span><span style=\"color:#E1E4E8\">, step</span><span style=\"color:#F97583\">.</span><span style=\"color:#E1E4E8\">step_id, step</span><span style=\"color:#F97583\">.</span><span style=\"color:#E1E4E8\">status,</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">            step</span><span style=\"color:#F97583\">.</span><span style=\"color:#E1E4E8\">duration_ms</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">unwrap_or</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#79B8FF\">0</span><span style=\"color:#E1E4E8\">));</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6A737D\">// List recent running runs</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">let</span><span style=\"color:#E1E4E8\"> running </span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\"> client</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">list_runs</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#B392F0\">Some</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"running\"</span><span style=\"color:#E1E4E8\">), </span><span style=\"color:#B392F0\">None</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#B392F0\">Some</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#79B8FF\">10</span><span style=\"color:#E1E4E8\">))</span><span style=\"color:#F97583\">.await?</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6A737D\">// Abort</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">client</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">abort_run</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#F97583\">&#x26;</span><span style=\"color:#E1E4E8\">resp</span><span style=\"color:#F97583\">.</span><span style=\"color:#E1E4E8\">id)</span><span style=\"color:#F97583\">.await?</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6A737D\">// Approve a step</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">client</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">approve_run</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#F97583\">&#x26;</span><span style=\"color:#E1E4E8\">resp</span><span style=\"color:#F97583\">.</span><span style=\"color:#E1E4E8\">id, </span><span style=\"color:#F97583\">&#x26;</span><span style=\"color:#B392F0\">ApproveRequest</span><span style=\"color:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    step_id</span><span style=\"color:#F97583\">:</span><span style=\"color:#9ECBFF\"> \"save\"</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">into</span><span style=\"color:#E1E4E8\">(),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    decision</span><span style=\"color:#F97583\">:</span><span style=\"color:#B392F0\"> Some</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"approve\"</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">into</span><span style=\"color:#E1E4E8\">()),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">})</span><span style=\"color:#F97583\">.await?</span><span style=\"color:#E1E4E8\">;</span></span></code></pre>\n<h2 id=\"types\">Types</h2>\n<h3 id=\"core-structs\">Core structs</h3>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Struct</th><th>Key fields</th></tr></thead><tbody><tr><td><code>Playbook</code></td><td><code>id</code>, <code>version</code>, <code>target</code>, <code>title</code>, <code>document_yaml</code>, <code>authored_by</code>, <code>created_at</code></td></tr><tr><td><code>PlaybookSummary</code></td><td><code>id</code>, <code>version</code>, <code>target</code>, <code>title</code>, <code>authored_by</code></td></tr><tr><td><code>Run</code></td><td><code>id</code>, <code>project_id</code>, <code>playbook_id</code>, <code>mode</code>, <code>status</code>, <code>inputs_json</code>, <code>outputs_json</code>, <code>steps: Option&#x3C;Vec&#x3C;RunStep>></code></td></tr><tr><td><code>RunStep</code></td><td><code>id</code>, <code>run_id</code>, <code>step_id</code>, <code>action</code>, <code>status</code>, <code>ai_used</code>, <code>duration_ms</code>, <code>error_message</code></td></tr><tr><td><code>Provider</code></td><td><code>id</code>, <code>project_id</code>, <code>provider</code>, <code>label</code>, <code>base_url</code>, <code>last_authenticated</code>, <code>expires_at</code></td></tr><tr><td><code>HealthStatus</code></td><td><code>status</code>, <code>database</code>, <code>driver_pool</code>, <code>provider_sessions</code>, <code>last_checked</code></td></tr></tbody></table>\n<h3 id=\"request-structs\">Request structs</h3>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Struct</th><th>Fields</th></tr></thead><tbody><tr><td><code>StartRunRequest</code></td><td><code>playbook_id</code>, <code>version?</code>, <code>mode?</code>, <code>inputs?</code> (<code>serde_json::Value</code>), <code>provider_profile_id?</code>, <code>project_id?</code></td></tr><tr><td><code>CreatePlaybookRequest</code></td><td><code>target</code>, <code>title</code>, <code>yaml</code>, <code>authored_by?</code></td></tr><tr><td><code>UpdatePlaybookRequest</code></td><td><code>yaml</code>, <code>target?</code>, <code>title?</code>, <code>authored_by?</code></td></tr><tr><td><code>ApproveRequest</code></td><td><code>step_id</code>, <code>decision?</code></td></tr></tbody></table>\n<p>All structs derive <code>Debug</code>, <code>Clone</code>, <code>Serialize</code>, and <code>Deserialize</code>.</p>\n<h2 id=\"error-handling\">Error handling</h2>\n<p>The SDK uses a single <code>PilotError</code> enum with three variants:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"rust\"><code><span class=\"line\"><span style=\"color:#F97583\">use</span><span style=\"color:#B392F0\"> cuitty_pilot_sdk</span><span style=\"color:#F97583\">::</span><span style=\"color:#B392F0\">PilotError</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#F97583\">match</span><span style=\"color:#E1E4E8\"> client</span><span style=\"color:#F97583\">.</span><span style=\"color:#B392F0\">start_run</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#F97583\">&#x26;</span><span style=\"color:#E1E4E8\">req)</span><span style=\"color:#F97583\">.await</span><span style=\"color:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">    Ok</span><span style=\"color:#E1E4E8\">(resp) </span><span style=\"color:#F97583\">=></span><span style=\"color:#B392F0\"> println!</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"Started: {}\"</span><span style=\"color:#E1E4E8\">, resp</span><span style=\"color:#F97583\">.</span><span style=\"color:#E1E4E8\">id),</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">    Err</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#B392F0\">PilotError</span><span style=\"color:#F97583\">::</span><span style=\"color:#B392F0\">Api</span><span style=\"color:#E1E4E8\"> { status, message }) </span><span style=\"color:#F97583\">=></span><span style=\"color:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">        eprintln!</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"API error {}: {}\"</span><span style=\"color:#E1E4E8\">, status, message);</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    }</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">    Err</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#B392F0\">PilotError</span><span style=\"color:#F97583\">::</span><span style=\"color:#B392F0\">Connection</span><span style=\"color:#E1E4E8\">(err)) </span><span style=\"color:#F97583\">=></span><span style=\"color:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">        eprintln!</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"Network error: {}\"</span><span style=\"color:#E1E4E8\">, err);</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    }</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">    Err</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#B392F0\">PilotError</span><span style=\"color:#F97583\">::</span><span style=\"color:#B392F0\">Other</span><span style=\"color:#E1E4E8\">(msg)) </span><span style=\"color:#F97583\">=></span><span style=\"color:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">        eprintln!</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#9ECBFF\">\"Unexpected: {}\"</span><span style=\"color:#E1E4E8\">, msg);</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}</span></span></code></pre>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Variant</th><th>Fields</th><th>When</th></tr></thead><tbody><tr><td><code>Api</code></td><td><code>status: u16</code>, <code>message: String</code></td><td>Non-2xx HTTP response</td></tr><tr><td><code>Connection</code></td><td>wraps <code>reqwest::Error</code></td><td>Network or timeout failure</td></tr><tr><td><code>Other</code></td><td><code>String</code></td><td>Any other error</td></tr></tbody></table>\n<h2 id=\"see-also\">See also</h2>\n<ul>\n<li><a href=\"/docs/pilot/sdk/javascript\">JavaScript SDK</a> — TypeScript client with event streaming</li>\n<li><a href=\"/docs/pilot/playbook-reference\">Playbook reference</a> — YAML schema for playbook documents</li>\n<li><a href=\"/docs/pilot/quickstart\">Quickstart</a> — record and replay your first workflow</li>\n</ul>",
  "links_out": [
    "/docs/pilot/sdk/javascript",
    "/docs/pilot/playbook-reference",
    "/docs/pilot/quickstart"
  ]
}