Skip to content

init()

The TypeScript SDK has one initialization function, init(), and it is async. There used to be a synchronous init() and an asynchronous createClient(); they were merged, because framework wiring (for example registering the Vercel AI SDK’s telemetry integration) has to import the user’s framework package, which cannot be done synchronously — so a synchronous init() silently produced no spans for those frameworks. Await the one call and the choice disappears.

function init(options: SideSeatOptions): Promise<SideSeat>;

Asynchronous initialization. Resolves to a SideSeat instance.

interface SideSeatOptions {
framework: Framework | string; // required
disabled?: boolean;
endpoint?: string;
apiKey?: string;
projectId?: string;
serviceName?: string;
serviceVersion?: string;
enableTraces?: boolean;
logLevel?: LogLevel;
debug?: boolean;
}

framework is required. Omitting it throws a SideSeatError at runtime. Use a Frameworks.* constant.

See Configuration for details on each option.

Promise<SideSeat> — resolves to the initialized client instance.

When awaited, init():

  1. Creates a tracer provider with resource attributes and registers it globally
  2. Configures a BatchSpanProcessor with an OTLP HTTP exporter
  3. Registers the framework’s telemetry integration where one is needed (this is the step that must be async)

The function is idempotent, and concurrent calls share one initialization rather than racing:

const a = await init({ framework: Frameworks.VercelAI }); // Initializes OpenTelemetry
const b = await init({ framework: Frameworks.VercelAI }); // Returns same instance, logs warning
console.log(a === b); // true
import { init, Frameworks } from '@sideseat/sdk';
// Minimal
await init({ framework: Frameworks.VercelAI });
// With options
const client = await init({
framework: Frameworks.Strands,
endpoint: 'http://sideseat.example.com:5388',
projectId: 'my-project',
serviceName: 'my-ai-agent',
debug: true
});
// Environment-based
await init({ framework: Frameworks.VercelAI, debug: process.env.NODE_ENV !== 'production' });
function getClient(): SideSeat;

Get the global SideSeat instance. Throws SideSeatError if not initialized.

import { init, getClient, Frameworks } from '@sideseat/sdk';
await init({ framework: Frameworks.VercelAI });
// Later, in another module
const client = getClient();
function shutdown(): Promise<boolean>;

Shutdown the global instance, flushing pending spans and releasing resources. Resolves to whether shutdown completed cleanly. false means something in flush-or-teardown failed and is worth acting on before exit — usually an exporter that could not deliver, though provider cleanup failing after a clean flush also reports false. Check the diag log for which.

It does not throw — this also runs from process signal handlers, where an unhandled rejection would replace your exit code with a crash. Note also that true means everything still queued was exported; a burst that overran the batch processor’s queue is discarded by the OpenTelemetry SDK at the time, and no return value can report that after the fact.

import { shutdown } from '@sideseat/sdk';
if (!(await shutdown())) {
console.warn('some spans were not exported');
}
function isInitialized(): boolean;

Check whether SideSeat has been initialized.

After initialization, code using @opentelemetry/api picks up SideSeat’s provider — provided no other library registered the global TracerProvider first. If one did, the OTel API refuses a second registration: SideSeat keeps its own provider (so client.span, client.spanSync and client.getTracer still export), but tracers obtained from the global API keep going to whoever registered first, and a warning is logged. Initialize SideSeat before that library if you need those spans.

import { init, Frameworks } from '@sideseat/sdk';
import { trace } from '@opentelemetry/api';
await init({ framework: Frameworks.VercelAI });
// This tracer uses the SideSeat-configured provider
const tracer = trace.getTracer('my-module');

init() registers the Vercel AI SDK’s current OpenTelemetry integration automatically — that is the async step above, so awaiting init() before the first generateText is what makes telemetry appear.

import { init, Frameworks } from '@sideseat/sdk';
import { generateText } from 'ai';
import { bedrock } from '@ai-sdk/amazon-bedrock';
await init({ framework: Frameworks.VercelAI });
const { text } = await generateText({
model: bedrock('us.anthropic.claude-sonnet-4-5-20250929-v1:0'),
prompt: 'Hello!',
experimental_telemetry: { isEnabled: true },
});
import { init, Frameworks } from '@sideseat/sdk';
import { Agent } from '@strands-agents/sdk';
await init({ framework: Frameworks.Strands });
const agent = new Agent({ model: 'global.anthropic.claude-haiku-4-5-20251001-v1:0' });
const result = await agent.invoke('Hello!');
console.log(result.toString());
import { init, Frameworks } from '@sideseat/sdk';
import express from 'express';
// Initialize before creating the app
await init({ framework: Frameworks.VercelAI });
const app = express();
app.get('/chat', async (req, res) => {
const response = await callAIModel(req.query.message);
res.json({ response });
});
app.listen(3000);

The SDK automatically handles shutdown via Node.js process events. For explicit control:

import { shutdown } from '@sideseat/sdk';
// Or `forceFlush()` to drain without tearing the SDK down.
if (!(await shutdown())) {
console.warn('some spans were not exported');
}