Export data

Opik gives you several ways to export the data you’ve logged — pick the one that fits your workflow.

SDK

The Python and TypeScript SDKs let you search and export traces, spans, and threads programmatically.

Traces

1import opik
2
3client = opik.Opik()
4
5# Export all traces
6traces = client.search_traces(project_name="Default project", max_results=1000000)
7
8# Export filtered traces
9traces = client.search_traces(
10 project_name="Default project",
11 filter_string='input contains "Opik"'
12)
13
14# Convert to dict if needed
15traces = [trace.dict() for trace in traces]

Spans

1import opik
2
3client = opik.Opik()
4
5# Export spans by trace ID
6spans = client.search_spans(
7 project_name="Default project",
8 trace_id="067092dc-e639-73ff-8000-e1c40172450f"
9)
10
11# Export filtered spans
12spans = client.search_spans(
13 project_name="Default project",
14 filter_string='input contains "Opik"'
15)

Threads

1import opik
2
3client = opik.Opik()
4
5# Export all threads
6threads = client.search_threads(project_name="Default project", max_results=1000000)
7
8# Export filtered threads
9threads = client.search_threads(
10 project_name="Default project",
11 filter_string='number_of_messages >= 5'
12)

Filtering with OQL

All search methods accept a filter_string / filterString using the Opik Query Language (OQL):

"<COLUMN> <OPERATOR> <VALUE> [AND <COLUMN> <OPERATOR> <VALUE>]*"
  • String values must be wrapped in double quotes
  • Multiple conditions can be combined with AND (OR is not supported)
  • DateTime fields require ISO 8601 format (e.g., "2024-01-01T00:00:00Z")
  • Use dot notation for nested fields: metadata.model, feedback_scores.accuracy

Common filter examples:

1client.search_traces(filter_string='start_time >= "2024-01-01T00:00:00Z"')
2client.search_traces(filter_string='usage.total_tokens > 1000')
3client.search_traces(filter_string='metadata.model = "gpt-4o"')
4client.search_traces(filter_string='feedback_scores.user_rating is_not_empty')
5client.search_traces(filter_string='tags contains "production"')

The full list of supported columns per entity type is documented below.

Exporting at scale

Read operations are rate limited per workspace. The search and listing endpoints used for export — search_traces and search_spans (and the underlying GET /traces and GET /spans endpoints) — are capped at 30 requests per minute per workspace. Exceeding a limit returns 429 Too Many Requests with a RateLimit-Reset header telling you how long to wait. See the rate-limit FAQ for the full list.

That budget is small, so how you fetch matters:

  • Fetch in bulk, not item-by-item. A single search_spans call streams up to 2,000 rows per underlying request, auto-paginates, and backs off on 429, so one call can return thousands of spans without ever erroring. Avoid making one request per trace.
  • Filter on the server with filter_string (e.g. a time window) so you only transfer the data you need.
  • Go easy on concurrency. Limits are shared per workspace, so parallel requests compete for the same budget and hit 429 sooner without finishing faster.
✅ Do: fetch in bulk, join on the client
1from collections import defaultdict
2
3traces = client.search_traces(project_name="Default project", max_results=1000000)
4
5# One call for all the spans, then group them by trace_id in memory.
6spans = client.search_spans(project_name="Default project", max_results=1000000)
7spans_by_trace = defaultdict(list)
8for span in spans:
9 spans_by_trace[str(span.trace_id)].append(span)
❌ Don't: one request per trace
1traces = client.search_traces(project_name="Default project", max_results=1000000)
2
3# A request per trace: slow, and quickly hits the read rate limit.
4spans_by_trace = {}
5for trace in traces:
6 spans_by_trace[trace.id] = client.search_spans(
7 project_name="Default project", trace_id=trace.id
8 )

REST API

Use the /traces and /spans endpoints to export data. Both endpoints are paginated.

