DEVELOPER DOCS

REST API

Usage, Latency & Cost

On this page

Workspace-level rollups. These power the cost and speed dashboard.


Usage summary

HTTP
GET /v1/observ/orgs/{org}/workspaces/{ws}/usage/summary

Headline totals for one period — traces, tokens, cost, error rate.

Auth: API key or JWT · Role: viewer

Query parameters

NameTypeRequiredDefaultDescription
periodstring➖dayday | week | month

Response 200 — not schema-modelled

The payload is data, containing totals plus two breakdowns:

JSON
{
  "data": {
    "period": "day",
    "workspace_id": "3f2b1c8e-9a4d-4f11-b7c2-1e5a8d3f6b90",
    "totals":     { "trace_count": 12480, "cost_usd": 412.87 },
    "by_model":   [ { "model": "claude-opus-4-6", "cost_usd": 311.02 } ],
    "by_project": [ { "project_id": "checkout-agent", "cost_usd": 208.44 } ]
  },
  "meta": { "request_id": "9f2c4b1e…", "scorer_version": "2.1.0" }
}

Exact keys inside totals, by_model, and by_project are computed and not schema-modelled — inspect one live response before typing against them.

Examples

r = evigauge.get("/v1/observ/orgs/{org}/workspaces/{ws}/usage/summary",
                 params={"period": "week"})
d = r["data"]
print(d["totals"])
for row in d["by_model"]:
    print(" ", row)

Usage timeseries

HTTP
GET /v1/observ/orgs/{org}/workspaces/{ws}/usage/timeseries

Bucketed usage over time, for charting.

Auth: API key or JWT · Role: viewer

Query parameters

NameTypeRequiredDefaultDescription
periodstring➖dayday only. v1 emits one row per calendar day; week / month return 400.
daysinteger➖30How many days back to cover

Unlike the other rollup endpoints, this one accepts only period=day. Aggregate to weeks or months client-side from the daily buckets.

Response 200 — not schema-modelled

JSON
{
  "period": "day",
  "days": 30,
  "points": [
    { "ts": "2026-08-03T00:00:00Z", "trace_count": 401, "total_tokens": 610233, "total_cost_usd": 13.94 }
  ]
}

Examples

ts = evigauge.get("/v1/observ/orgs/{org}/workspaces/{ws}/usage/timeseries",
                  params={"period": "day", "days": 14})
for p in ts["points"]:
    print(p["ts"][:10], f"${p['total_cost_usd']:.2f}")

Latency by phase

HTTP
GET /v1/observ/orgs/{org}/workspaces/{ws}/usage/latency

Latency percentiles broken down by execution phase. Tells you which stage is slow, not just that the whole trace is slow.

Auth: API key or JWT · Role: viewer

Query parameters

NameTypeRequiredDefaultDescription
periodstring➖dayday | week | month

Response 200 — not schema-modelled

JSON
{
  "period": "day",
  "phases": [
    { "phase": "retrieval", "p50_ms": 210, "p95_ms": 890,  "p99_ms": 1400, "call_count": 12480, "error_count": 12 },
    { "phase": "llm_call",  "p50_ms": 940, "p95_ms": 5200, "p99_ms": 9100, "call_count": 51203, "error_count": 340 }
  ]
}

Examples

lat = evigauge.get("/v1/observ/orgs/{org}/workspaces/{ws}/usage/latency",
                   params={"period": "day"})
worst = max(lat["phases"], key=lambda p: p["p95_ms"])
print(f"Slowest phase: {worst['phase']} @ p95 {worst['p95_ms']}ms")

Phase trace drill-down

HTTP
GET /v1/observ/orgs/{org}/workspaces/{ws}/usage/latency/phase/traces

The individual traces behind one phase's percentile or error count. This is the drill-down from a slow bar in the latency chart to the actual traces that caused it.

Auth: API key or JWT · Role: viewer

Query parameters

NameTypeRequiredDefaultDescription
phasestring✅—Phase name, exactly as returned by /usage/latency
metricstring✅—errors (a span in the phase errored) or slow (span duration ≥ the phase's live percentile)
periodstring➖dayday | week | month
percentilestring➖p95p95 | p99. Applies only when metric=slow.
limitinteger➖100Max traces returned, 1–500

The values are errors and slow — not error / latency. An invalid metric, period, or percentile returns 400 with the accepted list in detail.

threshold_ms is computed over the same population as the latency panel, so the number matches what the chart showed. An empty traces array is a valid healthy state, not an error.

Response 200 — not schema-modelled

JSON
{
  "phase": "llm_call",
  "metric": "slow",
  "percentile": "p95",
  "threshold_ms": 5200,
  "traces": [
    { "trace_id": "4bf92f...", "duration_ms": 9840, "start_time": "2026-09-01T14:23:05Z", "status": "ok" }
  ]
}

Examples

slow = evigauge.get(
    "/v1/observ/orgs/{org}/workspaces/{ws}/usage/latency/phase/traces",
    params={"phase": "llm_call", "metric": "slow", "percentile": "p99", "limit": 20},
)
print(f"Traces above {slow['threshold_ms']}ms:")
for t in slow["traces"]:
    print(" ", t["trace_id"], t["duration_ms"])

Errors

StatusCause
400Unknown phase, or invalid metric / period / percentile value
422phase or metric omitted — both are required