Instrument custom analytics

Declare bounded typed events in an Agent or Channel and emit metrics without granting tenant code analytics storage access.

Before you begin

Define the operational question first. Dimensions describe bounded categories used to filter or group; metrics are numeric values to aggregate. Do not put secrets, prompts, raw user content, unbounded identifiers, session ids, or request ids into custom dimensions.

Steps

  1. Declare the event with a stable namespaced id and version:
ts
import { agent, analyticsEvent } from "@constal/sdk";

const ticketResolved = analyticsEvent({
  id: "support.ticket-resolved",
  version: "1",
  dimensions: ["queue", "resolution"],
  metrics: ["duration_ms", "messages"],
} as const);
  1. Register it in the executable definition with analytics: [ticketResolved].
  2. Emit it from Agent code with ctx.analytics.emit() or Channel code with context.analytics.emit():
ts
ctx.analytics.emit(ticketResolved, {
  dimensions: { queue: "billing", resolution: "answered" },
  metrics: { duration_ms: 842, messages: 3 },
});
  1. Increment the event version when its meaning changes. Keep old and new definitions distinguishable during migration.
  2. Deploy the package. The runtime records emission intent with the durable invocation; tenant executables receive no direct archive, projection, or query authority.

Verify

Run one controlled input and query with filters.custom_event_id set to the declaration id. Confirm the returned custom_event_version, dimensions, and metrics. Repeat a durable invocation or replay scenario and verify event identity remains suitable for downstream deduplication.

Next steps

Use Query and export analytics to retrieve the event. Review SDK Policies and analytics for the runtime API and event validation limits.