API Reference
GET /api/v1/metrics/{id}/contract
The agent-facing contract envelope. What AI agents see when they ask ClariLayer for the canonical context of a metric.
A typical CTO or CAIO evaluation pipes this response into a system prompt before the agent answers a question that references the metric. The envelope carries the business definition, the currently-approved version, the live discourse signal, and the admin-curated notes a human pinned for the agent to read.
Request
GET https://app.clarilayer.com/api/v1/metrics/{id}/contract
Authorization: Bearer <api_key>
Accept: application/json
The route requests the canonical-metric-api:read scope. Current Agent Contract keys carry that scope by default, and legacy metrics:read keys remain compatible with the current read model. The route resolves the metric inside the API key's org; cross-org access returns 404 so metric existence is cloaked.
How trust fields map to the product journey
The trust fields map back to the product lifecycle: lifecycle_status and current_approved_version come from governance and release context, last_validated_at comes from warehouse validation evidence, agent_context_notes come from the Reasoning Trail, and disambiguation hints come from registry relationships and managed variants.
Read Governance and Release, Warehouse Validation, The Reasoning Trail, and Metric Registry for the product context behind those fields.
Response (200 OK)
Default response. Every field shown is always present unless documented otherwise; counts default to 0 and arrays default to [] so consumers can read inner fields without outer null-checks.
{
"data": {
"metric_id": "5e6f7a1b-2c3d-4e5f-8a9b-0c1d2e3f4a5b",
"name": "Active Customer Count",
"business_definition": {
"included": "Customers with at least one billable subscription in the trailing 30 days.",
"excluded": "Internal test orgs (org_type='internal'), churned accounts whose cancellation date is on or before the period start.",
"time_window": "trailing 30 days, anchored on the most recent UTC midnight",
"caveats": "Free-tier customers count as active. Self-serve and sales-led accounts are aggregated together.",
"legacy_description": "Number of customers we consider active."
},
"current_approved_version": {
"id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"definition_version": "2.1.0",
"released_at": "2026-04-22T14:08:11.000Z"
},
"last_validated_at": "2026-05-09T09:14:00.000Z",
"lifecycle_status": "RELEASED",
"challenges_count": 4,
"open_challenges_count": 1,
"requires_disambiguation": null,
"canonical_url": "https://app.clarilayer.com/metrics/5e6f7a1b-2c3d-4e5f-8a9b-0c1d2e3f4a5b",
"discussion_thread_count": 3,
"discussion_message_count": 11,
"agent_context_notes": [
{
"message_id": "11111111-2222-4333-8444-555555555555",
"thread_id": "aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee",
"intent": "decision_rationale",
"author_display_name": "Jamie Chen",
"body": "Exclude org_type='internal' from the active count. Decided in the 2026-Q1 metrics review after a test workspace skewed the board chart.",
"pinned_at": "2026-04-23T16:42:00.000Z",
"created_at": "2026-04-23T16:30:00.000Z"
},
{
"message_id": "22222222-3333-4444-8555-666666666666",
"thread_id": "bbbbbbbb-cccc-4ddd-8eee-ffffffffffff",
"intent": "clarification",
"author_display_name": "Priya Patel",
"body": "Trailing 30d anchors on UTC midnight - not the org's fiscal calendar. Confirmed with Finance for the May board pack.",
"pinned_at": "2026-05-02T11:05:00.000Z",
"created_at": "2026-05-02T10:48:00.000Z"
},
{
"message_id": "33333333-4444-4555-8666-777777777777",
"thread_id": "cccccccc-dddd-4eee-8fff-aaaaaaaaaaaa",
"intent": "objection",
"author_display_name": "Marcus Rivera",
"body": "Free-tier should be reported separately for ARR conversations. Tracked as an open challenge; see open_challenges_count.",
"pinned_at": "2026-05-08T19:21:00.000Z",
"created_at": "2026-05-08T19:12:00.000Z"
}
],
"discourse_summary": {
"open_objections_count": 1,
"open_proposals_count": 0,
"last_activity_at": "2026-05-09T08:02:00.000Z"
}
},
"meta": { "apiVersion": "v1" }
}
New envelope fields (v1)
The metric-contract envelope was extended with six fields that surface the Reasoning Trail half of the corpus. Legacy v1 consumers can ignore them; agents that consume them get a richer grounding signal.
discussion_thread_count
Type: number
Total threads on this metric across every intent and resolution status. This is the "is there any conversation at all" signal. It defaults to 0.
discussion_message_count
Type: number
Total non-deleted messages across all threads on the metric. Soft-deleted rows are excluded so the count aligns with what a human sees in the Notes tab. It defaults to 0.
agent_context_notes[]
Type: AgentContextNote[]
Admin-pinned notes curated for AI context, ordered by pin time with the most recent first and capped at 10 by the route. Each entry carries message_id, thread_id, intent, author_display_name, body, pinned_at, and created_at. The field returns an empty array when no notes are pinned.
discourse_summary
Type: DiscourseSummary | null
By-intent live-dispute signal: open_objections_count, open_proposals_count, and last_activity_at. It is null when no thread on the metric carries intent='objection' or intent='proposal', regardless of resolution.
discussion_summary
Type: string | null (optional)
Plain-text LLM summary of the discussion. It is only present when the caller passes ?summary=true. It is omitted, not returned as null, on the default response.
discussion_summary_meta
Type: { cache_hit: boolean; charged: boolean } (optional)
Caching and billing metadata for the LLM summary. cache_hit is true when a previously-generated summary served the call. charged is true exactly when a new billable meter event was persisted. It is omitted on the default response.
Consumer semantics
Treat the contract as the metric's current approved context, not as a warehouse execution endpoint. The response tells a consumer which business definition, approval state, latest released version, validation timestamp, and curated discussion notes should travel with an answer. Query execution, BI rendering, and warehouse permissions remain owned by the systems that consume the contract.
The canonical_url field points to the signed-in product detail surface for users who already have workspace access. Treat it as an authenticated workspace reference, not as a public docs or crawl destination.
The lifecycle_status field is the fastest trust signal. A released or approved metric can be used in production workflows according to your workspace policy. A candidate or draft metric should be handled as advisory context unless the consuming workflow explicitly accepts pre-release definitions. Deprecated metrics remain readable so downstream systems can show migration guidance instead of silently dropping context.
Freshness is exposed through multiple fields because different consumers need different checks. Use current_approved_version.released_at to understand when the approved definition last changed, last_validated_at to understand when the latest validation evidence ran, and discourse_summary.last_activity_at to understand whether the human conversation has moved since the agent last cached context.
Error and access model
Authentication happens before any metric lookup. Missing, malformed, or revoked API keys return an auth error. Keys that do not satisfy the route's canonical-metric-api:read request, including through legacy metrics:read compatibility, are rejected before the route reads contract data. Invalid metric IDs return 400 because the route can determine the ID shape without revealing whether a metric exists.
Cross-organization access is cloaked as 404 after authentication. That means a consumer should not use the difference between "not found" and "not in this org" as a discovery channel. If a workflow expects a metric to exist but receives 404, the safest operator action is to verify the API key's workspace and the metric ID source together.
Discussion counts and agent-context notes degrade conservatively if a supporting read fails: counts fall back to 0, arrays fall back to [], and optional summaries can return null with an explanatory header. Consumers should surface those degraded states as missing context, not as proof that no human discussion exists.
Pin safety limit
The
agent_context_notes[]array is bounded upstream by the shared per-metric pin safety limit and capped on the response at 10 entries to protect agent token budget.
?summary=true (opt-in)
Append ?summary=true to request a natural-language LLM summary of the metric's discussion. When the request lands on a previously-cached input hash, ClariLayer returns the cached summary with cache_hit: true; cache misses generate a fresh summary.
Cache misses are a metered overage on billable plans: Starter, Team, Enterprise, and Design Partner. The Developer plan serves cache hits and runs the generator on cache misses but is not billed; this is intentional so a personal workspace can light up the demo without a credit card.
GET https://app.clarilayer.com/api/v1/metrics/{id}/contract?summary=true
Authorization: Bearer <api_key>
// Response (200 OK) - abbreviated, only the appended fields shown:
{
"data": {
...
"discourse_summary": {
"open_objections_count": 1,
"open_proposals_count": 0,
"last_activity_at": "2026-05-09T08:02:00.000Z"
},
"discussion_summary": "Active Customer Count is defined as customers with a billable subscription in the trailing 30 days, anchored on UTC midnight. Internal test orgs are excluded by team decision in 2026-Q1. One open objection (Marcus Rivera) argues free-tier customers should be reported separately for ARR conversations; this is tracked as an open metric challenge and has not yet been resolved.",
"discussion_summary_meta": {
"cache_hit": false,
"charged": true
}
},
"meta": { "apiVersion": "v1" }
}
The response also carries an X-Discussion-Summary-Charged header (0 or 1) so downstream meters can read the billing decision without parsing the body. Degraded responses, such as LLM timeout, daily-cap exceeded, or pricing-state unavailable, return discussion_summary: null with an explanatory X-Discussion-Summary header.
See also
- Concept: The Reasoning Trail - why this envelope exists and how humans and agents share it.
- Authentication - API-key scopes, sandbox headers, rate limits, and revocation.
- Metrics list and detail - discovery and detail reads before fetching the contract.
- AI agent context guide - prompt and tool patterns for using the envelope safely.
- Pricing - credit packs and cache-miss overage policy.