Skip to main content

View on npm

netra-sdk on npm registry

View on Yarn

netra-sdk on Yarn registry

Installation

npm install netra-sdk
yarn add netra-sdk
pnpm add netra-sdk

Netra Class

The Netra class is the main entry point for all SDK operations. All methods are static and can be called directly on the class.
import { Netra } from "netra-sdk";

Initialization & Lifecycle

init

Initialize the Netra SDK with configuration options. This method is async and waits for all instrumentations to be ready before returning. Call this once at the start of your application, before importing other libraries for best results.
import { Netra, NetraInstruments } from "netra-sdk";

await Netra.init({
  appName: "my-ai-app",
  headers: `x-api-key=${process.env.NETRA_API_KEY}`,
  environment: "production",
  traceContent: true,
  instruments: new Set([NetraInstruments.OPENAI, NetraInstruments.LANGCHAIN]),
});
Always await the init() call to ensure all instrumentations (like OpenAI, Anthropic, LangGraph) are fully patched before your application starts using them.
Parameters:
ParameterTypeDescription
appNamestring?Name of your application for identification in the dashboard
headersstring?Headers for API requests (e.g., x-api-key=your-key)
disableBatchboolean?Disable batch processing of spans (default: false)
traceContentboolean?Enable tracing of prompt/completion content (default: true)
resourceAttributesRecord<string, any>?Additional OpenTelemetry resource attributes
environmentstring?Application environment (e.g., “production”, “staging”)
instrumentsSet<NetraInstruments>?Set of instrumentations to enable (enables only these)
blockInstrumentsSet<NetraInstruments>?Set of instrumentations to disable
enableRootSpanboolean?Create a root span wrapping all traces
debugModeboolean?Enable debug logging
enableScrubbingboolean?Enable PII scrubbing
blockedSpansstring[]?Span names to filter out globally (supports wildcards)
Returns: Promise<void>

Tracing

startSpan

Create a new span for manual tracing. Returns a SpanWrapper that must be explicitly ended with end().
import { Netra, SpanType } from "netra-sdk";

// Basic usage
const span = Netra.startSpan("process-document");
try {
  const result = await processDocument(doc);
  span.setAttribute("pages", result.pageCount);
  span.setSuccess();
} catch (error) {
  span.setError(error.message);
  throw error;
} finally {
  span.end();
}

// With options
const genSpan = Netra.startSpan("generate-response", {
  attributes: { model: "gpt-4" },
  moduleName: "chat",
  asType: SpanType.GENERATION,
});
Parameters:
ParameterTypeDescription
namestringName of the span (required)
options.attributesRecord<string, any>?Initial attributes to set
options.moduleNamestring?Module name for organization
options.asTypeSpanType?Type of span for categorization
options.blockedSpansstring[]?Patterns for blocking descendant spans
Returns: SpanWrapper

startActiveSpan

Create a span that is automatically set as the active span in the current context for the duration of the callback. Child spans created inside the callback will be parented under this span. The span is ended automatically when the callback completes or throws.
import { Netra, SpanType } from "netra-sdk";

// Basic usage — span auto-ends when the callback resolves
const result = await Netra.startActiveSpan("handle-request", async (span) => {
  span.setAttribute("endpoint", "/api/chat");
  const response = await processRequest();
  span.setSuccess();
  return response;
});

// With options
const result = await Netra.startActiveSpan(
  "generate-response",
  {
    attributes: { model: "gpt-4" },
    moduleName: "chat",
    asType: SpanType.GENERATION,
  },
  async (span) => {
    const response = await llm.generate(prompt);
    span.setSuccess();
    return response;
  },
);
Overloads:
Netra.startActiveSpan<T>(name: string, fn: (span: SpanWrapper) => T): T;
Netra.startActiveSpan<T>(name: string, options: SpanOptions, fn: (span: SpanWrapper) => T): T;
Parameters:
ParameterTypeDescription
namestringName of the span (required)
options.attributesRecord<string, any>?Initial attributes to set
options.moduleNamestring?Module name for organization
options.asTypeSpanType?Type of span for categorization
options.blockedSpansstring[]?Patterns for blocking descendant spans
fn(span: SpanWrapper) => TCallback executed within the span’s context
Returns: T (the return value of the callback)
If the callback returns a Promise, the span is ended when the promise settles. If it throws, the span is marked as errored and ended before re-throwing.

