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

# start

> Start a new workflow execution

## Overview

`start()` initiates a new workflow execution and returns a `Run` object for tracking and interacting with the workflow. It handles argument serialization, event sourcing, and queuing the workflow for execution.

## Usage

```typescript theme={null}
import { start } from 'workflow/runtime';
import { myWorkflow } from './workflows';

const run = await start(myWorkflow, ['arg1', 'arg2']);
console.log('Started workflow:', run.runId);
```

## Signature

```typescript theme={null}
function start<TArgs extends unknown[], TResult>(
  workflow: WorkflowFunction<TArgs, TResult> | WorkflowMetadata,
  args: TArgs,
  options?: StartOptions
): Promise<Run<TResult>>

function start<TResult>(
  workflow: WorkflowFunction<[], TResult> | WorkflowMetadata,
  options?: StartOptions
): Promise<Run<TResult>>
```

### Parameters

<ParamField path="workflow" type="WorkflowFunction | WorkflowMetadata" required>
  The workflow function to start. Must have a `'use workflow'` directive and be properly compiled.
</ParamField>

<ParamField path="args" type="TArgs">
  Arguments to pass to the workflow function. Must be serializable.
</ParamField>

<ParamField path="options" type="StartOptions">
  <Expandable title="properties">
    <ParamField path="world" type="World">
      Custom world instance to use. Defaults to `getWorld()`.
    </ParamField>

    <ParamField path="specVersion" type="number">
      Workflow spec version. Defaults to latest version.

      <Warning>This is an advanced option. Only set if you need compatibility with specific spec versions.</Warning>
    </ParamField>

    <ParamField path="deploymentId" type="string">
      Deployment ID for the workflow run. Auto-detected from environment.

      <Warning>This should not be set in user code under normal circumstances.</Warning>
    </ParamField>
  </Expandable>
</ParamField>

### Returns

<ResponseField name="Run<TResult>" type="Run">
  A `Run` object for interacting with the workflow execution. See [Run API](/api-reference/workflow-api/get-workflow-state).
</ResponseField>

## Examples

### Basic Workflow Start

```typescript theme={null}
import { start } from 'workflow/runtime';
import { processOrder } from './workflows/orders';

// Start a workflow with arguments
const run = await start(processOrder, [{ orderId: '123', items: [...] }]);

// Wait for completion
const result = await run.returnValue;
console.log('Order processed:', result);
```

### No Arguments

```typescript theme={null}
import { start } from 'workflow/runtime';
import { dailyCleanup } from './workflows/maintenance';

// Start a workflow without arguments
const run = await start(dailyCleanup);
console.log('Cleanup started:', run.runId);
```

### With Options

```typescript theme={null}
import { start } from 'workflow/runtime';
import { createLocalWorld } from '@workflow/world-local';
import { dataProcessing } from './workflows';

// Use a custom world for testing
const testWorld = createLocalWorld({ dataDir: './test-data' });

const run = await start(
  dataProcessing,
  [{ dataset: 'test' }],
  { world: testWorld }
);
```

### Start and Monitor

```typescript theme={null}
import { start } from 'workflow/runtime';
import { analyzeData } from './workflows';

const run = await start(analyzeData, [data]);

// Check status periodically
const checkStatus = async () => {
  const status = await run.status;
  console.log('Current status:', status);
  
  if (status === 'running') {
    setTimeout(checkStatus, 1000);
  }
};

checkStatus();
```

### Start and Stream Results

```typescript theme={null}
import { start } from 'workflow/runtime';
import { generateReport } from './workflows';

const run = await start(generateReport, [params]);

// Stream results as they're generated
const reader = run.readable.getReader();
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  
  console.log('Received chunk:', value);
}
```

### Parallel Workflow Starts

