Developer Guide · 5 min

SDK Quickstart

Install the Bear Lumen SDK, initialize the client, track your first AI call, and attribute it. Pick your language below and every example follows along.

Getting started

Examples in
  1. 1

    Install the SDK

    Install the Bear Lumen Node.js SDK via npm:

    npm install @bearlumen/node-sdk
    
  2. 2

    Initialize the client

    Initialize the SDK once at startup. init() reads your API key from the BEARLUMEN_API_KEY environment variable, so there is nothing to plumb through your code and no key to hard-code. Create the key in your dashboard under Settings then API Keys, with the usage:write scope (to send events) and costs:read (to read costs back):

    TypeScript
    import { BearLumen, getBearLumen } from '@bearlumen/node-sdk';
    
    // One-time setup. Reads BEARLUMEN_API_KEY from the environment.
    BearLumen.init();
    
    // Anywhere in your app:
    const bear = getBearLumen();
    
    // Need explicit config? new BearLumen({ apiKey }) still works.
    
  3. 3

    Track an AI call

    Make an AI API call and pass the response to Bear Lumen for automatic cost tracking. If the model cannot be identified, the event is tracked as model "unknown" and no cost is calculated until a rate card exists, so pass a model option explicitly for custom setups:

    TypeScript
    import OpenAI from 'openai';
    
    const openai = new OpenAI();
    
    const response = await openai.chat.completions.create({
      model: 'gpt-4o-mini',
      messages: [{ role: 'user', content: 'Summarize this support ticket.' }],
    });
    
    // Pass the response straight through. Bear Lumen auto-detects the
    // provider and extracts the model and token counts. Cost is
    // calculated server-side once the event is processed.
    const result = bear.track(response);
    console.log(`${result.model}: ${result.inputTokens} in, ${result.outputTokens} out`);
    
  4. 4

    Wrap your client (recommended)

    Prefer this to calling track() per request. Wrap your provider client once and every call through it is tracked automatically: provider, model, tokens, cost. When one unit of work spans several calls (an agent run, a pipeline, a conversation turn), group them in a span and the whole call tree, its cost, and its outcome roll up together. See the Trace agentic work guide in Next steps for the full model:

    TypeScript
    import OpenAI from 'openai';
    
    // Wrap your provider client ONCE and every call through it is tracked
    // automatically: provider, model, tokens, cost. No per-call track() needed.
    // Wrapped calls also inherit the ambient span context (see Tracing agentic
    // work), so trees and sessions come for free once you add spans.
    const openai = bear.wrap(new OpenAI());
    
    const response = await openai.chat.completions.create({
      model: 'gpt-4o',
      messages: [{ role: 'user', content: 'Hello!' }],
    });
    // Already tracked. The response object is untouched; use it as normal.
    
  5. 5

    Add attribution

    Tag each call with a user, feature, agent, and any custom attributes so you can see exactly where your AI spend goes:

    TypeScript
    // Attribute each call so you can slice spend by who, what, and any
    // custom key you define. Built-in fields (userId, feature, agentId)
    // plus a free-form `metadata` object for your own attributes.
    const result = bear.track(response, {
      userId: 'usr_8a2f19',        // your end user
      feature: 'ticket_summary',   // product surface
      agentId: 'triage-agent',     // which AI agent made the call
      metadata: {
        environment: 'production', // group cost by environment,
        customerTier: 'enterprise',// plan, team, workflow phase, or
        team: 'support',           // any dimension you care about
      },
    });
    
  6. 6

    Flush before exit

    Events are batched client-side. Call shutdown() before your process exits so the queue is delivered; without it, a short-lived script silently loses its events:

    TypeScript
    // Events are queued in memory and flushed in the background. A
    // short-lived script or serverless function exits before the flush
    // timer fires, and queued events are lost. Flush before exit:
    await bear.shutdown();
    
  7. 7

    Query your costsOptional

    Optional. Pull cost breakdowns in code, point an AI agent or MCP server at the same endpoints, or just read them in the dashboard. Ingestion is asynchronous, so allow a short delay after sending before the first costs appear:

    TypeScript
    // The same numbers live in your dashboard, and an AI agent or MCP
    // server can call these endpoints directly to reason over your spend.
    const summary = await bear.costs.summary();
    console.log(`Total this period: $${summary.current_period_cost}`);
    
    // Trailing 30 days, resolved client-side. Absolute dates still work:
    // bear.costs.byModel({ startDate: '2026-01-01', endDate: '2026-01-31' })
    const byModel = await bear.costs.byModel({ lastDays: 30 });
    console.log(byModel);
    

Next steps