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

# Output Node

> Control which data is returned from a flow

The `output` node explicitly controls what data is returned from a flow, allowing you to select from artifacts, transform results, and name outputs.

## Basic Usage

You can add an output node using the flow builder's `.output()` method:

```typescript theme={null}
import { createFlow, extract } from '@doclo/flows';

const flow = createFlow()
  .step('extract', extract({
    provider: vlmProvider,
    schema: invoiceSchema
  }))
  .output({ name: 'invoice_data' })
  .build();
```

Or import the `output` function from `@doclo/nodes` and use it as a step:

```typescript theme={null}
import { createFlow, extract } from '@doclo/flows';
import { output } from '@doclo/nodes';

const flow = createFlow()
  .step('extract', extract({
    provider: vlmProvider,
    schema: invoiceSchema
  }))
  .step('output', output({ name: 'invoice_data' }))
  .build();
```

## Configuration Options

```typescript theme={null}
output({
  name: 'result',              // Optional output name
  source: 'extract',           // Select from specific step
  transform: 'pick',           // Transform strategy
  fields: ['id', 'amount']     // Fields to pick
})
```

### Options Reference

| Option            | Type                 | Description                           |
| ----------------- | -------------------- | ------------------------------------- |
| `name`            | `string`             | Name for this output                  |
| `source`          | `string \| string[]` | Step ID(s) to pull from               |
| `transform`       | `string`             | Transform strategy                    |
| `fields`          | `string[]`           | Fields to pick (for 'pick' transform) |
| `customTransform` | `function`           | Custom transform function             |

## Selecting Sources

### Previous Step (Default)

Without configuration, returns output of previous step:

```typescript theme={null}
const flow = createFlow()
  .step('parse', parse({ provider: ocrProvider }))
  .step('extract', extract({ provider: llmProvider, schema }))
  .step('output', output())  // Returns extract output
  .build();
```

### Specific Step

Select output from a specific step:

```typescript theme={null}
const flow = createFlow()
  .step('parse', parse({ provider: ocrProvider }))
  .step('extract', extract({ provider: llmProvider, schema }))
  .step('output', output({ source: 'parse' }))  // Returns parse output
  .build();
```

### Multiple Steps

Combine outputs from multiple steps:

```typescript theme={null}
const flow = createFlow()
  .step('step1', extract({ provider: vlmProvider, schema: schema1 }))
  .step('step2', extract({ provider: vlmProvider, schema: schema2 }))
  .step('output', output({
    source: ['step1', 'step2'],
    transform: 'merge'
  }))
  .build();
```

## Transform Strategies

### Pick

Select specific fields from the output:

```typescript theme={null}
output({
  transform: 'pick',
  fields: ['invoiceNumber', 'totalAmount', 'date']
})
```

Input:

```json theme={null}
{
  "invoiceNumber": "INV-001",
  "totalAmount": 1250,
  "date": "2024-01-15",
  "lineItems": [...],
  "vendor": {...}
}
```

Output:

```json theme={null}
{
  "invoiceNumber": "INV-001",
  "totalAmount": 1250,
  "date": "2024-01-15"
}
```

### Merge

Merge multiple sources into one object:

```typescript theme={null}
output({
  source: ['header', 'items', 'totals'],
  transform: 'merge'
})
```

### First / Last

Return first or last non-null result:

```typescript theme={null}
output({
  source: ['primary', 'fallback'],
  transform: 'first'
})
```

### Custom Transform

Apply a custom transformation function:

```typescript theme={null}
output({
  transform: 'custom',
  customTransform: (input, artifacts) => {
    return {
      ...input,
      processedAt: new Date().toISOString(),
      metadata: {
        parseTime: artifacts['parse'].metrics?.ms,
        extractTime: artifacts['extract'].metrics?.ms
      }
    };
  }
})
```

## Named Outputs

Name outputs for identification:

```typescript theme={null}
output({ name: 'invoice_extraction_result' })
```

## Use Cases

### Clean Output

Remove internal fields:

```typescript theme={null}
const flow = createFlow()
  .step('extract', extract({ provider: vlmProvider, schema: fullSchema }))
  .step('output', output({
    transform: 'pick',
    fields: ['id', 'amount', 'date', 'vendor']
  }))
  .build();
```

### Combine with Metadata

Add processing metadata:

```typescript theme={null}
const flow = createFlow()
  .step('parse', parse({ provider: ocrProvider }))
  .step('extract', extract({ provider: llmProvider, schema }))
  .step('output', output({
    transform: 'custom',
    customTransform: (data, artifacts) => ({
      result: data,
      metadata: {
        pageCount: artifacts['parse']?.pages?.length,
        processingTime: Date.now()
      }
    })
  }))
  .build();
```

### Multiple Output Formats

Create different views:

```typescript theme={null}
// Full output
const fullFlow = createFlow()
  .step('extract', extract({ provider: vlmProvider, schema }))
  .step('output', output({ name: 'full' }))
  .build();

// Summary output
const summaryFlow = createFlow()
  .step('extract', extract({ provider: vlmProvider, schema }))
  .step('output', output({
    name: 'summary',
    transform: 'pick',
    fields: ['id', 'total', 'status']
  }))
  .build();
```

## Without Provider

The output node doesn't require an AI provider—it performs local data selection and transformation:

```typescript theme={null}
output()  // No provider needed
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Flows" icon="diagram-project" href="/sdk/flows">
    Learn about flow construction
  </Card>

  <Card title="extract" icon="code" href="/sdk/nodes/extract">
    Extract data before output
  </Card>
</CardGroup>
