Esc to close · ⌘K / Ctrl-K opens search anywhere
The console Logs tab is a request & trace explorer — one row per request, newest first. It answers “what did this call do, how long did it take, what did it cost, and can I correlate it end-to-end?” without ever weakening BharatRouter’szero-retention default.
Two layers, two postures. Metadata (model, provider, status, latency, tokens, ₹ cost, residency, cached/BYOK flags, trace id) is recorded for every request and always browsable. Request/response bodies are notstored unless your org explicitly turns on content logging.
Filter by model, status (OK 2xx / errors) and atime window (24 h / 7 / 30 / 90 days), or paste a trace id to pin a single request. Members see their own keys’ traffic; owners/admins (or holders ofusage:org:view) see the whole org. Click any row to expand its trace details.
The same rows are available as JSON — the console reads exactly this endpoint:
GET /me/activity/events?from=2026-08-01&to=2026-08-03&model=llama-3.1-8b-instruct&status=error&limit=50
→ { "events": [
{ "id": 91242, "at": "2026-08-03T08:14:22Z",
"model": "llama-3.1-8b-instruct", "provider": "krutrim",
"status": 200, "latency_ms": 612,
"prompt_tokens": 180, "completion_tokens": 74, "total_tokens": 254,
"cache_read_tokens": 0, "cost_inr": 0.019, "byok": false, "stream": true,
"residency": "india", "agent_id": null,
"trace_id": "4f1c8e2a9b7d6c5f0e3a2b1c9d8e7f60", "key_name": "prod" }
],
"next_before": 91191 }Filters: status=ok|error, model=,key_id=, workspace_id=, trace_id= (32 lowercase hex), plus thefrom/to IST date range. Paginate with before=<last id>(the response’s next_before).
Every request carries a W3C Trace Context id. An inbound traceparentheader continues the caller’s trace; otherwise the gateway mints a fresh root. That id is threaded onto the usage row (above) and, when an OTLP endpoint is configured, exported asmetadata-only spans — route, model, provider, residency, status, latency, failover reason, never prompt or response content. So tracing is safe by construction and needs no per-org switch. The full OTel waterfall / span-tree UI is a follow-up; today the console surfaces the trace id for correlation in your own collector.
Beyond the in-console trace id, an org can push gateway telemetry to its own SIEM — Datadog, Splunk, Grafana, or any collector that accepts OTLP/HTTP ingest. You register one or more per-org destinations; a background worker then streams new request records to each. Owners/admins manage destinations (isManager-gated and audited); the surface is reachable with a console session or a managementbr- key, so an agent can provision it headlessly.
Metadata only, residency-gated, fail-open. v1 exports otlp-traces — route, model, provider, residency, status, latency, tokens, ₹ cost — and neverprompt or response content. A per-destination residency allowlist decides which records may leave, the auth secret is encrypted at rest and never returned, and a broken destination is auto-disabled — it never blocks or slows a request.
Create a destination (owner/admin). export_residency is the allowlist of buckets whose records may egress (india / global / unknown; default["india"] — an empty list is rejected). auth_kind: "bearer" needs asecret; it is stored AES-256-GCM and only its mask is ever returned.
POST /me/siem-exports
{
"name": "datadog-prod",
"url": "https://http-intake.logs.datadoghq.com/api/v2/otlp/v1/traces",
"format": "otlp-traces", // only value in v1
"auth_kind": "bearer", // or "none"
"secret": "dd-api-key-…", // required for bearer; encrypted, never returned
"header_name": "authorization", // header the secret is sent in (default: authorization)
"headers": { "DD-OTLP-Source": "bharatrouter" }, // optional static headers
"export_residency": ["india"], // allowlist: india | global | unknown
"redact": true // strip any incidental identifiers
}
→ 201 { "id": 7, "name": "datadog-prod", "url": "https://…", "format": "otlp-traces",
"auth_kind": "bearer", "mask": "dd-…7f2c", "header_name": "authorization",
"headers": { "DD-OTLP-Source": "bharatrouter" },
"export_residency": ["india"], "redact": true, "enabled": true,
"failure_count": 0, "disabled_reason": null, "last_success_at": null,
"created_at": "…", "updated_at": "…" }A new destination exports now-forward only — it never back-fills history.
| Endpoint | What it does |
|---|---|
GET /me/siem-exports | List destinations (secrets masked). |
GET /me/siem-exports/:id | One destination. |
POST /me/siem-exports | Create a destination (owner/admin). |
PATCH /me/siem-exports/:id | Update name, url, allowlist, headers, or re-enable (owner/admin). |
POST /me/siem-exports/:id/rotate | Replace the bearer secret (owner/admin). |
POST /me/siem-exports/:id/test | Ship one synthetic metadata span to validate URL + auth, without touching the cursor. |
DELETE /me/siem-exports/:id | Remove a destination (owner/admin). |
If a destination fails repeatedly the worker sets enabled: false with adisabled_reason; fix it and PATCH enabled: true to resume (this clears the failure count and picks up from the current tip — it does not re-ship the gap). Exporting request/response bodies (otlp-logs, with redaction) is a gated follow-up: the format is rejected at create today.
Because inference is zero-retention, bodies are only inspectable when an owner/admin turns on the content-logging tier — a deliberate, bounded, audited departure from the default (see the toggle at the top of the Logs tab, orPUT /me/org/content-logging). When on, request/response pairs land in aphysically separate store, stamped with an expiry, and are hard-deleted once the retention window lapses.
The drill-in fetches a stored body by trace id — owner/admin only:
GET /me/logs/content?trace_id=4f1c8e2a9b7d6c5f0e3a2b1c9d8e7f60
// content logging OFF (the default) — NOT an error:
→ { "content_logging": false, "fleet_enabled": true, "reason": "opt_out" }
// content logging ON, body found:
→ { "content_logging": true, "found": true,
"entry": { "trace_id": "...", "model": "...", "status": 200,
"request_body": { ... }, "response_body": { ... },
"created_at": "...", "expires_at": "..." } }With content logging off, the console shows a clear affordance to enable it — not a failure. A member (non-manager) never sees bodies.