Features
Everything in the v1 product, stated the way it's actually built.
Span detail, down to the hash.
Open any span and see exactly what Spanwise parsed from its GenAI attributes — model, tokens, cost estimate and status, with nothing reconstructed after the fact.
OTel-compatible trace ingestion
POST /v1/traces accepts OTLP/HTTP-JSON (resourceSpans with key-value attribute lists) or a flat {spans:[...]} shape. Batches up to 10,000 spans; gen_ai.* / llm.* semantic-convention attributes are parsed into model and token fields.
Trace viewer API
List traces aggregated per trace_id with service/status/model filters and pagination; fetch a full trace with every span ordered by start time.
LLM-judge eval harness
Pluggable judges: HeuristicJudge (deterministic keyword-overlap, runs in CI) and LLMJudge, which raises unless SPANWISE_JUDGE_API_KEY is set — it never pretends to judge without a provider.
Per-model cost attribution
Token spend rolled up per model with USD estimates from your MODEL_PRICES_JSON table. Labeled estimates everywhere — provider invoices are the source of truth.
Tamper-evident audit log
Every ingestion and manual entry is appended to a SHA-256 hash chain. /v1/audit/verify recomputes the whole chain; direct database tampering is detected and reported with the failing sequence number.
Retention tiers
7-day Starter / 90-day Team / custom Enterprise retention enforced by a scheduled sweep. Audit-log rows are never deleted — append-only by design.
API-key workspaces
Every endpoint except /health requires x-spanwise-key. The key identifies the workspace; there is no way to address another workspace's data — including audit logs.
Single-binary self-host
Ship it as one binary (the 0.1.0 release is built and smoke-tested) or a Docker image. SQLite for trials, Postgres for production via DATABASE_URL. Structured JSON logs to stdout; all config via environment.