Skip to main content
Tracing records the chat completions your app already makes and stores them as traces on a Freesolo project. Point your existing OpenAI-compatible client at Freesolo’s recording endpoint, let it record while your app runs, then pull the traces down with flash traces export as task records - real production traffic becomes the dataset/train.jsonl you train on.
Tracing needs an existing project id: traces are stored per-project, and a recording request without one is rejected rather than stored nowhere. Create a project in the dashboard or with flash projects create.
Tracing records chat completions only (POST /chat/completions). The responses, embeddings, images, and audio APIs are not recorded, and neither are non-OpenAI-compatible native clients such as the Anthropic SDK messages API.

How recording works

Freesolo exposes one managed OpenAI-compatible recording endpoint at https://api.freesolo.co/v1. It is a pass-through proxy: it forwards your request to the upstream provider you pick, using a provider key you supply, returns the response unchanged, and stores a trace on the way through. Streaming works too: frames relay unbuffered and the trace is written after the stream completes. Because it is a pass-through, Freesolo stores no provider credentials and does not bill the inference. You send your own provider key per request and are billed by that provider directly, separate from Flash billing. The key transits the proxy as the upstream Authorization header without ever being persisted to a trace or a log. Supported upstream providers are openai, anthropic, openrouter, and google (Anthropic and Google through their OpenAI-compatibility layers).

Request headers

X-Freesolo-Project-Id takes the id (not the name) of a project that already exists in your org; recording never creates one. Omitting it on a recording request returns 400, and an id outside your org returns 404.

Secrets are redacted

Before anything is forwarded upstream or written to a trace, the proxy replaces two kinds of values with [redacted]:
  • Secret-named fields anywhere in the request or response body: authorization, proxy-authorization, and keys ending in api_key, secret, token, password, passwd, credential, credentials, or private_key, compared with case, underscores, and dashes ignored. The token suffix is matched in the singular, so max_tokens and completion_tokens pass through, and JSON Schema definitions (a tool property literally named token) are preserved.
  • Your credentials by value: the Freesolo API key and the provider key, wherever they appear, including inside message content.
Everything else (model, messages, tools, usage) passes through untouched.

Record from your app

Apply exactly one of these; both record identically through the same endpoint.

Method A: the drop-in SDK

For Python or TypeScript apps, the freesolo SDK ships a drop-in that subclasses the official OpenAI client and points itself at the recording endpoint. Do not set the base URL yourself.
The drop-in reads your Freesolo key from FREESOLO_API_KEY and accepts the project id as project_id / freesolo.projectId (or FREESOLO_PROJECT_ID). Carry over the original client’s behavioral options (timeout, retries, default headers) but not base_url or api_key: the drop-in owns routing and authentication. The provider headers are not set by the SDK itself; pass them as default headers as shown, or the proxy rejects the call with a 400 naming the missing header.

Method B: the base-URL proxy

Any OpenAI-compatible client works (the stock OpenAI SDK, OpenRouter, LiteLLM, the Vercel AI SDK) with no new dependency. Change only the base URL and headers:
Keep every request argument, including model and messages, unchanged.
Route through the recording endpoint only when FREESOLO_API_KEY is present, so your app still works when Freesolo is not configured. If a shared client also serves unrelated calls, build a separate client at the call site you want recorded instead of rerouting the shared one.

Export traces as a dataset

The export reads the newest 1000 traces in the project and writes them as {"input", "output"} records to dataset/train.jsonl, exactly the shape flash env setup scaffolds, so it drops into an environment unchanged:
dataset/train.jsonl
--format prompts exports {"input"}-only rows for GRPO and OPD, which train from prompts alone, and --format raw writes the stored trace rows unconverted. See the CLI reference for the full flag list. flash traces export ships in Flash 1.0.19; --format needs 1.0.22.

How a trace becomes a record

Traces with no extractable request/response pair are skipped, and the CLI reports the count. Because the export is an ordinary dataset, everything in Datasets applies: a scalar output becomes one assistant message, and {"messages": [...]} a full gold trajectory for SFT.
Rows whose output is a tool call score 0.0 under the scaffolded score_response, a string containment check that a correct tool call never satisfies. Train those rows with SFT, which needs no reward function, or replace the GRPO reward with one that compares the parsed tool call’s name and arguments. Text rows are ready for GRPO as scaffolded.

Seed a new environment from traces

You do not have to export by hand and wire the file up yourself. flash env setup can seed a new environment straight from a project’s traces:
When the selected project has traces and no dataset/train.jsonl exists yet, an interactive run offers to seed the dataset from them and sizes max_examples to the number of rows it exported. Traces are a head start, never a requirement: decline, or hit an export failure, and setup falls back to the starter dataset.

View traces in the dashboard

Each project has a Traces tab in the dashboard, with a per-trace detail view and aggregates over the project: score, pass rate, p50 latency, average output tokens and LLM calls per trace, and error rate. The tab can also export: select the traces you want and download them as JSONL, in the same records, prompts, and raw shapes as the CLI’s --format. The two files are interchangeable; the difference is that the dashboard exports exactly what you select, while flash traces export takes the newest 1000 in the project.

Next steps

Datasets

Everything the exported records can express.

Training

Train SFT, GRPO, or OPD on the exported dataset.