SDK Reference
Authentication

Authentication

Grounded supports API-key auth on the SDK-backed /api/* routes without replacing dashboard session auth.

That means:

  • the dashboard can keep using BetterAuth sessions
  • scripts and services can use API keys
  • browser telemetry can use publishable keys

Key Types

KindPrefixIntended PackagesNotes
secretgrd_sk_...@grounded/clienttenant-scoped or agent-scoped
publishablegrd_pk_...@grounded/tracing, @grounded/analyticsagent-scoped and narrow

Scopes

Available scopes today:

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

Route Families

Route familyRequired scopeAllowed kinds
/api/agentsagents:read or agents:writesecret
/api/connectorsconnectors:read or connectors:writesecret
/api/sessionssessions:readsecret
/api/insightsinsights:readsecret
/api/snapshotssnapshots:read or snapshots:writesecret
/api/jobsjobs:read or jobs:writesecret
/api/job-loopsjob_loops:read or job_loops:writesecret
/api/evalsevals:read or evals:writesecret
/api/tracestraces:read or traces:writepublishable, secret
/api/telemetrytraces:writepublishable, secret

Publishable keys are intentionally narrow. They are for writing and optionally reading trace-style data, not for creating agents, snapshots, jobs, or connectors.

Scope Resolution

The API checks auth in this order:

  1. valid dashboard session
  2. valid bearer API key

If a key is present:

  • its prefix identifies the key family
  • the stored secret hash must match
  • expired or revoked keys are rejected
  • key kind restrictions are enforced
  • route scope restrictions are enforced

Tenant-Scoped vs Agent-Scoped

Secret keys can be:

  • tenant-scoped
  • agent-scoped

Agent-scoped keys are safer for service integrations because they cannot operate on another agent.

Publishable keys must be agent-scoped.

Creating Keys

Key creation currently lives behind internal, session-authenticated routes:

  • GET /api/api-keys
  • POST /api/api-keys
  • POST /api/api-keys/:keyId/revoke

Secret Key Example

POST /api/api-keys
Content-Type: application/json
 
{
  "kind": "secret",
  "label": "ops worker",
  "scopes": [
    "connectors:read",
    "connectors:write",
    "sessions:read",
    "snapshots:read",
    "snapshots:write",
    "jobs:read",
    "jobs:write",
    "evals:read"
  ]
}

Publishable Key Example

POST /api/api-keys
Content-Type: application/json
 
{
  "kind": "publishable",
  "label": "support telemetry",
  "agentId": "agt_123",
  "scopes": ["traces:write"]
}

SDK Usage

@grounded/client

import { Grounded } from '@grounded/client';
 
const grounded = new Grounded({
  apiKey: process.env.GROUNDED_SECRET_KEY!,
  baseUrl: 'http://localhost:3001',
});

@grounded/tracing

import { GroundedTracing } from '@grounded/tracing';
 
const tracing = new GroundedTracing({
  publishableKey: process.env.GROUNDED_PUBLISHABLE_KEY!,
  agentId: 'agt_123',
  baseUrl: 'http://localhost:3001',
});

@grounded/analytics

import { init } from '@grounded/analytics';
 
const analytics = init({
  publishableKey: process.env.NEXT_PUBLIC_GROUNDED_PUBLISHABLE_KEY!,
  agentId: 'agt_123',
  baseUrl: 'http://localhost:3001',
});

Recommendations

  • use agent-scoped keys for individual services whenever possible
  • keep publishable keys trace-only
  • use one publishable key for both tracing and analytics when they target the same agent
  • rotate keys instead of sharing one broad tenant secret everywhere