getTraceId

Get the trace ID of the currently active span. Returns undefined if there is no active span.
const traceId = Netra.getTraceId();
if (traceId) {
  console.log(`Current trace: ${traceId}`);
}
Returns: string | undefined

runWithRootSpan

Run a function with the root span as the active parent context. All spans created within the function will be children of the root span. Requires enableRootSpan: true in the init config.
await Netra.init({
  appName: "my-app",
  enableRootSpan: true,
});

await Netra.runWithRootSpan(async () => {
  // All spans created here are parented under the root span
  const span = Netra.startSpan("child-operation");
  await doWork();
  span.end();
});
This is necessary in JavaScript because OpenTelemetry JS has no persistent context.attach(). Without this wrapper, spans created outside a callback-based context will not be parented under the root span.
Parameters:
ParameterTypeDescription
fn() => TFunction to execute within the root span context
Returns: T (the return value of the function)

withBlockedSpansLocal

Suppress specific spans by name pattern within a scoped callback. Uses OpenTelemetry baggage for propagation, so the blocking applies to all descendant spans including those from auto-instrumentation. Patterns support wildcards.
import { Netra } from "netra-sdk";

// Block all HTTP spans within this scope
const result = await Netra.withBlockedSpansLocal(
  ["http.*", "*.resolve"],
  async () => {
    // HTTP spans created inside here are filtered out
    const data = await fetch("https://api.example.com/data");
    return data.json();
  },
);
Overloads:
Netra.withBlockedSpansLocal<T>(patterns: readonly string[], fn: () => Promise<T>): Promise<T>;
Netra.withBlockedSpansLocal<T>(patterns: readonly string[], fn: () => T): T;
Parameters:
ParameterTypeDescription
patternsreadonly string[]Span name patterns to block (supports wildcards like "http.*")
fn() => TFunction to execute within the blocked scope
Returns: T (the return value of the function)

Context

setSessionId

Set the session ID for the current context. All subsequent spans will be associated with this session.
Netra.setSessionId("session-abc123");
Parameters:
ParameterTypeDescription
sessionIdstringUnique identifier for the session
Returns: void

setUserId

Set the user ID for the current context. All subsequent spans will be tagged with this user.
Netra.setUserId("user-456");
Parameters:
ParameterTypeDescription
userIdstringUnique identifier for the user
Returns: void

setTenantId

Set the tenant ID for multi-tenant applications. All subsequent spans will be tagged with this tenant.
Netra.setTenantId("tenant-org-789");
Parameters:
ParameterTypeDescription
tenantIdstringUnique identifier for the tenant
Returns: void

setCustomAttributes

Add a custom key-value attribute to the current active span.
Netra.setCustomAttributes("customer_tier", "premium");
Netra.setCustomAttributes("region", "us-east");
Parameters:
ParameterTypeDescription
keystringAttribute key
valueanyAttribute value
Returns: void

setCustomEvent

Record a custom event on the current active span.
Netra.setCustomEvent("user_feedback", {
  rating: 5,
  comment: "Great response!",
  category: "positive",
});
Parameters:
ParameterTypeDescription
eventNamestringName of the event
attributesRecord<string, any>Event attributes
Returns: void

Input / Output

setInput

Set the input value on the current active span. Useful for recording what was sent to an operation.
Netra.setInput("What is the capital of France?");
Netra.setInput({ query: "capital of France", language: "en" });
Parameters:
ParameterTypeDescription
valueanyThe input value (will be serialized)
Returns: void

