Trace format

SellTraces normalizes source-specific conversations into a shared trace shape before ingest. The public API accepts normalized JSON traces through POST /api/ingest.

Minimal accepted shape

Each trace must include a source, source id, creation time, and messages.
{
  "traces": [
    {
      "source": "codex_jsonl",
      "sourceId": "session-123",
      "model": "gpt-5",
      "createdAt": "2026-06-04T12:00:00.000Z",
      "messages": [
        {
          "position": 0,
          "role": "user",
          "content": "Build a trace uploader.",
          "tokenCount": 6,
          "createdAt": "2026-06-04T12:00:00.000Z"
        }
      ]
    }
  ]
}
The generated OpenAPI reference documents the accepted request body for POST /api/ingest.

Supported sources

The current normalized source values are:
SourceMeaning
claude_exportClaude web export ZIP
chatgpt_exportChatGPT web export ZIP
claude_code_jsonlClaude Code local JSONL
cursor_sqliteCursor SQLite state
codex_jsonlCodex CLI session data
gemini_cliGemini CLI local traces
opencodeOpenCode local traces
local_trace_indexLocal trace index database

Extended fields

The ingest package also supports richer V2 trace metadata when a source can provide it:
  • schemaVersion, conversationId, sessionId, parentTraceId
  • provider, client, agent, modelVersion
  • systemPrompt, toolsAvailable, contentBlocks
  • environment with cwd, git, OS, shell, permission, and sandbox fields
  • timing and usage details
  • outcome and trajectory details for coding-agent sessions
  • consent, license, piiScrub, and originalHash provenance fields
  • quality, domain, language, difficulty, and task metadata
When these fields are absent, the server fills what it can during normalization, scoring, and ingest.

Message roles

Messages use one of:
  • system
  • user
  • assistant
  • tool
content is the plain text used for token counts, search, dedupe, and generated OpenAPI validation. Rich sources may also include structured contentBlocks.

Deduplication fields

source plus sourceId provides source-level idempotency. originalHash provides content-level dedupe. If originalHash is absent, the server computes a hash from normalized role/content text. Within one ingest batch, duplicate source keys or duplicate content hashes are rejected before DB insert. Across persisted traces, duplicates refresh nullable metadata on the canonical trace instead of creating another trace row.