> ## 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.

# Polling Results

> Check execution status and retrieve results

For asynchronous executions, use the runs resource to check status and retrieve results.

## Execution Status

Executions progress through these statuses:

| Status      | Description             |
| ----------- | ----------------------- |
| `queued`    | Waiting to be processed |
| `running`   | Currently processing    |
| `success`   | Completed successfully  |
| `failed`    | Completed with error    |
| `cancelled` | Cancelled by user       |

```
queued → running → success
                 → failed
                 → cancelled
```

## Check Status

Use `runs.get()` to check the current status:

```typescript theme={null}
const execution = await client.runs.get('exec_abc123');

console.log('Status:', execution.status);
console.log('Created:', execution.createdAt);

if (execution.status === 'success') {
  console.log('Output:', execution.output);
  console.log('Duration:', execution.duration, 'ms');
} else if (execution.status === 'failed') {
  console.error('Error:', execution.error?.message);
}
```

## Wait for Completion

Use `runs.waitForCompletion()` to poll until the execution finishes:

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

// Poll until complete
const result = await client.runs.waitForCompletion(execution.id, {
  interval: 2000,   // Poll every 2 seconds
  timeout: 300000   // Wait up to 5 minutes
});

console.log('Final status:', result.status);
console.log('Output:', result.output);
```

### Options

| Option     | Type     | Default  | Description             |
| ---------- | -------- | -------- | ----------------------- |
| `interval` | `number` | `1000`   | Time between polls (ms) |
| `timeout`  | `number` | `300000` | Maximum wait time (ms)  |

<Warning>
  If the execution doesn't complete within the timeout, a `TimeoutError` is thrown. The execution continues running—you can call `waitForCompletion()` again with a new timeout.
</Warning>

## Manual Polling

For more control, implement your own polling loop:

```typescript theme={null}
async function pollExecution(executionId: string) {
  const maxAttempts = 60;
  const interval = 2000;

  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    const execution = await client.runs.get(executionId);

    switch (execution.status) {
      case 'success':
        return { success: true, output: execution.output };

      case 'failed':
        return { success: false, error: execution.error };

      case 'cancelled':
        return { success: false, error: { message: 'Cancelled' } };

      case 'queued':
      case 'running':
        // Still processing, wait and retry
        await new Promise(r => setTimeout(r, interval));
        break;
    }
  }

  throw new Error('Polling timeout');
}
```

## Execution Result

Completed executions include:

```typescript theme={null}
interface Execution<T> {
  id: string;
  flowId: string;
  status: ExecutionStatus;
  createdAt: string;
  completedAt?: string;     // When finished
  duration?: number;        // Duration in ms
  output?: T;               // Extracted data
  metrics?: {
    tokensUsed: number;
    cost: number;
    stepsRun: number;
    stepsTotal: number;
  };
  traceId?: string;
  metadata?: Record<string, unknown>;
  error?: {
    code: string;
    message: string;
    details?: Record<string, unknown>;
  };
}
```

## Type-Safe Results

Use generics for typed output:

```typescript theme={null}
interface InvoiceData {
  invoiceNumber: string;
  vendor: { name: string; address: string };
  totalAmount: number;
  lineItems: Array<{
    description: string;
    amount: number;
  }>;
}

const result = await client.runs.get<InvoiceData>('exec_abc123');

if (result.status === 'success' && result.output) {
  // result.output is typed as InvoiceData
  console.log('Invoice:', result.output.invoiceNumber);
  console.log('Total:', result.output.totalAmount);
}
```

## Cancel Execution

Cancel a running execution:

```typescript theme={null}
await client.runs.cancel('exec_abc123');
```

After cancellation, the execution status becomes `cancelled`. Partial results may be available.

## Batch Processing

Process multiple documents and poll all results:

```typescript theme={null}
// Start all executions
const executions = await Promise.all(
  documents.map(doc =>
    client.flows.run('flow_abc123', {
      input: { document: doc }
    })
  )
);

// Wait for all to complete
const results = await Promise.all(
  executions.map(exec =>
    client.runs.waitForCompletion(exec.id, { timeout: 120000 })
  )
);

// Process results
for (const result of results) {
  if (result.status === 'success') {
    console.log('Output:', result.output);
  } else {
    console.error('Failed:', result.error?.message);
  }
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Webhooks" icon="webhook" href="/cloud/webhooks">
    Get notified instead of polling
  </Card>

  <Card title="Error Handling" icon="triangle-exclamation" href="/cloud/executing-flows#error-handling">
    Handle execution failures
  </Card>
</CardGroup>