setOutput

Set the output value on the current active span. Useful for recording what an operation returned.
Netra.setOutput("The capital of France is Paris.");
Netra.setOutput({ answer: "Paris", confidence: 0.98 });
Parameters:
ParameterTypeDescription
valueanyThe output value (will be serialized)
Returns: void

setRootInput

Set the input value on the root span. Useful for recording the top-level input to your application.
Netra.setRootInput("Summarize this document");
Parameters:
ParameterTypeDescription
valueanyThe input value (will be serialized)
Returns: void

setRootOutput

Set the output value on the root span. Useful for recording the top-level output of your application.
Netra.setRootOutput("The document discusses three main topics...");
Parameters:
ParameterTypeDescription
valueanyThe output value (will be serialized)
Returns: void

Conversations

addConversation

Append a conversation entry to the current active span. Useful for tracking multi-turn LLM conversations.
import { Netra, ConversationType } from "netra-sdk";

Netra.addConversation(ConversationType.INPUT, "user", "What is the weather today?");
Netra.addConversation(ConversationType.OUTPUT, "assistant", "It's sunny and 72°F.");

// Content can also be an object
Netra.addConversation(ConversationType.INPUT, "user", {
  text: "Show me a chart",
  attachments: ["data.csv"],
});
Parameters:
ParameterTypeDescription
conversationTypeConversationTypeWhether this is an INPUT or OUTPUT entry
rolestringThe role of the speaker (e.g., "user", "assistant", "system")
contentstring | Record<string, any>The conversation content
Returns: void

Sub-clients

After calling Netra.init(), the following sub-clients are available as static properties on the Netra class. Each provides domain-specific functionality.
PropertyTypeDescription
Netra.usageUsageQuery span and trace data, session/tenant usage metrics
Netra.evaluationEvaluationManage datasets, run evaluations, and score results
Netra.dashboardDashboardQuery dashboard data and time-series metrics
Netra.simulationSimulationRun conversation simulations and test suites
Netra.promptsPromptsFetch and manage prompt templates

SpanWrapper Class

The SpanWrapper class provides methods for enriching spans with additional context. It’s returned by Netra.startSpan() and supports method chaining.

setAttribute

Add a custom attribute to the span.
span.setAttribute("query", userQuery);
span.setAttribute("results.count", results.length);
Parameters:
ParameterTypeDescription
keystringAttribute key
valueanyAttribute value
Returns: SpanWrapper (for chaining)

addEvent

Record a timestamped event within the span.
span.addEvent("validation-started");
span.addEvent("validation-completed", { valid: true, errors: 0 });
Parameters:
ParameterTypeDescription
namestringEvent name
attributesRecord<string, any>?Event attributes
Returns: SpanWrapper (for chaining)

setPrompt

Set the input prompt for LLM spans.
span.setPrompt("Summarize this article: ...");
Parameters:
ParameterTypeDescription
promptstringThe prompt text
Returns: SpanWrapper (for chaining)

setNegativePrompt

Set the negative prompt (commonly used for image generation).
span.setNegativePrompt("blurry, low quality, distorted");
Parameters:
ParameterTypeDescription
promptstringThe negative prompt text
Returns: SpanWrapper (for chaining)

setModel

Set the model name used in the operation.
span.setModel("gpt-4-turbo");
Parameters:
ParameterTypeDescription
modelstringModel name
Returns: SpanWrapper (for chaining)

setLlmSystem

Set the LLM provider/system name.
span.setLlmSystem("openai");
Parameters:
ParameterTypeDescription
systemstringLLM system name
Returns: SpanWrapper (for chaining)

setUsage

Record token usage and cost metrics.
span.setUsage([
  {
    model: "gpt-4",
    costInUsd: 0.006,
    usageType: "chat",
    unitsUsed: 1,
  },
]);
Parameters:
ParameterTypeDescription
usageDataUsageModel[]List of usage records
Returns: SpanWrapper (for chaining)

