Grounded SDK
Grounded now has a clean product model and the SDK follows it closely.
- write primitives
- traces and span data from
@grounded/tracing - browser telemetry from
@grounded/analytics
- traces and span data from
- derived read primitive
- sessions from
@grounded/client.sessions.*
- sessions from
- control-plane primitives
- snapshots from
@grounded/client.snapshots.* - jobs from
@grounded/client.jobs.*
- snapshots from
The SDK stays on top of the existing Grounded /api. There is no separate public namespace right now.
Three Packages, One Model
| Package | Runtime | Purpose | Key Type |
|---|---|---|---|
@grounded/client | server | agents, connectors, traces, sessions, snapshots, jobs, evals, datasets | grd_sk_... |
@grounded/tracing | server | direct llm traces, spans, scores, trace events, openai wrapping, otel mirroring | grd_pk_... |
@grounded/analytics | browser | identify, page, track, stable session context, optional fullstory mirroring | grd_pk_... |
What Grounded Actually Does
Grounded combines three ingestion modes:
- import
- sync from providers like LangSmith and FullStory through connectors
- direct
- write traces and telemetry from your own app with the SDKs
- mirror
- keep an existing provider and send a normalized copy into Grounded at the same time
That data becomes:
- trace records for raw debugging
- derived sessions for product understanding
- insights mined from sessions
- snapshots you can fork and improve
- jobs that run sync, analysis, optimization, and eval work
Typical Loop
- Create or choose an
agent. - Create a
snapshotfor that agent. - Ingest data through connectors, tracing, analytics, or both.
- Let Grounded derive
sessions. - Read
insightsand rawtraces. - Fork or draft a new
snapshot. - Run
jobsto analyze, optimize, or evaluate it. - Activate the winning snapshot.
First Combined Example
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 analytics = initAnalytics({
apiKey: process.env.NEXT_PUBLIC_GROUNDED_PUBLISHABLE_KEY!,
agentId: 'agt_support',
baseUrl: process.env.NEXT_PUBLIC_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: 'web-2026-03-09',
});
analytics.page();
analytics.track('checkout_started', { sku: 'pro-monthly' });
const ctx = analytics.getContext();
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 llm = trace.startSpan({
name: 'openai.responses.create',
kind: 'llm',
input: { model: 'gpt-5-mini' },
});
llm.end({
status: 'ok',
output: { text: 'Your refund is processing.' },
});
trace.score({
name: 'resolved',
value: true,
dataType: 'boolean',
});
await trace.end({ status: 'ok' });
await tracing.flush();
const sessionList = await grounded.sessions.list({
agentId: 'agt_support',
q: 'refund',
});