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

# List Spans

> Get spans with filters and pagination

```python theme={null}
result = client.spans.list(options?)
# Async
result = await client.spans.alist(options?)
```

Retrieve spans with optional filters and cursor-based pagination.

## Parameters

Pass a `ListSpansOptions` object:

| Parameter     | Type                   | Required | Description                            |
| ------------- | ---------------------- | -------- | -------------------------------------- |
| `prompt_slug` | `str`                  | No       | Filter by prompt slug                  |
| `status`      | `"SUCCESS" \| "ERROR"` | No       | Filter by status                       |
| `start_date`  | `datetime`             | No       | Filter spans created after this date   |
| `end_date`    | `datetime`             | No       | Filter spans created before this date  |
| `user_id`     | `str`                  | No       | Filter by end user ID                  |
| `session_id`  | `str`                  | No       | Filter by session ID                   |
| `tags`        | `list[str]`            | No       | Filter by tags (AND logic)             |
| `limit`       | `int`                  | No       | Results per page (max 100, default 50) |
| `cursor`      | `str`                  | No       | Cursor from previous response          |

## Response

```python theme={null}
class ListSpansResult(BaseModel):
    spans: list[SpanListItem]
    cursor: str | None
    has_more: bool              # alias: "hasMore"
```

The list endpoint returns `SpanListItem` objects with reduced fields (no `input`, `output`, `variables`, `error`, `tags`). Use `spans.get(span_id)` to fetch the full `Span` detail.

## Examples

### Basic Usage

```python theme={null}
result = client.spans.list()
print(f"Found {len(result.spans)} spans")
```

### Filtering by Prompt

```python theme={null}
from tracia import ListSpansOptions

result = client.spans.list(ListSpansOptions(
    prompt_slug="welcome-email",
    status="SUCCESS",
))

for span in result.spans:
    print(f"{span.span_id}: {span.latency_ms}ms, {span.total_tokens} tokens")
```

### Date Range Filtering

```python theme={null}
from datetime import datetime
from tracia import ListSpansOptions

result = client.spans.list(ListSpansOptions(
    start_date=datetime(2024, 1, 1),
    end_date=datetime(2024, 1, 31),
))
```

### Filtering by Tags

```python theme={null}
from tracia import ListSpansOptions

result = client.spans.list(ListSpansOptions(
    tags=["production", "v2"],  # Must have ALL tags
))
```

### Pagination

```python theme={null}
from tracia import ListSpansOptions

def get_all_spans():
    all_spans = []
    cursor = None

    while True:
        result = client.spans.list(ListSpansOptions(limit=100, cursor=cursor))
        all_spans.extend(result.spans)
        if not result.has_more:
            break
        cursor = result.cursor

    return all_spans
```

### Calculating Costs

```python theme={null}
from datetime import datetime
from tracia import ListSpansOptions

result = client.spans.list(ListSpansOptions(
    prompt_slug="welcome-email",
    start_date=datetime(2024, 1, 1),
))

total_cost = sum(s.cost or 0 for s in result.spans)
total_tokens = sum(s.total_tokens for s in result.spans)

print(f"Total cost: ${total_cost:.4f}")
print(f"Total tokens: {total_tokens}")
```

## Error Handling

```python theme={null}
from tracia import TraciaError, TraciaErrorCode

try:
    result = client.spans.list()
except TraciaError as error:
    if error.code == TraciaErrorCode.UNAUTHORIZED:
        print("Invalid API key")
```
