> For the complete documentation index, see [llms.txt](https://docs.zenml.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.zenml.io/kitaru/import-your-traces/import-phoenix-traces.md).

# Arize Phoenix

Import Arize Phoenix trace exports into Kitaru: supported UI and CLI files, span mapping, source identity, and known limits.

If your agent already sends traces to Arize Phoenix, export the runs you care about and import the file into Kitaru. Each Phoenix trace becomes one [session](/kitaru/core-concepts/agents-and-sessions.md), with its model calls, tool calls, agent spans, timings, status, token usage, and cost preserved where the export records them.

Phoenix stays your system of record. Kitaru stores a runnable copy for evaluation, cohort building, and replay. The importer runs on a [worker](/kitaru/core-concepts/workers.md) in your environment; the server stores the uploaded file, but does not parse it.

## 1. Export traces from Phoenix

### Phoenix UI

Open a project in Phoenix, select **Traces**, select the traces to export, and choose **Download selection**. In the download dialog:

1. Choose **Traces** for the data.
2. Choose **JSONL** for the format.
3. Include span or trace annotations if you want them retained as import metadata.
4. Download the file.

Phoenix's UI trace download is one flat span object per JSONL line. The file is still a trace export: `context.trace_id` groups its lines, while `context.span_id` and `parent_id` reconstruct the graph. Line order is not significant.

### Phoenix CLI

The importer also accepts the JSON written by Phoenix CLI trace retrieval. A CLI trace object contains `traceId` and a `spans` array, with optional trace `annotations` and `notes`. You can import one object, a JSON array of objects, or JSONL with one trace object per line.

The UI and CLI therefore carry the same span objects in different containers. You do not need to reshape either one. See Phoenix's [trace retrieval guide](https://arize.com/docs/phoenix/tracing/how-to-tracing/importing-and-exporting-traces/retrieve-traces-via-cli) for the current CLI commands.

Uploads are capped by the server's configurable blob limit. Split a larger export into smaller files.

## 2. Import the file

Register the agent the traces belong to, if needed, and run a worker:

```bash
kitaru agent register support-agent --command "python support.py"
kitaru worker start
```

Then import a Phoenix UI download:

```bash
kitaru session import phoenix-traces.jsonl \
  --importer kitaru/phoenix@latest \
  --agent support-agent@latest \
  --params '{"source_instance":"my-phoenix-project"}' \
  --media-type application/x-ndjson \
  --tag imported-baseline \
  --wait
```

Use `--media-type application/json` for a CLI JSON object or array. On Kitaru 0.22.2 and later, `kitaru/phoenix` is a built-in importer registered at server startup, so there is no importer code to register. Older servers do not have it in their catalog; upgrade the server before importing.

List the imported sessions:

```bash
kitaru session list \
  --agent support-agent \
  --origin imported \
  --imported-from phoenix
```

### Source identity

The importer chooses `params.source_instance`, then the `params.project` alias, then an embedded top-level `project` on the span or trace envelope. UI and CLI downloads without project identity require one of those parameters. Values are trimmed strings, and conflicting embedded projects fail the affected trace even with an override.

Use the same project identifier for file and API imports. The API fetcher includes the selected query or configured project in its payload; a project name and its ID are not automatically reconciled. See [Import your traces](/kitaru/import-your-traces/import-your-traces.md) for the shared identity rules and guidance for existing imports.

## 3. Or fetch from the Phoenix API

Skip the export and upload, and let the import task fetch spans from Phoenix directly:

```bash
kitaru session import \
  --importer kitaru/phoenix@latest \
  --agent support-agent@latest \
  --since 7d \
  --tag imported-baseline --wait
```

Omitting FILE and setting `--since` selects an API import: the worker calls the Phoenix API instead of parsing an uploaded payload. `--since` and `--until` accept an ISO 8601 timestamp or a relative duration (`7d`, `12h`, `30m`). `--trace-id` (repeatable) fetches exactly those trace ids instead of a time window. The same selection is a query object on the SDK and REST request:

| Query key     | Meaning                                                                                                    |
| ------------- | ---------------------------------------------------------------------------------------------------------- |
| `project`     | Phoenix project to fetch from. Defaults to the project name from the environment.                          |
| `trace_ids`   | Phoenix trace ids to fetch. When present, exactly those traces are fetched and the time window is ignored. |
| `since`       | Timezone-aware ISO 8601 datetime, lower bound of span start time. Required when `trace_ids` is absent.     |
| `until`       | Timezone-aware ISO 8601 datetime, upper bound of span start time. Defaults to now.                         |
| `concurrency` | Traces fetched at once. Defaults to 4.                                                                     |

Pass `project` through `--query '{"project": "my-project"}'`. The worker installs the package's `api` extra for an API import, which carries the provider client. A [connection](/kitaru/import-your-traces/provider-connections.md) you name with `--connection`, or the provider's default connection, supplies `PHOENIX_ENDPOINT` or `PHOENIX_COLLECTOR_ENDPOINT`, `PHOENIX_API_KEY`, and `PHOENIX_PROJECT` for the default project. Without either, the worker's own environment does, and only a worker started with `--selector kitaru/requires-credentials=phoenix` claims the task. Each fetched trace is parsed the same way an uploaded export would be, so the node mapping and limits below apply the same way.

## What becomes a session

Each Phoenix trace becomes one Kitaru session. Its `external_id` is `<source_instance>:<trace_id>`, so importing the same trace with the same project identity into the same agent skips it. Earlier bare trace IDs do not match these prefixed IDs. Overlapping re-imports of those can therefore create additional sessions. Phoenix session or conversation attributes remain on the span; the importer does not join several traces into one multi-turn session.

Every exported span becomes a node. The importer sorts spans by time and reconstructs their parent relationships instead of trusting export order.

| Phoenix `span_kind`                          | Kitaru node |
| -------------------------------------------- | ----------- |
| `LLM`                                        | `llm_call`  |
| `TOOL`                                       | `tool_call` |
| `AGENT`, `CHAIN`, `UNKNOWN`, and other kinds | `span`      |

`AGENT` remains a plain span because a Phoenix agent span does not by itself prove that Kitaru should treat it as a separately replayable subagent.

The importer reads common OpenInference and OpenTelemetry GenAI attributes for:

* inputs and outputs, including model messages, tool arguments and results, and Google ADK request and response payloads;
* requested and resolved model names, model provider, and model parameters;
* input, output, cached-input, and reasoning token counts;
* recorded cost;
* tool name;
* PydanticAI or Google ADK framework identity when provider-specific attributes establish it.

The original Phoenix attributes and events remain on each node under `phoenix.attributes` and `phoenix.events`. CLI trace annotations and notes remain in session metadata.

## Status and partial exports

Phoenix `ERROR` spans become failed nodes. `OK` and `UNSET` spans become completed nodes because both are terminal states in exported traces. Session status follows the root span, so a tool call that failed and was successfully retried does not incorrectly fail the whole session.

A span whose parent is absent from the file remains importable as a root node. The session records `source_completeness: partial` and a `normalization_warnings` entry. Duplicate span ids and parent cycles fail only the affected trace; other valid traces in the same file still import.

## Limits

* The parser reads files. Live API access is the separate fetch path described above, not something the parser itself does.
* It supports Phoenix's native JSON and JSONL trace shapes, not arbitrary OTLP JSON envelopes. Export JSONL from the Phoenix UI or JSON with the Phoenix CLI.
* It does not accept JSONL produced by serializing `get_spans_dataframe()`. That table uses flattened top-level column names rather than the UI and CLI span objects.
* It does not import Phoenix datasets, experiments, evaluators, or project configuration. Trace and span annotations included in the export are retained as metadata, but do not become Kitaru evaluations.
* Replay still needs the registered agent code that produced the trace. No trace export contains runnable agent code.

{% hint style="warning" %}
A trace export can contain prompts, tool arguments, tool results, annotations, and exception stack traces. Importing stores that content on your Kitaru server. Check your access and retention rules before importing production data.
{% endhint %}

## Next

Evaluate the imported history with [Write an evaluator](/kitaru/guides/write-an-evaluator.md), then freeze the sessions that matter into a cohort with [Build a regression suite from production](/kitaru/guides/regression-suite.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.zenml.io/kitaru/import-your-traces/import-phoenix-traces.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
