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

# addSpanEvent()

> Add a timestamped event to the current span

## Overview

`addSpanEvent()` adds a named event with optional attributes to the currently active span. Events are useful for marking significant milestones or state changes within a span.

## Signature

```typescript theme={"system"}
addSpanEvent(
  name: string, 
  attributes?: Record<string, any>
): void
```

## Basic Usage

```typescript theme={"system"}
import { KeywordsAITelemetry } from '@keywordsai/tracing';

const keywordsAi = new KeywordsAITelemetry({
    apiKey: process.env.KEYWORDSAI_API_KEY,
    appName: 'my-app'
});

await keywordsAi.initialize();

await keywordsAi.withTask(
    { name: 'data_processing' },
    async () => {
        const client = keywordsAi.getClient();
        
        client.addSpanEvent('processing_started');
        
        const data = await fetchData();
        
        client.addSpanEvent('data_fetched', { 
            records: data.length 
        });
        
        const processed = await processData(data);
        
        client.addSpanEvent('processing_completed', {
            records_processed: processed.length,
            success_rate: 0.98
        });
        
        return processed;
    }
);
```

## Batch Processing Events

```typescript theme={"system"}
await keywordsAi.withWorkflow(
    { name: 'batch_job' },
    async () => {
        const client = keywordsAi.getClient();
        
        client.addSpanEvent('batch_started', { 
            total_batches: 10 
        });
        
        for (let i = 0; i < 10; i++) {
            await processBatch(i);
            
            client.addSpanEvent('batch_completed', {
                batch_number: i,
                records: 100,
                duration_ms: 150
            });
        }
        
        client.addSpanEvent('all_batches_completed', {
            total_records: 1000
        });
        
        return 'done';
    }
);
```

## API Call Events

```typescript theme={"system"}
await keywordsAi.withTask(
    { name: 'external_api_call' },
    async () => {
        const client = keywordsAi.getClient();
        
        client.addSpanEvent('request_prepared', {
            endpoint: '/api/users',
            method: 'GET'
        });
        
        const response = await fetch('https://api.example.com/users');
        
        client.addSpanEvent('response_received', {
            status_code: response.status,
            content_type: response.headers.get('content-type')
        });
        
        const data = await response.json();
        
        client.addSpanEvent('response_parsed', {
            records: data.length
        });
        
        return data;
    }
);
```

## State Transitions

```typescript theme={"system"}
await keywordsAi.withAgent(
    { name: 'workflow_agent' },
    async () => {
        const client = keywordsAi.getClient();
        
        client.addSpanEvent('state_changed', {
            from: 'idle',
            to: 'planning'
        });
        
        const plan = await createPlan();
        
        client.addSpanEvent('state_changed', {
            from: 'planning',
            to: 'executing'
        });
        
        const result = await executePlan(plan);
        
        client.addSpanEvent('state_changed', {
            from: 'executing',
            to: 'completed'
        });
        
        return result;
    }
);
```

## Error Context Events

```typescript theme={"system"}
await keywordsAi.withTask(
    { name: 'retry_operation' },
    async () => {
        const client = keywordsAi.getClient();
        let attempt = 0;
        
        while (attempt < 3) {
            try {
                client.addSpanEvent('attempt_started', {
                    attempt_number: attempt + 1
                });
                
                const result = await unstableApiCall();
                
                client.addSpanEvent('attempt_succeeded', {
                    attempt_number: attempt + 1
                });
                
                return result;
            } catch (error) {
                client.addSpanEvent('attempt_failed', {
                    attempt_number: attempt + 1,
                    error_message: error.message
                });
                
                attempt++;
                if (attempt >= 3) throw error;
            }
        }
    }
);
```

## Performance Milestones

```typescript theme={"system"}
await keywordsAi.withWorkflow(
    { name: 'image_processing' },
    async () => {
        const client = keywordsAi.getClient();
        const startTime = Date.now();
        
        client.addSpanEvent('download_started');
        const image = await downloadImage();
        client.addSpanEvent('download_completed', {
            duration_ms: Date.now() - startTime,
            size_bytes: image.size
        });
        
        const resizeStart = Date.now();
        client.addSpanEvent('resize_started');
        const resized = await resizeImage(image);
        client.addSpanEvent('resize_completed', {
            duration_ms: Date.now() - resizeStart,
            dimensions: resized.dimensions
        });
        
        const uploadStart = Date.now();
        client.addSpanEvent('upload_started');
        await uploadImage(resized);
        client.addSpanEvent('upload_completed', {
            duration_ms: Date.now() - uploadStart
        });
        
        return 'done';
    }
);
```

## Parameters

<ParamField body="name" type="string" required>
  Event name for identification
</ParamField>

<ParamField body="attributes" type="Record<string, any>">
  Optional key-value pairs with additional event context
</ParamField>

## Best Practices

* Use events to mark significant milestones in span execution
* Include relevant attributes for context (counts, durations, status codes)
* Add events before and after critical operations
* Use consistent naming conventions for events
* Events are automatically timestamped
* Only call within an active span
* Events are visible in the Keywords AI dashboard timeline
