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

# Workflows

> Explore and validate workflows with the TypeScript/JavaScript SDK

# Workflows Client

The Workflows client lets you explore workflow definitions, fetch metadata, and validate input payloads before executing a run. Use it to inspect schemas and prevent invalid submissions.

## Setup

```typescript theme={null}
import { CloudCruise } from 'cloudcruise';

const client = new CloudCruise({
  apiKey: "your-api-key",
  encryptionKey: "your-encryption-key",
});
```

## Listing All Workflows

Retrieve all workflows accessible by your API key:

```typescript theme={null}
const workflows = await client.workflows.getAllWorkflows();

for (const workflow of workflows) {
  console.log(`ID: ${workflow.id}`);
  console.log(`Name: ${workflow.name}`);
  console.log(`Description: ${workflow.description}`);
  console.log("---");
}
```

### Workflow Object

| Field                          | Type      | Description                              |
| ------------------------------ | --------- | ---------------------------------------- |
| `id`                           | `string`  | Unique workflow identifier               |
| `name`                         | `string`  | Workflow name                            |
| `description`                  | `string`  | Workflow description                     |
| `created_at`                   | `string`  | Creation timestamp                       |
| `updated_at`                   | `string`  | Last update timestamp                    |
| `workspace_id`                 | `string`  | Associated workspace ID                  |
| `created_by`                   | `string`  | Creator user ID                          |
| `enable_popup_handling`        | `boolean` | Whether popup handling is enabled        |
| `enable_xpath_recovery`        | `boolean` | Whether XPath recovery is enabled        |
| `enable_error_code_generation` | `boolean` | Whether error code generation is enabled |

## Getting Workflow Metadata

Fetch detailed metadata for a specific workflow, including its input schema:

```typescript theme={null}
const metadata = await client.workflows.getWorkflowMetadata("workflow-123");

const inputSchema = metadata.input_schema;
const properties = inputSchema?.properties || {};
const required = inputSchema?.required || [];

console.log("Input Schema Properties:");
for (const [name, schema] of Object.entries(properties)) {
  const isRequired = required.includes(name) ? "required" : "optional";
  console.log(`  ${name} (${isRequired}):`, schema);
}
```

### Metadata Object

| Field          | Type     | Description                                   |
| -------------- | -------- | --------------------------------------------- |
| `input_schema` | `object` | JSON Schema defining required input variables |

### Input Schema Structure

The `input_schema` follows JSON Schema format:

```typescript theme={null}
{
  type: "object",
  properties: {
    url: { type: "string" },
    max_attempts: { type: "integer" },
    USER: { type: "string" },
  },
  required: ["url", "USER"],
  additionalProperties: false
}
```

## Validating Workflow Input

Validate input payloads against a workflow's schema before starting a run:

```typescript theme={null}
import { InputValidationError } from 'cloudcruise';

const payload = {
  url: "https://example.com",
  USER: "user-123",
};

try {
  await client.workflows.validateWorkflowInput("workflow-123", payload);
  console.log("✓ Payload is valid");
} catch (error) {
  if (error instanceof InputValidationError) {
    console.log(`✗ Validation failed: ${error.message}`);
    console.log(`  Missing required: ${error.missingRequired}`);
    console.log(`  Invalid types: ${error.invalidTypes}`);
    console.log(`  Unknown keys: ${error.unknownKeys}`);
  }
  throw error;
}
```

<Note>
  When you call `client.runs.start()`, the SDK automatically validates the input against the workflow's schema. Manual validation is useful when you want to check inputs before making the API call.
</Note>

### Validation Checks

The validator checks:

| Check                     | Description                                                           |
| ------------------------- | --------------------------------------------------------------------- |
| **Required fields**       | All fields listed in `required` must be present                       |
| **Type matching**         | Values must match their declared type (string, number, boolean, etc.) |
| **Additional properties** | If `additionalProperties: false`, unknown keys are rejected           |

### InputValidationError

When validation fails, an `InputValidationError` is thrown with details:

| Property          | Type                  | Description                                           |
| ----------------- | --------------------- | ----------------------------------------------------- |
| `missingRequired` | `string[]`            | Fields that are required but missing                  |
| `invalidTypes`    | `InvalidTypeDetail[]` | Fields with incorrect value types                     |
| `unknownKeys`     | `string[]`            | Fields not defined in schema (when extras disallowed) |

## Combining with Runs

Use workflow metadata to build dynamic UIs or validate inputs before execution:

```typescript theme={null}
const workflowId = "workflow-123";

// Get metadata to understand required inputs
const metadata = await client.workflows.getWorkflowMetadata(workflowId);
const schema = metadata.input_schema;
const requiredFields = schema?.required || [];

console.log(`Required inputs: ${requiredFields.join(", ")}`);

// Build a form with required_fields...

// Build your payload
const payload = {
  url: "https://example.com",
  USER: "user-123",
};

// Validate before running
try {
  await client.workflows.validateWorkflowInput(workflowId, payload);
} catch (error) {
  console.log(`Fix these issues: ${error}`);
  throw error;
}

// Start the run
const run = await client.runs.start({
  workflow_id: workflowId,
  run_input_variables: payload,
});

console.log(`Started run: ${run.sessionId}`);
```
