> ## Documentation Index
> Fetch the complete documentation index at: https://whyops.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript SDK Quickstart

> Start here for @whyops/sdk: install the package, initialize the agent, make your first proxied call, and then move into runtime tracing.

`@whyops/sdk` is the main WhyOps package for Node.js, Bun, and modern server-side TypeScript apps. This page is the basic setup path: install the package, register the agent, then route OpenAI or Anthropic traffic through WhyOps.

<Callout type="info" title="Using the Vercel AI SDK?">
  Start with this page to create the base `WhyOps` client, then use the companion wrapper on the [Vercel AI SDK integration page](/integrations/vercel-ai-sdk).
</Callout>

<CardGroup cols={3}>
  <Card title="Proxy Helpers" icon="plug" href="/integrations/typescript-sdk-proxy">
    Read this next if you want the exact API-key flow and what `whyops.openai()` or `whyops.anthropic()` mutates.
  </Card>

  <Card title="Runtime Events" icon="diagram-project" href="/integrations/typescript-sdk-runtime">
    Add tool spans, cache-aware token usage, thinking events, and runtime failures.
  </Card>

  <Card title="Advanced Patterns" icon="sliders" href="/integrations/typescript-sdk-advanced">
    Hybrid tracing, self-hosted overrides, prompt caching, and common mistakes.
  </Card>

  <Card title="Vercel AI SDK" icon="sparkles" href="/integrations/vercel-ai-sdk">
    Wrap `generateText()`, `streamText()`, and embedding helpers when your app uses `ai`.
  </Card>
</CardGroup>

## Before you start

| You need                                  | Why                                                                                       |
| ----------------------------------------- | ----------------------------------------------------------------------------------------- |
| `WHYOPS_API_KEY`                          | Authenticates agent init, manual events, and proxied model traffic to WhyOps              |
| A stable `agentName`                      | Keeps proxy traffic and runtime events attached to the same agent identity                |
| `systemPrompt` and tool metadata          | Lets WhyOps version the agent and show the right configuration in the UI                  |
| Your provider key in the WhyOps dashboard | Lets WhyOps authenticate upstream when it forwards OpenAI or Anthropic traffic            |
| A stable session or trace ID              | Best for explicit continuity between proxied model calls and later tool or runtime events |

<Callout type="info" title="Recommended order">
  In TypeScript, the cleanest flow is: create the WhyOps client, call `await whyops.initAgent()` during startup, then patch OpenAI or Anthropic, and only after that add manual runtime events.
</Callout>

## 1. Install the package

<Tabs>
  <Tab title="npm">
    ```bash theme={null}
    npm install @whyops/sdk
    ```
  </Tab>

  <Tab title="pnpm">
    ```bash theme={null}
    pnpm add @whyops/sdk
    ```
  </Tab>

  <Tab title="yarn">
    ```bash theme={null}
    yarn add @whyops/sdk
    ```
  </Tab>

  <Tab title="bun">
    ```bash theme={null}
    bun add @whyops/sdk
    ```
  </Tab>
</Tabs>

## 2. Create the WhyOps client once

```ts theme={null}
import { WhyOps } from '@whyops/sdk';

export const whyops = new WhyOps({
  apiKey: process.env.WHYOPS_API_KEY!,
  agentName: 'customer-support-agent',
  agentMetadata: {
    systemPrompt: 'You are a precise customer support assistant.',
    description: 'Handles support, billing, and order status flows.',
    tools: [
      {
        name: 'search_orders',
        description: 'Look up order state by ID',
        inputSchema: JSON.stringify({
          type: 'object',
          properties: { orderId: { type: 'string' } },
          required: ['orderId'],
        }),
        outputSchema: JSON.stringify({
          type: 'object',
          properties: { status: { type: 'string' } },
        }),
      },
    ],
  },
});
```

<Callout type="warning" title="Tool schemas are strings">
  If you include `inputSchema` or `outputSchema`, pass JSON strings with `JSON.stringify(...)`. If the agent has no tools, set `tools: []` explicitly so the registered definition stays clear.
</Callout>

## 3. Initialize the agent during startup

```ts theme={null}
await whyops.initAgent();
```

You do not have to call this manually because `trace()` auto-initializes on first event, but calling it during boot is the better default because agent registration problems fail early.

## 4. Make your first proxied model call

<Tabs>
  <Tab title="OpenAI">
    ```ts theme={null}
    import OpenAI from 'openai';
    import { whyops } from './whyops';

    const traceId = 'session-123';
    const openai = whyops.openai(
      new OpenAI({ apiKey: process.env.WHYOPS_API_KEY }),
    );

    openai.defaultHeaders = {
      ...(openai as any).defaultHeaders,
      'X-Trace-ID': traceId,
      'X-Thread-ID': traceId,
    };

    const response = await openai.chat.completions.create({
      model: 'gpt-4o',
      messages: [{ role: 'user', content: 'Where is order 123?' }],
    });
    ```
  </Tab>

  <Tab title="Anthropic">
    ```ts theme={null}
    import Anthropic from '@anthropic-ai/sdk';
    import { whyops } from './whyops';

    const traceId = 'session-123';
    const anthropic = whyops.anthropic(
      new Anthropic({ apiKey: process.env.WHYOPS_API_KEY }),
    );

    anthropic.defaultHeaders = {
      ...(anthropic as any).defaultHeaders,
      'X-Trace-ID': traceId,
      'X-Thread-ID': traceId,
    };

    const message = await anthropic.messages.create({
      model: 'claude-3-5-sonnet-20241022',
      max_tokens: 800,
      messages: [{ role: 'user', content: 'Summarize this incident.' }],
    });
    ```
  </Tab>
</Tabs>

<Callout type="tip" title="Read the proxy page next">
  The helper mutates the provider client in place. Go to [TypeScript SDK Proxy Helpers](/integrations/typescript-sdk-proxy) for the exact key flow, header behavior, and OpenAI versus Anthropic details.
</Callout>

<Callout type="warning" title="Use explicit trace headers when you care about follow-up tool continuity">
  The proxy can generate a trace automatically, but the backend checks `X-Trace-ID` and `X-Thread-ID` first. If your app later emits tool or runtime events, reusing the same explicit trace ID is the cleaner and more reliable setup.
</Callout>

## 5. Add runtime traces only where you need more visibility

Start with proxy-only instrumentation first. Add `trace()` events when you need:

* tool execution latency and outputs
* retries inside your framework
* runtime failures after the model returns
* prompt caching-aware usage on manual `llmResponse()` calls
* exposed thinking blocks or orchestration milestones

## Next pages

<CardGroup cols={3}>
  <Card title="Proxy Helpers" icon="plug" href="/integrations/typescript-sdk-proxy">
    Understand which API key goes where and what the helper changes on the provider client.
  </Card>

  <Card title="Runtime Events" icon="terminal" href="/integrations/typescript-sdk-runtime">
    Add manual event coverage for tool spans, thinking blocks, embeddings, and errors.
  </Card>

  <Card title="Advanced Patterns" icon="sliders" href="/integrations/typescript-sdk-advanced">
    Finish with hybrid tracing, self-hosting, prompt caching, and event IDs.
  </Card>
</CardGroup>