setAction

Track actions or tool calls within the span.
span.setAction([
  {
    action: "DB",
    actionType: "INSERT",
    affectedRecords: [{ recordId: "123", recordType: "user" }],
    metadata: { table: "users" },
    success: true,
  },
]);
Parameters:
ParameterTypeDescription
actionsActionModel[]List of action records
Returns: SpanWrapper (for chaining)

setSuccess

Mark the span as successful.
span.setSuccess();
Returns: SpanWrapper (for chaining)

setError

Mark the span as failed with an error message.
span.setError("Failed to connect to database");
Parameters:
ParameterTypeDescription
messagestringError message
Returns: SpanWrapper (for chaining)

end

End the span. Required in TypeScript - spans won’t be exported until end() is called.
span.end();
Returns: void
Always call span.end() in TypeScript, preferably in a finally block to ensure spans are closed even when errors occur.

Types and Interfaces

SpanType

Enum for categorizing spans.
import { SpanType } from "netra-sdk";

SpanType.SPAN;       // General operations (default)
SpanType.GENERATION; // LLM completions, image generation
SpanType.EMBEDDING;  // Vector embedding operations
SpanType.TOOL;       // Function calls, API requests
SpanType.AGENT;      // AI agent operations

UsageModel

Interface for tracking token usage and costs.
interface UsageModel {
  model: string;
  costInUsd?: number;
  usageType?: string;
  unitsUsed?: number;
}
Example:
const usage: UsageModel = {
  model: "gpt-4",
  costInUsd: 0.0045,
  usageType: "chat",
  unitsUsed: 1,
};

ActionModel

Interface for tracking actions and tool calls.
interface ActionModel {
  action: string;
  actionType: string;
  affectedRecords?: Array<{
    recordId: string;
    recordType: string;
  }>;
  metadata?: Record<string, string>;
  success: boolean;
}
Example:
const action: ActionModel = {
  action: "API",
  actionType: "CALL",
  affectedRecords: [{ recordId: "order-123", recordType: "order" }],
  metadata: {
    endpoint: "/api/orders",
    method: "POST",
    statusCode: "201",
  },
  success: true,
};

Decorators

TypeScript decorators for easy function instrumentation.
TypeScript decorators require "experimentalDecorators": true in your tsconfig.json.

@agent

Mark a function or class as an AI agent.
import { agent } from "netra-sdk/decorators";

@agent
async function researchAgent(query: string) {
  return await performResearch(query);
}

@agent({ name: "customer-support" })
async function supportAgent(request: Request) {
  return await handleRequest(request);
}

@task

Mark a function as a task or tool.
import { task } from "netra-sdk/decorators";

@task
async function fetchData(query: string) {
  return await database.query(query);
}

@task({ name: "web-search" })
async function searchWeb(query: string) {
  return await searchApi.search(query);
}

@workflow

Mark a function as a workflow.
import { workflow } from "netra-sdk/decorators";

@workflow
async function processOrder(order: Order) {
  await validateOrder(order);
  await processPayment(order);
  await fulfillOrder(order);
}

Instruments

Available instrumentations for auto-tracing.
import { NetraInstruments } from "netra-sdk";

// LLM Providers
NetraInstruments.OPENAI;
NetraInstruments.GOOGLE_GENAI;
NetraInstruments.MISTRAL;
NetraInstruments.GROQ;
NetraInstruments.VERTEX_AI;
NetraInstruments.TOGETHER;

// AI Frameworks
NetraInstruments.LANGCHAIN;
NetraInstruments.LANGGRAPH;
NetraInstruments.LLAMAINDEX;

// Vector Databases
NetraInstruments.PINECONE;
NetraInstruments.QDRANT;
NetraInstruments.CHROMADB;

// HTTP Clients
NetraInstruments.HTTP;
NetraInstruments.HTTPS;
NetraInstruments.FETCH;

