JavaScript SDK (preview)

Typed TypeScript helpers for instrumenting your AI agent — install from source while the SDK is in preview.

The JavaScript SDK (@obsivara/sdk@0.1.0) is in preview and is not yet published to npm. Install from source using the instructions below. The generic webhook and OTLP methods above need no install and work today.
There is no Python SDK. Use the generic webhook from Python — it is a plain HTTP POST and works with the standard requests or httpx library.

Install from source

bash
# Clone the repo (or copy the sdk/ directory into your project)
git clone https://github.com/obsivara/obsivara.git

# Build the SDK
cd obsivara/sdk
npm install
npm run build

# In your project — reference the local build
# package.json:
{
  "dependencies": {
    "@obsivara/sdk": "file:../path/to/sdk"
  }
}

Exported API surface

The SDK exports the following from @obsivara/sdk:

ExportKindDescription
ObsivaraClientclassMain client. Construct with { apiKey, workspaceId, endpoint? }.
client.startRun(data)methodPush a run_start event; returns runId (auto-generated UUID if not provided).
client.recordLlmCall(data)methodPush an llm_call event; accumulates tokens/cost for the run automatically.
client.endRun(runId, data)methodPush a run_end event; auto-fills totalTokens/totalCost from accumulated LLM calls.
client.flush()async methodFlush all buffered events immediately. Call before process exit.
client.wrapGemini(opts)methodReturns a { generate(runId, prompt, config?) } wrapper that auto-records the full llm_call (tokens, cost, latency, prompt, completion).
EventBufferclassInternal buffer (exported for advanced use — not needed in normal usage).

Type exports: ClientConfig, RunStart, RunEnd, LlmCallData, ToolCallData, SpanData, ErrorEventData, PromptVersionData, Event.

Basic usage

typescript
import { ObsivaraClient } from "@obsivara/sdk";

const client = new ObsivaraClient({
  apiKey: "obs_live_YOUR_KEY",
  workspaceId: "YOUR_WORKSPACE_ID",
  // endpoint defaults to https://api.obsivara.com
});

// Start a run — returns a runId
const runId = client.startRun({
  name: "Support reply",
  assetId: "support-agent",
  input: "Where is my order?",
});

// Record an LLM call within the run
client.recordLlmCall({
  runId,
  provider: "openai",
  model: "gpt-4o",
  promptTokens: 312,
  completionTokens: 87,
  totalTokens: 399,
  costUsd: 0.0048,
  latencyMs: 1240,
});

// End the run — totalTokens/totalCost auto-derived from recordLlmCall if omitted
client.endRun(runId, {
  status: "success",
  durationMs: 3500,
});

// Flush buffered events before process exit
await client.flush();

Trace helper

client.trace() handles startRun + endRun automatically, including error handling:

typescript
// client.trace() handles startRun + endRun automatically
const result = await client.trace("Support reply", "support-agent", async (runId) => {
  const answer = await callMyLLM(runId);
  return answer;
});

Auto-instrument Gemini

wrapGemini calls the Gemini API and records a complete llm_call event automatically — tokens (from usageMetadata), cost (from the built-in pricing table), latency, prompt, and completion. PII is redacted before transmission.

typescript
import { ObsivaraClient } from "@obsivara/sdk";

const client = new ObsivaraClient({
  apiKey: "obs_live_YOUR_KEY",
  workspaceId: "YOUR_WORKSPACE_ID",
});

// wrapGemini auto-records tokens, cost, latency, prompt, and completion
const gemini = client.wrapGemini({
  apiKey: "GOOGLE_API_KEY",
  model: "gemini-2.0-flash",
});

const runId = client.startRun({ name: "Chat", assetId: "my-chatbot" });
const reply = await gemini.generate(runId, "Explain OTLP in one sentence.");
client.endRun(runId, { status: "success", durationMs: 800 });

await client.flush();

Buffering and flushing

Events are buffered in memory and sent to POST /ingest/batch in batches (default: flush every 5 seconds or every 50 events, whichever comes first). Call client.flush() before your process exits to avoid losing the final batch. For serverless environments where the process terminates immediately, call await client.flush() before returning from your handler.

The SDK sends all events to POST https://api.obsivara.com/ingest/batch — the same endpoint you can call directly. If you prefer no dependencies, the generic webhook gives you the same result with a plain HTTP call.

Next steps