---
title: "arize-phoenix-client"
description: "Phoenix Client is a comprehensive SDK for interacting with the Phoenix"
---

[![PyPI Version](https://img.shields.io/pypi/v/arize-phoenix-client)](https://pypi.org/project/arize-phoenix-client/)

<Info>
For the complete API reference and detailed guides, see the [full documentation](https://arize-phoenix.readthedocs.io/projects/client/index.html).
</Info>

Phoenix Client provides a interface for interacting with the Phoenix platform via its REST API, enabling you to manage datasets, run experiments, analyze traces, and collect feedback programmatically

## Features

- **REST API Interface** - Interact with Phoenix's OpenAPI REST interface
- **Prompts** - Create, version, and invoke prompt templates
- **Datasets** - Create and append to datasets from DataFrames, CSV files, or dictionaries
- **Experiments** - Run evaluations and track experiment results
- **Spans** - Query and analyze traces with powerful filtering
- **Annotations** - Add human feedback and automated evaluations
- **Sessions** - Retrieve and list multi-turn conversation sessions

## Installation

Install the Phoenix Client using pip:

```bash
pip install arize-phoenix-client
```

# Getting Started

## Environment Variables

Configure the Phoenix Client using environment variables for seamless use across different environments:

```bash
# For local Phoenix server (default)
export PHOENIX_ENDPOINT="http://localhost:6006"

# A hosted or self-hosted instance with authentication
export PHOENIX_ENDPOINT="https://phoenix.example.com"
export PHOENIX_API_KEY="your-api-key"

# Customize headers
export PHOENIX_CLIENT_HEADERS="Authorization=Bearer your-api-key,custom-header=value"
```

`PHOENIX_ENDPOINT` is a base URL and is the canonical setting for the client. If your app also exports traces, set `PHOENIX_COLLECTOR_ENDPOINT` for the OTel SDK — usually to the same value. When only `PHOENIX_COLLECTOR_ENDPOINT` is set, the client infers its base URL from it. See [Environments](/docs/phoenix/environments).

## Client Initialization

The client automatically reads environment variables, or you can override them:

```python
from phoenix.client import Client, AsyncClient

# Automatic configuration from environment variables
client = Client()

client = Client(base_url="http://localhost:6006")  # Local Phoenix server

# Cloud instance with API key
client = Client(
    base_url="https://your-phoenix.example.com",
    api_key="your-api-key"
)

# Custom authentication headers
client = Client(
    base_url="https://your-phoenix-instance.com",
    headers={"Authorization": "Bearer your-api-key"}
)

# Asynchronous client (same configuration options)
async_client = AsyncClient()
async_client = AsyncClient(base_url="http://localhost:6006")
async_client = AsyncClient(
    base_url="https://your-phoenix.example.com",
    api_key="your-api-key"
)
```

# Resources

The Phoenix Client organizes functionality into resources that correspond to key Phoenix platform features. Each resource provides specialized methods for managing different types of data:

### Prompts

Manage prompt templates and versions:

```python 
from phoenix.client import Client
from phoenix.client.types import PromptVersion

content = """
You're an expert educator in {{ topic }}. Summarize the following article
in a few concise bullet points that are easy for beginners to understand.

{{ article }}
"""

prompt = client.prompts.create(
    name="article-bullet-summarizer",
    version=PromptVersion(
        [{"role": "user", "content": content}],
        model_name="gpt-4o-mini",
    ),
    prompt_description="Summarize an article in a few bullet points"
)

# Retrieve and use prompts
prompt = client.prompts.get(prompt_identifier="article-bullet-summarizer")

# Format the prompt with variables
prompt_vars = {
    "topic": "Sports",
    "article": "Moises Henriques, the Australian all-rounder, has signed to play for Surrey in this summer's NatWest T20 Blast. He will join after the IPL and is expected to strengthen the squad throughout the campaign."
}
formatted_prompt = prompt.format(variables=prompt_vars)

# Make a request with your Prompt using OpenAI
from openai import OpenAI
oai_client = OpenAI()
resp = oai_client.chat.completions.create(**formatted_prompt)
print(resp.choices[0].message.content)
```

## Datasets

Manage evaluation datasets and examples for experiments and evaluation:

```python 
import pandas as pd

# List all available datasets
datasets = client.datasets.list()
for dataset in datasets:
    print(f"Dataset: {dataset['name']} ({dataset['example_count']} examples)")

# Get a specific dataset with all examples
dataset = client.datasets.get_dataset(dataset="qa-evaluation")
print(f"Dataset {dataset.name} has {len(dataset)} examples")

# Convert dataset to pandas DataFrame for analysis
df = dataset.to_dataframe()
print(df.columns)  # Index(['input', 'output', 'metadata'], dtype='object')

# Create a new dataset from dictionaries
dataset = client.datasets.create_dataset(
    name="customer-support-qa",
    dataset_description="Q&A dataset for customer support evaluation",
    inputs=[
        {"question": "How do I reset my password?"},
        {"question": "What's your return policy?"},
        {"question": "How do I track my order?"}
    ],
    outputs=[
        {"answer": "You can reset your password by clicking the 'Forgot Password' link on the login page."},
        {"answer": "We offer 30-day returns for unused items in original packaging."},
        {"answer": "You can track your order using the tracking number sent to your email."}
    ],
    metadata=[
        {"category": "account", "difficulty": "easy"},
        {"category": "policy", "difficulty": "medium"},
        {"category": "orders", "difficulty": "easy"}
    ]
)

# Create dataset from pandas DataFrame
df = pd.DataFrame({
    "prompt": ["Hello", "Hi there", "Good morning"],
    "response": ["Hi! How can I help?", "Hello! What can I do for you?", "Good morning! How may I assist?"],
    "sentiment": ["neutral", "positive", "positive"],
    "length": [20, 25, 30]
})

dataset = client.datasets.create_dataset(
    name="greeting-responses",
    dataframe=df,
    input_keys=["prompt"],           # Columns to use as input
    output_keys=["response"],        # Columns to use as expected output
    metadata_keys=["sentiment", "length"]  # Additional metadata columns
)
```

## Spans

Query for spans and annotations from your projects for custom evaluation and annotation workflows:

```python 
from datetime import datetime, timedelta

from phoenix.client.types.spans import SpanQuery

# Get spans as pandas DataFrame for analysis
spans_df = client.spans.get_spans_dataframe(
    project_identifier="my-llm-app",
    limit=1000,
    query=SpanQuery().where("parent_id is None"),  # Only top-level spans
    start_time=datetime.now() - timedelta(hours=24)
)

# Get span annotations as DataFrame
annotations_df = client.spans.get_span_annotations_dataframe(
    spans_dataframe=spans_df,  # Use spans from previous query
    project_identifier="my-llm-app",
    include_annotation_names=["relevance", "accuracy"],  # Only specific annotations
    exclude_annotation_names=["note"]  # Exclude UI notes
)
```

## Annotations

Add annotations to spans for evaluation, user feedback, and custom annotation workflows:

```python 
# Add a single annotation with human feedback
client.spans.add_span_annotation(
    span_id="span-123",
    annotation_name="helpfulness",
    annotator_kind="HUMAN",
    label="helpful",
    score=0.9,
    explanation="Response directly answered the user's question"
)

# Bulk annotation logging for multiple spans
annotations = [
    {
        "name": "sentiment",
        "span_id": "span-123",
        "annotator_kind": "LLM",
        "result": {"label": "positive", "score": 0.8}
    },
    {
        "name": "accuracy",
        "span_id": "span-456",
        "annotator_kind": "HUMAN",
        "result": {"label": "accurate", "score": 0.95}
    },
]
client.spans.log_span_annotations(span_annotations=annotations)
```

## Projects

Manage Phoenix projects that organize your AI application data:

```python 
# List all projects
projects = client.projects.list()
for project in projects:
    print(f"Project: {project['name']} (ID: {project['id']})")

# Filter server-side by a case-insensitive substring of the project name
support_projects = client.projects.list(name_contains="support")

# Create a new project
new_project = client.projects.create(
    name="Customer Support Bot",
    description="Traces and evaluations for our customer support chatbot"
)
print(f"Created project with ID: {new_project['id']}")
```

## Sessions

Retrieve session data for multi-turn conversations. Sessions group related traces from a conversation into a single timeline.

```python
# Get a specific session by ID
session = client.sessions.get(session_id="my-session-id")
print(f"Session: {session['session_id']}, Traces: {len(session['traces'])}")

# List sessions for a project
sessions = client.sessions.list(project_name="my-chatbot")
for s in sessions:
    print(f"{s['session_id']}: {len(s['traces'])} traces")

# List with a limit
recent = client.sessions.list(project_name="my-chatbot", limit=10)

# Get sessions as a pandas DataFrame
df = client.sessions.get_sessions_dataframe(project_name="my-chatbot")
print(df[["session_id", "start_time", "end_time", "num_traces"]])
```

### Async Usage

```python
from phoenix.client import AsyncClient

async_client = AsyncClient()

session = await async_client.sessions.get(session_id="my-session-id")
sessions = await async_client.sessions.list(project_name="my-chatbot", limit=10)
df = await async_client.sessions.get_sessions_dataframe(project_name="my-chatbot")
```

---

## Reference Documentation

<Card title="Full API Reference" icon="arrow-up-right-from-square" href="https://arize-phoenix.readthedocs.io/projects/client/">
  Complete API documentation for datasets, experiments, prompts, spans, sessions, and annotations
</Card>
