SDK Reference
Client Reference

Client Reference

@grounded/client exposes one top-level class:

import { Grounded } from '@grounded/client';

Constructor

const grounded = new Grounded({
  apiKey,
  baseUrl,
  timeoutMs,
  maxRetries,
  fetch,
});

Shared Return Shapes

List methods return:

type ListResponse<T> = {
  data: T[];
  page?: number;
  pageSize?: number;
  total?: number;
  totalPages?: number;
  hasMore?: boolean;
};

This is important because the underlying /api routes are not fully consistent yet. The SDK normalizes them.

Error Type

Most API failures throw GroundedApiError:

class GroundedApiError extends Error {
  status: number;
  requestId?: string;
  code?: string;
  details?: unknown;
  body?: unknown;
}

Agents

MethodDescription
agents.list({ tenantId? })list agents
agents.get(agentId)fetch one agent
agents.create({ name, tenantId? })create a new agent

Connectors

MethodDescription
connectors.list({ agentId? })list connectors
connectors.get(connectorId)fetch one connector
connectors.create(input)create a connector
connectors.update(connectorId, input)patch connector metadata or config
connectors.delete(connectorId)delete a connector
connectors.connect(connectorId, { config? })mark connected and trigger sync
connectors.disconnect(connectorId)mark disconnected
connectors.sync(connectorId)enqueue a sync job directly

Connector creation uses the current backend shape:

await grounded.connectors.create({
  agentId: 'agt_123',
  name: 'LangSmith prod',
  category: 'llm-tracing',
  config: {
    apiKey: process.env.LANGSMITH_API_KEY!,
    projectName: 'support-prod',
  },
});

Current connector categories are:

  • 'llm-tracing'
  • 'session-data'

Sessions

MethodDescription
sessions.list(params?)list sessions with route-level filters
sessions.get(sessionId)fetch one session
sessions.stats(agentId)fetch aggregate session stats

Because the SDK passes session filters through, you can use the backend query shape directly:

await grounded.sessions.list({
  agentId: 'agt_123',
  outcome: 'resolved',
  page: 1,
  pageSize: 20,
  q: 'refund',
});

Insights

MethodDescription
insights.list({ agentId?, ids? })list insights
insights.get(insightId)fetch one insight

Snapshots

MethodDescription
snapshots.list(params?)list snapshots
snapshots.get(snapshotId)fetch one snapshot
snapshots.create(input)create a snapshot
snapshots.fork(snapshotId)create a candidate copy
snapshots.updateDraft(snapshotId, input)patch draft content
snapshots.runAnalysis(snapshotId)enqueue analyze-only optimization
snapshots.activate(snapshotId)mark active
snapshots.reject(snapshotId)mark rejected
snapshots.delete(snapshotId)delete snapshot
snapshots.getSourceJob(snapshotId)resolve producing job
snapshots.getAttribution(snapshotId)fetch attribution summary

Jobs

MethodDescription
jobs.list(params?)list jobs
jobs.get(jobId)fetch one job
jobs.create(input)create a job
jobs.cancel(jobId)cancel a job
jobs.steps(jobId)fetch ordered execution steps
jobs.summary(jobId)fetch summarized output
jobs.wait(jobId, options?)poll until terminal state

jobs.wait():

  • returns the job if it reaches completed
  • throws GroundedApiError if the job reaches failed or cancelled
  • throws GroundedApiError on timeout if timeoutMs is exceeded

Job Loops

MethodDescription
jobLoops.list({ agentId?, status? })list loops
jobLoops.get(loopId)fetch loop detail
jobLoops.create(input)create and start a loop
jobLoops.pause(loopId)pause a running loop
jobLoops.resume(loopId, action?)resume with retry or skip
jobLoops.cancel(loopId)cancel a loop

Evals

MethodDescription
evals.list({ agentId? })list eval definitions
evals.create(input)create an eval definition
evals.run(evalId, snapshotId)run an eval against a snapshot
evals.listRuns(params?)list historical eval runs

Datasets

MethodDescription
datasets.list({ agentId? })list datasets
datasets.get(datasetId)fetch one dataset
datasets.create(input)create a dataset and rows
datasets.listRows(datasetId)list rows in a dataset

Example: Full Control-Plane Flow

const grounded = new Grounded({
  apiKey: process.env.GROUNDED_SECRET_KEY!,
  baseUrl: 'http://localhost:3001',
});
 
const fork = await grounded.snapshots.fork('snap_base_123');
 
await grounded.snapshots.updateDraft(fork.id, {
  systemPrompt: 'Tighten refund policy handling',
  commitMessage: 'Refine refund policy',
});
 
const analysisJob = await grounded.snapshots.runAnalysis(fork.id);
await grounded.jobs.wait(analysisJob.id);
 
const optimizeJob = await grounded.jobs.create({
  agentId: fork.agentId,
  type: 'optimize-snapshot',
  snapshotId: fork.id,
  data: {
    effort: 'medium',
    topK: 3,
  },
});
 
await grounded.jobs.wait(optimizeJob.id, {
  timeoutMs: 20 * 60_000,
});