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

# Manual Span Creation

> [tab] TypeScript
>
> Laminar.startSpan(options)
>
> Create a span without activating it. Use for spans you'll pass to other functions.
>
> ```typescript theme={null}
> const span = Laminar.startSpan({ name: 'custom_operation' });
> try {
>   const result = doWork();
>   span.setAttributes({ 'result.count': result.length });
> } finally {
>   span.end();
> }
> ```
>
> **Parameters:**
>
> | Name | Type | Default | Description |
> | - | - | - | - |
> | `name` | `string` | — | Span name (required) |
> | `input` | `any` | — | Span input (JSON-serialized) |
> | `spanType` | `'DEFAULT'` \| `'LLM'` \| `'TOOL'` \| `'EXECUTOR'` \| `'EVALUATOR'` \| `'HUMAN_EVALUATOR'` \| `'EVALUATION'` \| `'CACHED'` | `'DEFAULT'` | Span type |
> | `tags` | `string[]` | — | Span tags |
> | `userId` | `string` | — | User ID |
> | `sessionId` | `string` | — | Session ID |
> | `metadata` | `Record<string, any>` | — | Metadata |
> | `parentSpanContext` | `string` \| `LaminarSpanContext` | — | Parent context |
> | `context` | `Context` | — | OpenTelemetry context |
> | `startTime` | `TimeInput` | — | Custom start timestamp |
>
> **Returns:** `Span`
>
> **Note:** Not activated—caller must propagate context manually or use `withSpan`.
>
> ***
>
> Laminar.startActiveSpan(options)
>
> Create and activate a span. Child spans nest automatically.
>
> ```typescript theme={null}
> const span = Laminar.startActiveSpan({ name: 'parent_operation' });
> try {
>   // Any spans created here are children of parent_operation
>   await doWork();
> } finally {
>   span.end();
> }
> ```
>
> **Parameters:**
>
> | Name | Type | Default | Description |
> | - | - | - | - |
> | `name` | `string` | — | Span name (required) |
> | `input` | `any` | — | Span input (JSON-serialized) |
> | `spanType` | `'DEFAULT'` \| `'LLM'` \| `'TOOL'` \| `'EXECUTOR'` \| `'EVALUATOR'` \| `'HUMAN_EVALUATOR'` \| `'EVALUATION'` \| `'CACHED'` | `'DEFAULT'` | Span type |
> | `tags` | `string[]` | — | Span tags |
> | `userId` | `string` | — | User ID |
> | `sessionId` | `string` | — | Session ID |
> | `metadata` | `Record<string, any>` | — | Metadata |
> | `parentSpanContext` | `string` \| `LaminarSpanContext` | — | Parent context |
> | `context` | `Context` | — | OpenTelemetry context |
> | `startTime` | `TimeInput` | — | Custom start timestamp |
>
> **Returns:** `LaminarSpan` | `Span`
>
> **Note:** Must call `span.end()` (recommend in `finally` block). Context push/pop handled automatically.
>
> ***
>
> Laminar.withSpan(span, fn, endOnExit?)
>
> Activate an existing span for the duration of a function.
>
> ```typescript theme={null}
> const parentSpan = Laminar.startSpan({ name: 'parent' });
>
> await Laminar.withSpan(parentSpan, async () => {
>   // parentSpan is active here
>   const child = Laminar.startSpan({ name: 'child' });
>   await doWork();
>   child.end();
> });
>
> parentSpan.end();
> ```
>
> **Parameters:**
>
> | Name | Type | Default | Description |
> | - | - | - | - |
> | `span` | `Span` | — | Span to activate |
> | `fn` | `() => T` | — | Function to execute |
> | `endOnExit` | `boolean` | `false` | End span when function completes |
>
> **Returns:** Return value of `fn` (or `Promise` if async)
>
> **Note:** Records exception on error. If `endOnExit` is true, span ends after `fn` (awaited if Promise).
>
> **Example: Pass span objects between functions**
>
> ```typescript theme={null}
> import { Tracevell, observe, type Span } from '@lmnr-ai/lmnr';
>
> const processData = (span: Span, data: unknown) =>
>   Laminar.withSpan(span, async () => {
>     return observe({ name: 'dataValidation' }, async () => validateData(data));
>   });
>
> export async function handleRequest(userInput: string) {
>   const rootSpan = Laminar.startSpan({ name: 'handleUserRequest' });
>   try {
>     return await processData(rootSpan, userInput);
>   } finally {
>     rootSpan.end();
>   }
> }
> ```
>
> **Example: Custom span hierarchy**
>
> ```typescript theme={null}
> import { Tracevell } from '@lmnr-ai/lmnr';
>
> export async function processWorkflow(workflowData: { id: string }) {
>   const workflowSpan = Laminar.startSpan({
>     name: 'workflow-execution',
>     metadata: { workflowId: workflowData.id },
>   });
>
>   try {
>     await Laminar.withSpan(workflowSpan, async () => {
>       const validationSpan = Laminar.startSpan({ name: 'validation' });
>       await Laminar.withSpan(validationSpan, async () => {
>         await validateWorkflow(workflowData);
>       });
>       validationSpan.end();
>
>       const processingSpan = Laminar.startSpan({ name: 'processing' });
>       await Laminar.withSpan(processingSpan, async () => {
>         const result = await processWithLLM(workflowData);
>         processingSpan.setAttributes({
>           'processing.items_count': result.items.length,
>         });
>       });
>       processingSpan.end();
>     });
>   } catch (error) {
>     workflowSpan.recordException(error as Error);
>     throw error;
>   } finally {
>     workflowSpan.end();
>   }
> }
> ```