// Web Frameworks
NetraInstruments.EXPRESS;
NetraInstruments.FASTIFY;
NetraInstruments.NESTJS;

// Databases
NetraInstruments.PRISMA;
NetraInstruments.TYPEORM;
NetraInstruments.MONGODB;
NetraInstruments.POSTGRES;
NetraInstruments.MYSQL;
NetraInstruments.REDIS;

// Message Queues
NetraInstruments.KAFKA;
NetraInstruments.RABBITMQ;

Complete Example

import { Netra, SpanType, NetraInstruments } from "netra-sdk";
import OpenAI from "openai";

// Initialize SDK (must await to ensure instrumentations are ready)
await Netra.init({
  appName: "my-ai-app",
  headers: `x-api-key=${process.env.NETRA_API_KEY}`,
  environment: "production",
  instruments: new Set([NetraInstruments.OPENAI]),
});

// Set context
Netra.setUserId("user-123");
Netra.setSessionId("session-abc");

// Create a traced operation
async function chatWithAI(userMessage: string): Promise<string> {
  const span = Netra.startSpan("chat-completion", {}, undefined, SpanType.GENERATION);

  span.setPrompt(userMessage);
  span.setModel("gpt-4");
  span.setLlmSystem("openai");

  try {
    const client = new OpenAI();
    const response = await client.chat.completions.create({
      model: "gpt-4",
      messages: [{ role: "user", content: userMessage }],
    });

    // Calculate cost based on token usage
    const promptCost = ((response.usage?.prompt_tokens || 0) / 1000) * 0.03;
    const completionCost = ((response.usage?.completion_tokens || 0) / 1000) * 0.06;
    const totalCost = promptCost + completionCost;

    span.setUsage([
      {
        model: "gpt-4",
        costInUsd: totalCost,
        usageType: "chat",
        unitsUsed: 1,
      },
    ]);

    span.setSuccess();
    return response.choices[0].message.content || "";
  } catch (error: any) {
    span.setError(error.message);
    throw error;
  } finally {
    span.end();
  }
}

// Use the function
const result = await chatWithAI("What is the capital of France?");
console.log(result);

// Shutdown gracefully
await Netra.shutdown();

Express.js Integration

Example of integrating Netra with Express.js:
import express from "express";
import { Netra, NetraInstruments } from "netra-sdk";

async function main() {
  // Initialize before creating the app (must await)
  await Netra.init({
    appName: "my-api",
    headers: `x-api-key=${process.env.NETRA_API_KEY}`,
    instruments: new Set([NetraInstruments.EXPRESS, NetraInstruments.OPENAI]),
  });

  const app = express();

  // Middleware to set user context
  app.use((req, res, next) => {
    if (req.headers["x-user-id"]) {
      Netra.setUserId(req.headers["x-user-id"] as string);
    }
    if (req.headers["x-session-id"]) {
      Netra.setSessionId(req.headers["x-session-id"] as string);
    }
    next();
  });

  app.post("/api/chat", async (req, res) => {
    const span = Netra.startSpan("handle-chat-request");

    try {
      const { message } = req.body;
      span.setAttribute("input.length", message.length);

      const response = await processMessage(message);

      span.setSuccess();
      res.json({ response });
    } catch (error: any) {
      span.setError(error.message);
      res.status(500).json({ error: error.message });
    } finally {
      span.end();
    }
  });

  // Graceful shutdown
  process.on("SIGTERM", async () => {
    await Netra.shutdown();
    process.exit(0);
  });

  app.listen(3000);
}

main();

Key Differences from Python SDK

FeaturePythonTypeScript
InitializationNetra.init() (sync)await Netra.init() (async, waits for instrumentations)
Span lifecycleContext manager (with statement)Manual end() call required
Naming conventionsnake_casecamelCase
Instruments enumInstrumentsNetraInstruments
ShutdownNetra.shutdown()await Netra.shutdown()
AsyncContext managers work with sync/asyncAlways use async/await

Next Steps

Last modified on July 8, 2026