The REST API filter parameter has limited flexibility as it was designed for use with the Opik UI. For complex queries, use the SDK instead. These endpoints are also rate limited and do not back off on their own — for large exports, prefer the SDK (see Exporting at scale) or implement your own retry on 429 that honors the RateLimit-Reset header.

UI

Select the traces or spans you want to export in the Opik dashboard and click Export CSV in the Actions dropdown.

The UI exports up to 100 traces or spans at a time. For larger exports use the SDK or CLI.

Command-line tools

The opik export and opik import commands let you export traces, spans, datasets, prompts, and experiments for a project to local JSON or CSV files, and import them back — useful for migrations, backups, and cross-environment syncs. Every command is scoped to a single project, named right after the workspace.

On disk, folders and files are keyed by ID: data lands under <path>/<workspace>/projects/<project_id>/, with a project.json ({"id", "name"}) and id-named item files (dataset_<id>.json, prompt_<id>.json, experiment_<id>.json, trace_<id>.json). Human names are stored as data inside the files — this keeps paths free of /, :, and spaces. You still pass project and item names on the command line; the CLI resolves names ↔ IDs for you.

Export

$opik export WORKSPACE PROJECT ITEM [NAME] [OPTIONS]

ITEM is one of: all, dataset, traces, experiment, prompt

$# Export everything in a project
$opik export my-workspace my-project all
$
$# Export the project's traces
>opik export my-workspace my-project traces
>
># Export a specific dataset
>opik export my-workspace my-project dataset "my-test-dataset"
>
># Export with a date filter
>opik export my-workspace my-project traces \
> --filter 'created_at >= "2024-01-01T00:00:00Z"'
>
># Export as CSV for analysis
>opik export my-workspace my-project traces --format csv --path ./csv_data

Import

$opik import WORKSPACE PROJECT ITEM [NAME] [OPTIONS]

WORKSPACE is the source workspace — used to locate the exported files under <path>/WORKSPACE/projects/. Use --to-workspace to write into a different destination workspace.

$# Import a dataset
$opik import my-workspace my-project dataset "my-dataset"
$
$# Import the project's traces
>opik import my-workspace my-project traces
>
># Preview what would be imported
>opik import my-workspace my-project all --dry-run
>
># Import into a different destination project
>opik import my-workspace my-project all --to-project my-restore
>
># Import into a different destination workspace
>opik import src-workspace my-project all --to-workspace dest-workspace
>
># Import into a different workspace and project
>opik import src-workspace my-project all --to-workspace dest-workspace --to-project new-project

The project name is matched against the name recorded in each exported project.json. Import uses the same --path as export (both resolve <path>/<workspace>/projects/<id>/), so no path juggling is needed. Use --to-project <NAME> to import into a different destination project, or --to-workspace <NAME> to import into a different workspace (the source WORKSPACE argument is still used to locate the files on disk).

Imports are automatically resumable — if interrupted, re-run the same command and it picks up where it left off using a local migration_manifest.db.

Migrating between environments

$# Step 1: Export from source (use source credentials)
$# Writes to ./migration_data/my-workspace/projects/<project_id>/
$OPIK_API_KEY=<source_key> OPIK_URL_OVERRIDE=https://source.opik.example.com \
> opik export my-workspace my-project all --path ./migration_data
$
$# Step 2: Import to destination — same workspace (use destination credentials)
$# Same --path as export — import resolves <path>/my-workspace/projects/<id>/.
$OPIK_API_KEY=<dest_key> OPIK_URL_OVERRIDE=https://dest.opik.example.com \
> opik import my-workspace my-project all --path ./migration_data
$
$# Step 2 (alternative): Import into a different destination workspace
$# WORKSPACE (my-workspace) still locates the files; --to-workspace sets the API target.
$OPIK_API_KEY=<dest_key> OPIK_URL_OVERRIDE=https://dest.opik.example.com \
> opik import my-workspace my-project all --path ./migration_data --to-workspace dest-workspace

See the CLI help (opik export --help / opik import --help) for all options and troubleshooting.