> [tab] Python
>
> Laminar.start\_as\_current\_span()
>
> Create and activate a span using a context manager. Recommended for most cases.
>
> ```python theme={null}
> from lmnr import Tracevell
>
> with Laminar.start_as_current_span(name="custom_operation", input=data) as span:
>     result = process_data(data)
>     Laminar.set_span_output(result)
>     # Any spans created here are children of custom_operation
> # Span ends automatically
> ```
>
> **Parameters:**
>
> | Name | Type | Default | Description |
> | - | - | - | - |
> | `name` | `str` | — | Span name (required) |
> | `input` | `Any` | `None` | Span input (JSON-serialized) |
> | `span_type` | `'DEFAULT'` \| `'LLM'` \| `'TOOL'` \| `'EXECUTOR'` \| `'EVALUATOR'` \| `'HUMAN_EVALUATOR'` \| `'EVALUATION'` | `'DEFAULT'` | Span type |
> | `labels` | `list[str]` | `None` | Deprecated |
> | `parent_span_context` | `LaminarSpanContext` | `None` | Parent context for distributed tracing |
> | `tags` | `list[str]` | `None` | Span tags |
> | `user_id` | `str` | `None` | User ID |
> | `session_id` | `str` | `None` | Session ID |
> | `metadata` | `dict[str, AttributeValue]` | `None` | Trace metadata |
> | `context` | `Context` | `None` | OpenTelemetry context |
>
> **Returns:** Context manager (`LaminarSpan`)
>
> ***
>
> Laminar.start\_span()
>
> Create a span without activating it. Must end manually.
>
> ```python theme={null}
> span = Laminar.start_span(name="custom_operation")
> try:
>     result = do_work()
>     span.set_attribute("result.count", len(result))
> finally:
>     span.end()
> ```
>
> **Parameters:**
>
> | Name | Type | Default | Description |
> | - | - | - | - |
> | `name` | `str` | — | Span name (required) |
> | `input` | `Any` | `None` | Span input (JSON-serialized) |
> | `span_type` | `'DEFAULT'` \| `'LLM'` \| `'TOOL'` \| `'EXECUTOR'` \| `'EVALUATOR'` \| `'HUMAN_EVALUATOR'` \| `'EVALUATION'` | `'DEFAULT'` | Span type |
> | `parent_span_context` | `LaminarSpanContext` | `None` | Parent context for distributed tracing |
> | `labels` | `dict[str, str]` | `None` | Deprecated |
> | `tags` | `list[str]` | `None` | Span tags |
> | `user_id` | `str` | `None` | User ID |
> | `session_id` | `str` | `None` | Session ID |
> | `metadata` | `dict[str, AttributeValue]` | `None` | Trace metadata |
> | `context` | `Context` | `None` | OpenTelemetry context |
>
> **Returns:** `Span`
>
> **Note:** Does not attach to context. Combine with `use_span` to activate.
>
> ***
>
> Laminar.start\_active\_span()
>
> Create a span and immediately activate it. Must end manually.
>
> ```python theme={null}
> span = Laminar.start_active_span(name="parent_operation")
> try:
>     # Any spans created here are children of parent_operation
>     do_work()
> finally:
>     span.end()
> ```
>
> **Parameters:**
>
> | Name | Type | Default | Description |
> | - | - | - | - |
> | `name` | `str` | — | Span name (required) |
> | `input` | `Any` | `None` | Span input (JSON-serialized) |
> | `span_type` | `'DEFAULT'` \| `'LLM'` \| `'TOOL'` \| `'EXECUTOR'` \| `'EVALUATOR'` \| `'HUMAN_EVALUATOR'` \| `'EVALUATION'` | `'DEFAULT'` | Span type |
> | `parent_span_context` | `LaminarSpanContext` | `None` | Parent context for distributed tracing |
> | `labels` | `dict[str, str]` | `None` | Deprecated |
> | `tags` | `list[str]` | `None` | Span tags |
> | `user_id` | `str` | `None` | User ID |
> | `session_id` | `str` | `None` | Session ID |
> | `metadata` | `dict[str, AttributeValue]` | `None` | Trace metadata |
> | `context` | `Context` | `None` | OpenTelemetry context |
>
> **Returns:** `LaminarSpan` | `Span`
>
> **Warning:** Must end span in the same thread/async context it was created. For cross-context use, prefer `start_span` + `use_span`.
>
> ***
>
> Laminar.use\_span() / use\_span()
>
> Activate an existing span for a block of code.
>
> ```python theme={null}
> from lmnr import Tracevell, use_span
>
> parent_span = Laminar.start_span(name="parent")
>
> with use_span(parent_span):
>     # parent_span is active here
>     child_span = Laminar.start_span(name="child")
>     do_work()
>     child_span.end()
>
> parent_span.end()
> ```
>
> **Parameters:**
>
> | Name | Type | Default | Description |
> | - | - | - | - |
> | `span` | `Span` | — | Span to activate |
> | `end_on_exit` | `bool` | `False` | End span when context exits |
> | `record_exception` | `bool` | `True` | Record exceptions on span |
> | `set_status_on_exception` | `bool` | `True` | Set ERROR status on exception |
>
> **Returns:** Context manager (`LaminarSpan` | `Span`)
>
> **Example: Pass span objects between functions**
>
> ```python theme={null}
> from lmnr import Tracevell, use_span
>
> def process_data(span, data):
>     with use_span(span):
>         return validate_data(data)
>
> def handle_request(user_input: str):
>     span = Laminar.start_span(name="handle_user_request")
>     try:
>         return process_data(span, user_input)
>     finally:
>         span.end()
> ```
>
> **Example: Custom span hierarchy**
>
> ```python theme={null}
> from lmnr import Tracevell, use_span
>
> def process_workflow(workflow_data):
>     workflow_span = Laminar.start_span(name="workflow-execution")
>     try:
>         with use_span(workflow_span):
>             validation_span = Laminar.start_span(name="validation")
>             try:
>                 with use_span(validation_span):
>                     validate_workflow(workflow_data)
>             finally:
>                 validation_span.end()
>
>             processing_span = Laminar.start_span(name="processing")
>             try:
>                 with use_span(processing_span):
>                     result = process_with_llm(workflow_data)
>                     processing_span.set_attribute(
>                         "processing.items_count",
>                         len(result["items"]),
>                     )
>             finally:
>                 processing_span.end()
>     except Exception as e:
>         workflow_span.record_exception(e)
>         raise
>     finally:
>         workflow_span.end()
> ```


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