All posts
ENGINEERING5 min read

LLM observability beyond Python and TypeScript

The Currai team, EngineeringMar 12, 2026

The SDKs cover Python and TypeScript because that's where most LLM code lives. But "most" isn't "all" — there's a Go service calling a model, a Rust worker doing retrieval, an Elixir backend orchestrating the whole thing. None of them should be a blind spot. Because Currai ingests over plain HTTP and OTLP, any language that can make a request can send a trace.

The ingestion endpoint is just HTTP

Under every SDK is an HTTP API. If there's no SDK for your language, call the API directly — authenticate with your key pair and POST the trace.

POST https://currai.app/api/public/ingestion
Authorization: Basic <base64 of pk:sk>
Content-Type: application/json

{
  "batch": [
    {"id": "evt-1", "type": "trace-create", "timestamp": "2026-01-01T00:00:00Z",
     "body": {"id": "trace-1", "name": "chat-turn", "userId": "user-1"}},
    {"id": "evt-2", "type": "generation-create", "timestamp": "2026-01-01T00:00:01Z",
     "body": {"id": "gen-1", "traceId": "trace-1", "name": "answer",
              "model": "gpt-4o-mini", "input": "...", "output": "..."}}
  ]
}

A thin wrapper over your language's HTTP client is often all the "SDK" you need.

Or speak OpenTelemetry

If your language has an OpenTelemetry SDK — and most do — you already have a mature, batteries-included client. Point its OTLP exporter at Currai and your spans flow in with retries, batching, and context propagation handled for you.

OTEL_EXPORTER_OTLP_ENDPOINT=https://currai.app/api/public/otel

This is usually the better path for non-Python/TS stacks: you lean on a well-tested exporter instead of hand-rolling HTTP.

One trace across many languages

The real payoff shows up in polyglot systems. A request that starts in a Go gateway, fans out to a Python model worker, and returns through a Node API can be one trace — if every hop propagates the same trace context. OpenTelemetry's context propagation makes that automatic across languages, so the trace reflects the request as the user experienced it, not as your service boundaries happened to carve it up.

Don't let language be the excuse

The reason teams under-instrument the non-Python parts of their stack is friction, not principle — there was no obvious client, so the spans never got written. With HTTP and OTLP as the floor, that excuse is gone. Every service that touches an LLM request can contribute to the trace, and the parts of your system that used to be dark stop being the place incidents hide.