> ## Documentation Index
> Fetch the complete documentation index at: https://docs.timbal.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Metric Definition

> Define a metric of your own, emitted as runs land. Once it exists it behaves like any platform metric: readable through `GET /orgs/{org_id}/metrics`, listed in the catalog with `origin: custom`, and alarmable with no extra setup.

The definition is a span predicate over each completed run's trace. Span paths are `{workforce}.{step}` and matching is on the **leaf**: use `llm` or `get_address`, not the full path. Predicate fields AND together and all are optional — omitting every one matches every non-root span.

`metric_name` is forced under the reserved `trace.` prefix so a definition cannot shadow a platform series. Set `label_source` to `span_name` to break the metric out per step, then point an alarm at a single step with `dims.label`.

Definitions are **not retroactive**: matching happens as runs arrive, so a new definition only sees traces written after it. Dry-run it against stored traces first with `POST /orgs/{org_id}/metrics/definitions/preview`. Note also that only sum/count/avg/min/max are available on the result — percentiles are not derivable from metric bins.

Set `project_id` to scope the definition to one project, which also makes it editable by holders of `projects.alarms.manage` there. Leaving it out defines an org-wide metric that runs against every project's traces, and needs `alarms.manage`.



## OpenAPI

````yaml POST /orgs/{org_id}/metrics/definitions
openapi: 3.1.0
info:
  title: Timbal Platform API
  description: Public API documentation for the Timbal platform
  license:
    name: ''
  version: 2.0.0
servers:
  - url: https://api.timbal.ai
    description: Production
  - url: https://api.dev.timbal.ai
    description: Development
security: []
tags:
  - name: ace
    description: Action Control Engine (ACE) operations
  - name: alarms
    description: Metric series and threshold alarms
  - name: analytics
    description: Org and project analytics
  - name: billing
    description: Subscriptions, usage, and payment-related operations
  - name: channels
    description: Delivery channels alarms notify through
  - name: content
    description: Re-sign stored content URLs
  - name: files
    description: File operations
  - name: iam
    description: IAM — actions, roles, users, and authorization introspection
  - name: k2
    description: Knowledge Bases v2 operations
  - name: orgs
    description: Organization operations
  - name: projects
    description: Project operations
  - name: runs
    description: Execution operations
  - name: templates
    description: Public project template catalog
  - name: users
    description: Authenticated user profile
paths:
  /orgs/{org_id}/metrics/definitions:
    post:
      tags:
        - alarms
      summary: Define a custom metric
      description: >-
        Define a metric of your own, emitted as runs land. Once it exists it
        behaves like any platform metric: readable through `GET
        /orgs/{org_id}/metrics`, listed in the catalog with `origin: custom`,
        and alarmable with no extra setup.


        The definition is a span predicate over each completed run's trace. Span
        paths are `{workforce}.{step}` and matching is on the **leaf**: use
        `llm` or `get_address`, not the full path. Predicate fields AND together
        and all are optional — omitting every one matches every non-root span.


        `metric_name` is forced under the reserved `trace.` prefix so a
        definition cannot shadow a platform series. Set `label_source` to
        `span_name` to break the metric out per step, then point an alarm at a
        single step with `dims.label`.


        Definitions are **not retroactive**: matching happens as runs arrive, so
        a new definition only sees traces written after it. Dry-run it against
        stored traces first with `POST
        /orgs/{org_id}/metrics/definitions/preview`. Note also that only
        sum/count/avg/min/max are available on the result — percentiles are not
        derivable from metric bins.


        Set `project_id` to scope the definition to one project, which also
        makes it editable by holders of `projects.alarms.manage` there. Leaving
        it out defines an org-wide metric that runs against every project's
        traces, and needs `alarms.manage`.
      operationId: create_org_metric_definition
      parameters:
        - name: org_id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateMetricDefinitionReq'
            examples:
              Failing tool calls, per tool:
                value:
                  name: Tool errors
                  metric_name: tool_errors
                  has_error: true
                  value_source: count
                  label_source: span_name
              Output token burn on LLM spans:
                value:
                  name: Output tokens
                  metric_name: output_tokens
                  span_name: llm
                  value_source: usage:output_text_tokens
              Slow retrieval steps:
                value:
                  name: Slow lookups
                  metric_name: slow_lookup_ms
                  span_name_prefix: get_
                  min_duration_ms: 2000
                  value_source: duration_ms
                  label_source: span_name
        required: true
      responses:
        '201':
          description: Definition created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MetricDefinitionOut'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
      security:
        - bearer_auth: []
