> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cyberdesk.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Quick Start

> Create your first Cyberdesk workflow and run it in under 5 minutes

This guide will walk you through creating your first workflow, installing Cyberdriver, and executing a run programmatically.

## Prerequisites

* An active Cyberdesk subscription (if you're not on a paid plan, [book a demo](https://cal.com/mahmoud-al-madi-klrs5s/cyberdesk-intro))
* A Cyberdesk account ([sign up here](https://cyberdesk.io/register))
* Node.js 14+ or Python 3.10+ for SDK usage
* Windows machine for desktop automation

## Step 1: Create a workflow in the dashboard

Workflows define the tasks you want to automate. Let's create your first one.

<Steps>
  <Step title="Navigate to Workflows">
    Go to the [Cyberdesk Dashboard](https://cyberdesk.io/dashboard) and click on **Workflows** in the sidebar.
  </Step>

  <Step title="Create a new workflow">
    Click the **New Workflow** button to open the workflow editor.
  </Step>

  <Step title="Define your workflow">
    Fill in the workflow details:

    * **Name** (optional): Give your workflow a descriptive name like "Extract Patient Data"
    * **Main Prompt**: This is the instruction that tells AI what to do. For example:
      ```
      Navigate to the patient portal and extract the demographics information
      for patient ID: {patient_id}. Look for patient name {patient_first_name}
      {patient_last_name} to confirm you have the right record.
      ```
          <Info>
            You can also add images to the prompt from the dashboard editor (click **Add
            Image**). Images help the agent understand tricky icons and UI elements in
            legacy apps.
          </Info>
    * **Input Schema** (optional): Define expected run inputs with JSON Schema. This validates the merged run payload (`input_values` + `sensitive_input_values` + machine/session values) before execution. In `input_schema`, sensitive root keys use a `$` prefix (for example, `"$api_key"`).
    * **Output Schema** (optional): Define the structure of data you want back using JSON Schema

    <Tip>
      **Variables in Workflows:**

      * Use `{variable_name}` for input variables - values you pass when starting the workflow
      * Use `{{runtime_variable}}` for runtime variables - values discovered and set during execution by focused\_action
      * Use `{$variable}` for sensitive variables - pass values at run creation via `sensitive_input_values`. Sensitive values are stored in a secure vault during the run, never logged or sent to LLMs, resolved only during actual computer actions, and deleted immediately after the run completes.

      Example: `"Search for {patient_name} and save their ID as {{patient_id}} for later use"`
    </Tip>

    <Note>
      **AI Assist Feature**: Instead of writing prompts manually, you can use our AI assist feature:

      1. Type a natural language description of what you want to automate
      2. Click **Apply**
      3. AI will create a detailed prompt for you
      4. You can send follow-up instructions to refine the prompt - AI uses the current field contents as context

      The same AI assist is available for both Input Schema and Output Schema fields to help you define JSON schemas quickly.
    </Note>
  </Step>

  <Step title="Save your workflow">
    Click **Create Workflow** to save. You'll be redirected to the workflow details page where you can find your workflow ID.
  </Step>
</Steps>

## Step 2: Install Cyberdriver

Cyberdriver connects your desktop to Cyberdesk. Most users should start with the stable legacy installer. Use the Cyberdriver 1.x beta MSI only when you need Windows login-screen access, boot-time startup, or Windows service management.

<Steps>
  <Step title="Install stable Legacy Cyberdriver">
    Open PowerShell and run the installer script from [Cyberdriver Quickstart](/cyberdriver/quickstart#stable-install-legacy-cyberdriver).

    The script downloads legacy Cyberdriver `v0.0.41`, adds it to your user `PATH`, and verifies the download.

    If you need the new Windows service path for login-screen control, use the [Cyberdriver 1.x beta installer](/cyberdriver/quickstart#beta-cyberdriver-1x-windows-install) instead.
  </Step>

  <Step title="Join your desktop">
    Close and reopen PowerShell, then join your machine with an organization API key from the dashboard.

    ```bash theme={null}
    cyberdriver join --secret YOUR_API_KEY
    ```

    The desktop should appear online in **Cyberdesk -> Desktops**.
  </Step>

  <Step title="Verify Desktop Tools">
    Open the desktop in Cyberdesk and click **Desktop Tools**. Verify that it connects and you can control the computer.
  </Step>
</Steps>

## Step 3: Create a run via SDK

Now let's execute your workflow programmatically using the SDK.

<Tabs>
  <Tab title="TypeScript">
    <Steps>
      <Step title="Install the SDK">
        ```bash theme={null}
        npm install cyberdesk
        ```
      </Step>

      <Step title="Create and run your workflow">
        ```typescript theme={null}
        import { createCyberdeskClient } from 'cyberdesk';

        async function runWorkflow() {
          const client = createCyberdeskClient('YOUR_API_KEY');

          const { data: run, error } = await client.runs.create({
            workflow_id: 'your-workflow-id', // From Step 1
            machine_id: 'your-machine-id', // Optional: omit to auto-select an available machine
            input_values: {
              patient_id: '12345',
              patient_first_name: 'John',
              patient_last_name: 'Doe'
            }
          });

          if (error || !run) {
            console.error('Failed to create run:', error);
            return;
          }

          console.log('Run created:', run.id);

          let currentRun = run;
          while (currentRun.status === 'scheduling' || currentRun.status === 'running') {
            await new Promise((resolve) => setTimeout(resolve, 5000));
            const { data: updatedRun, error: refreshError } = await client.runs.get(currentRun.id);
            if (refreshError || !updatedRun) {
              console.error('Failed to refresh run:', refreshError);
              return;
            }
            currentRun = updatedRun;
            console.log('Status:', currentRun.status);
          }

          if (currentRun.status === 'success') {
            console.log('Results:', currentRun.output_data);
          } else {
            console.error('Run failed:', currentRun.error?.join(', '));
          }
        }

        runWorkflow();

        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Python">
    <Steps>
      <Step title="Install the SDK">
        ```bash theme={null}
        pip install cyberdesk
        ```
      </Step>

      <Step title="Create and run your workflow">
        ```python theme={null}
        from cyberdesk import CyberdeskClient, RunCreate
        import asyncio

        async def run_workflow():
            client = CyberdeskClient('YOUR_API_KEY')

            # Create a run
            run_data = RunCreate(
                workflow_id='your-workflow-id',  # From Step 1
                machine_id='your-machine-id',    # Optional: omit to auto-select an available machine
                input_values={
                    'patient_id': '12345',
                    'patient_first_name': 'John',
                    'patient_last_name': 'Doe'
                }
            )

            response = await client.runs.create(run_data)
            if response.error:
                print(f'Failed to create run: {response.error}')
                return

            run = response.data
            print(f'Run created: {run.id}')

            while run.status in ['scheduling', 'running']:
                await asyncio.sleep(5)
                response = await client.runs.get(run.id)
                if response.error:
                    print(f'Failed to refresh run: {response.error}')
                    return
                run = response.data
                print(f'Status: {run.status}')

            if run.status == 'success':
                print('Results:', run.output_data)
            else:
                print('Run failed:', ', '.join(run.error or []))

        asyncio.run(run_workflow())

        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>

<Note>
  If your workflow defines an **Input Schema** and provided inputs do not match, the API returns a `422` validation error with path-level details so you can fix the payload before retrying.
</Note>

## Step 4: View results in the dashboard

After your run completes, you can view detailed information in the dashboard.

<Steps>
  <Step title="Navigate to Runs">
    Go to the [Runs page](https://cyberdesk.io/dashboard/runs) in your dashboard.
  </Step>

  <Step title="View run details">
    Click on your run to see:

    * **Status**: Current state of the run
    * **Output Data**: The extracted/processed data based on your output schema
    * **Message History**: Complete conversation between AI and your desktop
  </Step>

  <Step title="Generate and approve workflow trajectories">
    From the run details panel:

    * Click **Generate Trajectory** (when available) to promote that run's captured path into your workflow trajectory library

    Then navigate to your workflow's **Trajectories** tab to:

    * Review step-by-step actions with screenshots
    * **Approve trajectories** to enable fast cached execution on future runs

    <Info>
      Trajectories are Cyberdesk's intelligent caching system. Capture happens in the background during runs, generation makes a trajectory visible/reviewable, and approval enables replay. Learn more in [Trajectories 101](/concepts/trajectories).
    </Info>
  </Step>
</Steps>

## What's next?

<CardGroup cols={2}>
  <Card title="SDK Guides" icon="code" href="/sdk-guides/typescript">
    Deep dive into SDK features and advanced usage patterns
  </Card>

  <Card title="Workflow Prompting" icon="wand-magic-sparkles" href="/workflow-prompting/prompting-overview">
    Master workflow prompting with specialized tools and best practices
  </Card>

  <Card title="Trajectories 101" icon="route" href="/concepts/trajectories">
    Learn how trajectories speed up workflows by caching successful executions
  </Card>

  <Card title="API Reference" icon="terminal" href="/api-reference/introduction">
    Explore all available API endpoints
  </Card>
</CardGroup>

## Learn More

<CardGroup cols={2}>
  <Card title="Extract Prompt" icon="scanner-image" href="/workflow-prompting/extract-prompt">
    Vision-based extraction with async processing modes
  </Card>

  <Card title="Focused Action" icon="crosshairs" href="/workflow-prompting/focused-action">
    Dynamic observations and decisions in workflows
  </Card>

  <Card title="Looping Tools" icon="repeat" href="/workflow-prompting/looping-tools">
    Repeat workflow steps over arrays or counts efficiently
  </Card>

  <Card title="Generating Output Data" icon="file-export" href="/concepts/generating-output-data">
    How observations transform into structured output
  </Card>

  <Card title="Async Extraction Patterns" icon="clock" href="/concepts/async-extraction-patterns">
    Optimize workflow performance with batch and run-scoped async
  </Card>
</CardGroup>
