Skip to main content
Metadata lets you attach custom key-value pairs to your AgentMark traces. Use metadata to add context like user IDs, environment names, feature flags, request IDs, and customer tiers — then filter and search by those values in the dashboard.
Developers configure metadata in your application. See Development documentation for setup instructions.

Setting metadata

There are two ways to attach metadata to traces in the AgentMark SDK: via the telemetry.metadata object when formatting a prompt, and via the trace() function’s metadata option when grouping traces.

Via telemetry metadata

Pass metadata when formatting a prompt. These key-value pairs are attached to the resulting span:
import { AgentMarkSDK } from "@agentmark-ai/sdk";
import { createAgentMarkClient, VercelAIModelRegistry } from "@agentmark-ai/ai-sdk-v5-adapter";
import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";

const sdk = new AgentMarkSDK({
  apiKey: process.env.AGENTMARK_API_KEY,
  appId: process.env.AGENTMARK_APP_ID,
});

sdk.initTracing();

const modelRegistry = new VercelAIModelRegistry()
  .registerModels(["gpt-4o-mini"], (name) => openai(name));

const client = createAgentMarkClient({
  loader: sdk.getApiLoader(),
  modelRegistry,
});

const prompt = await client.loadTextPrompt("greeting.prompt.mdx");
const input = await prompt.format({
  props: { query: "Hello" },
  telemetry: {
    isEnabled: true,
    functionId: "my-function",
    metadata: {
      userId: "user-123",
      environment: "production",
      feature: "chat-v2",
      customerTier: "enterprise",
    },
  },
});

const result = await generateText(input);

Via the trace function

Pass metadata when creating a trace group. All spans within the trace inherit this metadata:
import { trace } from "@agentmark-ai/sdk";

const { result, traceId } = await trace(
  {
    name: "my-workflow",
    metadata: {
      requestId: "req-abc-123",
      version: "2.1.0",
      environment: "production",
    },
  },
  async (ctx) => {
    const prompt = await client.loadTextPrompt("handler.prompt.mdx");
    const input = await prompt.format({
      props: { query: "What is AgentMark?" },
      telemetry: { isEnabled: true },
    });

    return await generateText(input);
  }
);
You can combine both approaches. Metadata from trace() applies to the parent trace, while telemetry.metadata applies to individual spans within that trace.

Filtering by metadata

In the AgentMark dashboard, metadata keys are auto-discovered from your trace data. You can filter traces by any metadata key that appears in your data. To filter by metadata:
  1. Navigate to the Traces tab in the dashboard.
  2. Open the filter dropdown.
  3. Look for entries prefixed with Metadata: followed by the key name (for example, “Metadata: userId”).
  4. Select the key you want to filter by.
  5. Choose an operator and enter a value.
AgentMark supports the following filter operators for metadata values:
  • equals — exact match on the value
  • contains — value includes the specified substring
  • starts with — value begins with the specified string
  • ends with — value ends with the specified string
  • exists — the key is present, regardless of value
  • does not exist — the key is not present on the trace
You can apply up to 10 filters simultaneously to narrow down your traces.

Metadata in the trace detail

When viewing an individual trace in the dashboard, metadata appears in the attributes section. All key-value pairs you attached are displayed, making it easy to see the full context of a trace without switching to your application logs.

How metadata is stored

AgentMark stores metadata as a Map(LowCardinality(String), String) column in ClickHouse. Keys are indexed for fast filtering and search. All values are stored as strings — if you need to attach non-string values, convert them first:
metadata: {
  userId: "user-123",
  resultCount: String(results.length),   // number → string
  isRetry: String(isRetry),              // boolean → string
}

Best practices

  • userId — Per-user debugging and cost attribution. Example: "user-123"
  • sessionId — Group related traces. Also available as a top-level trace() option. Example: "sess-abc"
  • environment — Distinguish staging from production when using a single app. Example: "production"
  • version — Track which application version generated the trace. Example: "2.1.0"
  • requestId — Correlate AgentMark traces with your application logs. Example: "req-xyz"
  • feature — Identify which feature or flow triggered the trace. Example: "chat-v2"

Tips

  • Use consistent key names across your application. If one service sends userId and another sends user_id, they appear as separate keys in the dashboard.
  • Keep values short (under 250 characters). Metadata is designed for identifiers and labels, not large payloads.
  • Use metadata for anything you want to filter by later. If you find yourself searching your application logs for a value, it is a good candidate for metadata.
  • Metadata keys are case-sensitive. userId and userid are treated as different keys.

Limits

AgentMark enforces the following limits on metadata:
  • Key names: Up to 64 characters, alphanumeric characters and underscores only
  • Values: String values up to 500 characters
  • Filters: Up to 10 metadata filters can be applied simultaneously in the dashboard

Next steps

Traces and logs

Understand trace details and span attributes

Sessions

Group related traces together

Filtering and search

Filter traces by metadata keys

Development setup

Set up tracing in your application

Have Questions?

We’re here to help! Choose the best way to reach us: