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

# Executing Flows

> Run flows synchronously or asynchronously

Learn how to execute document processing flows on Doclo Cloud, with options for synchronous and asynchronous processing.

## Execution Modes

Doclo Cloud supports two execution modes:

| Mode         | Use Case                                   | How                                  |
| ------------ | ------------------------------------------ | ------------------------------------ |
| Synchronous  | Small documents, immediate response needed | Set `wait: true`                     |
| Asynchronous | Large documents, background processing     | Omit `wait`, use webhooks or polling |

## Synchronous Execution

Wait for the flow to complete before returning:

```typescript theme={null}
const result = await client.flows.run('flow_abc123', {
  input: {
    document: {
      base64: documentBase64,
      filename: 'invoice.pdf',
      mimeType: 'application/pdf'
    }
  },
  wait: true,
  timeout: 60000  // Wait up to 60 seconds
});

// Result is immediately available
console.log('Output:', result.output);
console.log('Status:', result.status);  // 'success' or 'failed'
```

### Timeout Configuration

| Option    | Default | Description                              |
| --------- | ------- | ---------------------------------------- |
| `timeout` | `30000` | Max time to wait for sync execution (ms) |

<Warning>
  If the flow takes longer than the timeout, a `TimeoutError` is thrown. The execution continues in the background—use `runs.get()` to check status.
</Warning>

## Asynchronous Execution

Start execution and retrieve results later:

```typescript theme={null}
// Start execution
const execution = await client.flows.run('flow_abc123', {
  input: {
    document: {
      base64: documentBase64,
      filename: 'invoice.pdf',
      mimeType: 'application/pdf'
    }
  }
  // No 'wait' option - returns immediately
});

console.log('Execution ID:', execution.id);
console.log('Status:', execution.status);  // 'queued' or 'running'
```

Retrieve results using:

* [Polling](/cloud/polling-results) - check status periodically
* [Webhooks](/cloud/webhooks) - receive notification when complete

## Input Structure

Every flow execution requires a document input:

```typescript theme={null}
interface FlowRunInput {
  document: {
    base64: string;    // Base64-encoded content
    filename: string;  // Original filename
    mimeType: string;  // MIME type
  };
  variables?: Record<string, unknown>;  // Optional flow variables
}
```

### Supported MIME Types

| Format | MIME Type         |
| ------ | ----------------- |
| PDF    | `application/pdf` |
| JPEG   | `image/jpeg`      |
| PNG    | `image/png`       |
| WebP   | `image/webp`      |
| TIFF   | `image/tiff`      |

### Flow Variables

Pass variables to customize flow behavior:

```typescript theme={null}
const result = await client.flows.run('flow_abc123', {
  input: {
    document: { base64, filename, mimeType: 'application/pdf' },
    variables: {
      extractLineItems: true,
      currency: 'USD',
      language: 'en'
    }
  },
  wait: true
});
```

Check the flow's `inputSchema` for required variables:

```typescript theme={null}
const flow = await client.flows.get('flow_abc123');
console.log('Required variables:', flow.inputSchema);
```

## Execution Options

| Option           | Type           | Description                       |
| ---------------- | -------------- | --------------------------------- |
| `input`          | `FlowRunInput` | Document and variables (required) |
| `wait`           | `boolean`      | Wait for completion               |
| `timeout`        | `number`       | Sync mode timeout in ms           |
| `webhookUrl`     | `string`       | URL for completion notification   |
| `metadata`       | `object`       | Custom metadata to attach         |
| `idempotencyKey` | `string`       | Prevent duplicate executions      |
| `version`        | `string`       | Specific flow version             |

### Idempotency

Prevent duplicate processing by providing an idempotency key:

```typescript theme={null}
const result = await client.flows.run('flow_abc123', {
  input: { document: { base64, filename, mimeType: 'application/pdf' } },
  idempotencyKey: `invoice-${invoiceId}`,
  wait: true
});
```

If the same key is used within 24 hours, the original execution result is returned instead of starting a new one.

### Custom Metadata

Attach metadata to track executions:

```typescript theme={null}
const result = await client.flows.run('flow_abc123', {
  input: { document: { base64, filename, mimeType: 'application/pdf' } },
  metadata: {
    customerId: 'cust_123',
    source: 'email-inbox',
    priority: 'high'
  },
  wait: true
});

// Metadata is returned with the execution
console.log(result.metadata);  // { customerId: 'cust_123', ... }
```

### Flow Versions

Run a specific flow version:

```typescript theme={null}
const result = await client.flows.run('flow_abc123', {
  input: { document: { base64, filename, mimeType: 'application/pdf' } },
  version: '1.2.0',
  wait: true
});
```

If omitted, the latest version is used.

## Error Handling

```typescript theme={null}
import {
  DocloClient,
  AuthenticationError,
  NotFoundError,
  ValidationError,
  RateLimitError,
  TimeoutError,
  ExecutionError
} from '@doclo/client';

try {
  const result = await client.flows.run('flow_abc123', {
    input: { document: { base64, filename, mimeType: 'application/pdf' } },
    wait: true
  });
} catch (error) {
  if (error instanceof AuthenticationError) {
    // Invalid or expired API key
    console.error('Authentication failed:', error.message);
  } else if (error instanceof NotFoundError) {
    // Flow doesn't exist
    console.error('Flow not found:', error.message);
  } else if (error instanceof ValidationError) {
    // Invalid input (missing required variables, bad document format)
    console.error('Validation error:', error.message, error.details);
  } else if (error instanceof RateLimitError) {
    // Too many requests
    console.error('Rate limited, retry after:', error.rateLimitInfo?.retryAfter);
  } else if (error instanceof TimeoutError) {
    // Sync execution timed out (execution continues in background)
    console.error('Timeout:', error.message);
  } else if (error instanceof ExecutionError) {
    // Flow execution failed
    console.error('Execution failed:', error.code, error.message);
  }
}
```

### Execution Failures

When an execution fails, the `error` field contains details:

```typescript theme={null}
const result = await client.flows.run('flow_abc123', {
  input: { document: { base64, filename, mimeType: 'application/pdf' } },
  wait: true
});

if (result.status === 'failed') {
  console.error('Error code:', result.error?.code);
  console.error('Error message:', result.error?.message);
  console.error('Error details:', result.error?.details);
}
```

Common error codes:

| Code                    | Description                    |
| ----------------------- | ------------------------------ |
| `EXECUTION_FAILED`      | General execution failure      |
| `EXECUTION_TIMEOUT`     | Execution exceeded time limit  |
| `PROVIDER_ERROR`        | LLM/OCR provider failed        |
| `PROVIDER_RATE_LIMITED` | Provider rate limit exceeded   |
| `INVALID_INPUT`         | Document couldn't be processed |

## Next Steps

<CardGroup cols={2}>
  <Card title="Polling Results" icon="clock" href="/cloud/polling-results">
    Check execution status
  </Card>

  <Card title="Webhooks" icon="webhook" href="/cloud/webhooks">
    Receive completion notifications
  </Card>
</CardGroup>
