Quickstart

Quickstart

This quickstart covers the full Grounded loop:

  • browser telemetry with @grounded/analytics
  • backend traces with @grounded/tracing
  • control-plane reads and jobs with @grounded/client

Prerequisites

  • Node.js 22+
  • a running Grounded API, for example http://localhost:3001
  • an existing tenant
  • an agent with at least one snapshot if you want direct traces to normalize into sessions
  • API keys

1. Install The Packages

The SDK is implemented in the Grounded monorepo today. Public npm publishing is prepared but may not be live yet in your environment.

Inside the monorepo:

pnpm --filter @grounded/client build
pnpm --filter @grounded/tracing build
pnpm --filter @grounded/analytics build

The intended public install shape is:

npm install @grounded/client @grounded/tracing @grounded/analytics

2. Create Keys

  • use a secret key for @grounded/client
  • use a publishable key for @grounded/tracing
  • use a publishable key for @grounded/analytics

Example secret key scopes:

  • agents:read
  • connectors:write
  • sessions:read
  • insights:read
  • snapshots:write
  • jobs:read
  • jobs:write
  • evals:read
  • evals:write

Example publishable key scopes:

  • traces:write
  • optionally traces:read

3. Initialize The SDKs

import { Grounded } from '@grounded/client';
import { GroundedTracing } from '@grounded/tracing';
import { init as initAnalytics } from '@grounded/analytics';
 
const grounded = new Grounded({
  apiKey: process.env.GROUNDED_SECRET_KEY!,
  baseUrl: process.env.GROUNDED_BASE_URL ?? 'http://localhost:3001',
});
 
const tracing = new GroundedTracing({
  apiKey: process.env.GROUNDED_PUBLISHABLE_KEY!,
  agentId: 'agt_support',
  baseUrl: process.env.GROUNDED_BASE_URL ?? 'http://localhost:3001',
  environment: 'production',
  release: 'api-2026-03-09',
});
 
const analytics = initAnalytics({
  apiKey: process.env.NEXT_PUBLIC_GROUNDED_PUBLISHABLE_KEY!,
  agentId: 'agt_support',
  baseUrl: process.env.NEXT_PUBLIC_GROUNDED_BASE_URL ?? 'http://localhost:3001',
  mirror: { fullstory: window.FS },
});

baseUrl can be either the Grounded origin or the origin plus /api.

4. Send Browser Telemetry

analytics.identify('user_123', { plan: 'pro' });
analytics.page();
analytics.track('checkout_started', { sku: 'pro-monthly' });
 
const ctx = analytics.getContext();

getContext() is the primary handoff contract between browser telemetry and backend traces.

5. Send A Backend Trace

const trace = tracing.startTrace({
  name: 'support.reply',
  sessionId: ctx.sessionId,
  anonymousId: ctx.anonymousId,
  userId: ctx.userId,
  resource: { snapshotId: 'snap_live' },
  input: { message: 'where is my refund?' },
});
 
const retrieval = trace.startSpan({
  name: 'policy.lookup',
  kind: 'retrieval',
  input: { source: 'faq' },
});
 
retrieval.recordEvent('cache_hit', { index: 'policy-cache' });
 
retrieval.end({
  status: 'ok',
  output: { articleId: 'refund-policy-v3' },
});
 
trace.score({
  name: 'resolved',
  value: true,
  dataType: 'boolean',
});
 
await trace.end({
  status: 'ok',
  output: { text: 'your refund is processing' },
});
 
await tracing.flush();
await analytics.flush();

The tracing SDK now fails fast if it cannot link a trace into Grounded's session model. Every trace must resolve:

  • an agentId
  • and at least one stitch key
    • sessionId, or
    • anonymousId, or
    • userId plus non-empty correlationKeys

6. Read The Data Back

const traces = await grounded.traces.list({
  agentId: 'agt_support',
  sessionId: ctx.sessionId,
});
 
const sessions = await grounded.sessions.list({
  agentId: 'agt_support',
  q: 'refund',
});
 
const stats = await grounded.sessions.stats('agt_support');

7. Sync A Connector

const connector = await grounded.connectors.create({
  agentId: 'agt_support',
  name: 'LangSmith prod',
  category: 'llm-tracing',
  provider: 'langsmith',
  config: {
    apiKey: process.env.LANGSMITH_API_KEY!,
    projectName: 'support-prod',
  },
});
 
await grounded.connectors.connect(connector.id);
 
const syncJob = await grounded.connectors.sync(connector.id, {
  from: '2026-03-01T00:00:00.000Z',
  to: '2026-03-06T00:00:00.000Z',
});
 
await grounded.jobs.wait(syncJob.id, {
  timeoutMs: 10 * 60_000,
});

8. Draft And Analyze A Snapshot

const draft = await grounded.snapshots.createDraft('agt_support', {
  parentSnapshotId: 'snap_live',
  systemPrompt: 'Be more explicit about refund timelines.',
});
 
await grounded.snapshots.commitDraft(
  draft.id,
  'Tighten refund messaging',
  {
    systemPrompt: 'Be more explicit about refund timelines and cite policy names.',
  },
);
 
const analysisJob = await grounded.snapshots.runAnalysis(draft.id);
await grounded.jobs.wait(analysisJob.id);

9. Run An Optimization Job

const optimizeJob = await grounded.jobs.create({
  agentId: 'agt_support',
  type: 'optimize-snapshot',
  snapshotId: draft.id,
  effort: 'medium',
  topK: 3,
});
 
await grounded.jobs.wait(optimizeJob.id, {
  timeoutMs: 20 * 60_000,
});
 
const summary = await grounded.jobs.summary(optimizeJob.id);

What To Read Next