```typescript theme={null}
import { start } from 'workflow/runtime';
import { processItem } from './workflows';

// Start multiple workflows in parallel
const items = [1, 2, 3, 4, 5];
const runs = await Promise.all(
  items.map(item => start(processItem, [item]))
);

console.log('Started', runs.length, 'workflows');

// Wait for all to complete
const results = await Promise.all(
  runs.map(run => run.returnValue)
);

console.log('All workflows completed:', results);
```

### Type-Safe Workflow Starts

```typescript theme={null}
import { start } from 'workflow/runtime';

// Workflow with typed arguments
export async function createUser(name: string, email: string) {
  'use workflow';
  // ... workflow implementation
  return { userId: '123', name, email };
}

// TypeScript ensures correct argument types
const run = await start(createUser, ['John Doe', 'john@example.com']);

// Return type is inferred
const user: { userId: string; name: string; email: string } = await run.returnValue;
```

### Using Workflow Metadata

```typescript theme={null}
import { start } from 'workflow/runtime';
import { myWorkflow } from './workflows';

// Access workflow metadata (added by compiler)
const workflowId = (myWorkflow as any).workflowId;
console.log('Starting workflow:', workflowId);

const run = await start(myWorkflow, [args]);
```

## Error Handling

```typescript theme={null}
import { start } from 'workflow/runtime';
import { WorkflowRuntimeError } from '@workflow/errors';
import { riskyWorkflow } from './workflows';

try {
  const run = await start(riskyWorkflow, [params]);
  
  try {
    const result = await run.returnValue;
    console.log('Success:', result);
  } catch (error) {
    // Workflow execution error
    if (error instanceof WorkflowRunFailedError) {
      console.error('Workflow failed:', error.message);
      console.error('Run ID:', error.runId);
    }
  }
} catch (error) {
  // Start error (e.g., invalid workflow, serialization error)
  if (WorkflowRuntimeError.is(error)) {
    console.error('Failed to start workflow:', error.message);
  }
}
```

## Run ID Generation

Each workflow run gets a unique ID in the format `wrun_{ulid}`. The ID is:

* Generated client-side before execution
* Globally unique and sortable by creation time
* Used for tracking, logging, and event correlation

```typescript theme={null}
const run = await start(myWorkflow, [args]);
console.log(run.runId); // e.g., "wrun_01HQXYZ123456789ABCDEFGH"
```

## Serialization

Workflow arguments must be serializable. Supported types:

* Primitives: string, number, boolean, null, undefined
* Objects and arrays
* Dates
* URLs
* Custom classes with proper serialization
* Streams (automatically handled)

```typescript theme={null}
// ✅ Valid arguments
await start(workflow, [
  'string',
  123,
  { nested: { object: true } },
  new Date(),
  new URL('https://example.com'),
]);

// ❌ Invalid arguments
await start(workflow, [
  function() {}, // Functions not serializable
  Symbol('test'), // Symbols not serializable
]);
```

## Trace Propagation

`start()` automatically propagates OpenTelemetry trace context to the workflow:

```typescript theme={null}
import { trace } from '@opentelemetry/api';
import { start } from 'workflow/runtime';
import { myWorkflow } from './workflows';

const tracer = trace.getTracer('my-app');

await tracer.startActiveSpan('process-request', async (span) => {
  // Trace context automatically propagated to workflow
  const run = await start(myWorkflow, [data]);
  
  span.setAttribute('workflow.runId', run.runId);
  span.end();
});
```

## Best Practices

1. **Await the start call**: Always await `start()` to ensure the workflow is queued

2. **Store run IDs**: Save `run.runId` for later reference and monitoring

3. **Use type inference**: Let TypeScript infer return types from workflow functions

4. **Handle start errors**: Catch and handle errors from the start call separately from execution errors

5. **Serialize carefully**: Ensure all arguments are serializable before passing to workflows

6. **Don't start workflows from workflows**: Use direct function calls or steps instead

## See Also

* [Run API](/api-reference/workflow-api/get-workflow-state)
* [Workflow Functions](/essentials/workflows)
* [Error Handling](/essentials/error-handling)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.