components:
  schemas:
    CreateMetricDefinitionReq:
      type: object
      description: >-
        Body for **POST** `/orgs/{org_id}/metrics/definitions`.


        Every predicate field is optional and they AND together. All omitted
        means

        "every non-root span", which paired with `label_source: span_name` gives
        a

        per-step call count — a reasonable first definition.
      required:
        - name
        - metric_name
      properties:
        has_error:
          type:
            - boolean
            - 'null'
          description: >-
            `true` = only errored spans, `false` = only clean ones, omitted =
            both.
        label_source:
          type: string
          description: '`none` (default) or `span_name` to break the metric out per step.'
        metric_name:
          type: string
          description: Destination metric. `trace.` is prepended when missing.
        min_duration_ms:
          type:
            - integer
            - 'null'
          format: int32
          description: Only spans at least this slow. Spans still running never match.
        name:
          type: string
          description: Human label for the definition itself, unique within the org.
        project_id:
          type:
            - string
            - 'null'
          description: Scope to one project. Omit to apply across the org.
        source:
          $ref: '#/components/schemas/MetricDefinitionSource'
          description: Defaults to `trace_span`, the only source today.
        span_name:
          type:
            - string
            - 'null'
          description: |-
            Exact span name — the leaf of the span path (`llm`, `get_address`),
            not the full `{workforce}.{step}`.
        span_name_prefix:
          type:
            - string
            - 'null'
          description: Span-name prefix, for matching a family of tools (`get_`).
        status_code:
          type:
            - string
            - 'null'
        value_source:
          type: string
          description: '`count` (default), `duration_ms`, or `usage:<key>`.'
    MetricDefinitionOut:
      type: object
      required:
        - id
        - name
        - metric_name
        - source
        - value_source
        - label_source
        - enabled
        - created_at
      properties:
        created_at:
          type: string
          format: date-time
        enabled:
          type: boolean
        has_error:
          type:
            - boolean
            - 'null'
        id:
          type: integer
          format: int64
        label_source:
          type: string
          description: '`none` or `span_name`.'
        metric_name:
          type: string
        min_duration_ms:
          type:
            - integer
            - 'null'
          format: int32
        name:
          type: string
        project_id:
          type:
            - integer
            - 'null'
          format: int64
          description: Project scope; omitted when the filter applies to the whole org.
        source:
          $ref: '#/components/schemas/MetricDefinitionSource'
          description: Always `trace_span` today; see [`MetricDefinitionSource`].
        span_name:
          type:
            - string
            - 'null'
        span_name_prefix:
          type:
            - string
            - 'null'
        status_code:
          type:
            - string
            - 'null'
        value_source:
          type: string
          description: '`count`, `duration_ms`, or `usage:<key>`.'
    ErrorMessage:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Machine-readable error code (e.g. `ALREADY_EXISTS`, `BAD_REQUEST`).
        message:
          type: string
          description: Human-readable description.
    MetricDefinitionSource:
      type: string
      description: >-
        Where a definition draws its observations from.


        One variant today. It is in the payload from the start so that adding a

        second source is an additive change to this enum instead of a new
        resource

        alongside `/metrics/definitions` — the reason the endpoint is named for

        metrics rather than for traces.
      enum:
        - trace_span
  securitySchemes:
    bearer_auth:
      type: http
      scheme: bearer
      description: >-
        Timbal API key. Obtain your API key from the Timbal platform settings.
        See [Authentication](/api-reference/authentication) for more
        information.

````