Telemetry API Reference

Reference the OTLP write and MLflow-native read telemetry endpoints by using standalone OpenAPI specifications.

This page provides the OpenAPI specifications for the following telemetry API planes:

  • Telemetry Write API (OTLP): Endpoints for sending OTLP/HTTP traces, metrics, and logs. Served behind the /ai-platform/v1 route prefix.
  • Telemetry Read API (MLflow-native): Endpoints that an MLflow client calls on your behalf to search and retrieve traces and to manage the SQL warehouse behind them. Served behind the /ai-platform route prefix.

Telemetry sinks are provisioned by TetraScience when telemetry is enabled for your organization, so this page doesn't document a provisioning endpoint. To request a sink, or a change to one, contact your customer account leader.

For a task-oriented walkthrough of configuring an exporter and an MLflow client, see AI Observability and Telemetry in the TetraScience AI Services User Guide (v1.3.x).

📘

NOTE

The Telemetry Read API uses the /ai-platform base URL without /v1, and an MLflow client reaches it through the Databricks REST surface. Set MLFLOW_TRACKING_URI to databricks, set DATABRICKS_HOST to the org-scoped base URL https://<your-gateway>/ai-platform/org/<your-org-slug>, and set DATABRICKS_TOKEN to your Tetra token.

DATABRICKS_HOST names the TetraScience gateway, not a Databricks workspace. MLflow reads that variable name because the databricks tracking URI selects its Databricks REST client. Setting MLFLOW_TRACKING_URI to an https:// URL selects the open source implementation instead, which calls endpoints that the gateway doesn't serve. Use the bare https://<your-gateway>/ai-platform base only if your client can send an x-org-slug header.

Telemetry Write API (OTLP)

openapi: 3.0.3
info:
  title: TetraScience Telemetry Write API (OTLP)
  version: 1.0.0
  description: |-
    Send OTLP/HTTP traces, metrics, and logs to an active telemetry sink.

    ## Authentication

    All endpoints require a Tetra token, sent either as a `ts-auth-token` header or as `Authorization: Bearer <token>`, and the `x-org-slug` header. Supply the `x-ts-sink-id` header or its deprecated `x-mlflow-experiment-id` alias to select an active sink.

    ## Base URL

    All endpoints are served behind `/ai-platform/v1`.
servers:
- url: https://gateway.tetrascience.com/ai-platform/v1
  description: TetraScience AWS API Gateway (US MT)
tags:
- name: Telemetry
paths:
  "/telemetry/v1/traces":
    post:
      summary: OTLP/HTTP trace ingest
      description: |
        Standard OTLP/HTTP. Body is `ExportTraceServiceRequest` as **protobuf only** -
        OTLP/JSON is NOT accepted, so exporters must be configured `http/protobuf`.
        `Content-Encoding: gzip` or `identity` is accepted; any other encoding is
        refused. Bodies are capped at 4 MiB. The body
        is forwarded to the upstream collector byte-identically, it is never parsed,
        re-encoded, or inspected. `x-ts-sink-id` selects an ACTIVE sink and is REQUIRED;
        `x-mlflow-experiment-id` is an identical alias. Equal aliases are accepted;
        disagreeing aliases return 400 before dependency calls. A request carrying neither
        returns 400: there is no per-org default, and guessing one would route an app's
        traces into another app's table.
        Emitted by an OTLP exporter, not written by hand.
      tags:
      - Telemetry
      security:
      - bearerAuth: []
      parameters:
      - "$ref": "#/components/parameters/OrgSlugRequired"
      - "$ref": "#/components/parameters/TelemetrySinkSelector"
      - "$ref": "#/components/parameters/TelemetrySinkSelectorAlias"
      requestBody:
        required: true
        content:
          application/x-protobuf:
            schema:
              type: string
              format: binary
      responses:
        '200':
          description: Accepted by the upstream telemetry store.
        '400':
          description: The sink selector is missing or conflicts with its alias; fix the headers before retrying because the request is not retryable as sent.
        '401':
          description: The bearer token is missing or unverifiable; obtain a valid token before retrying.
        '403':
          description: The token is not scoped to write telemetry for this org or telemetry is not enabled; obtain the required access before retrying.
        '404':
          "$ref": "#/components/responses/TelemetryOpaqueNotFound"
        '413':
          description: The body exceeded the 4 MiB cap; reduce the export batch before retrying because the request is not retryable as sent.
        '415':
          description: |
            `Content-Type` was not `application/x-protobuf`, or `Content-Encoding` was
            something other than `gzip`/`identity`. Fix the content type or encoding before
            retrying because the request is not retryable as sent.
        '502':
          description: The telemetry sink registry or the upstream collector could not be reached; back off and retry.
        default:
          description: |
            Any other status is RELAYED from the upstream OTLP collector
            unmodified, body and content-type included, rather than being re-shaped into
            a gateway error envelope. Treat unlisted statuses as upstream's own and follow
            the relayed status, body, and retry guidance before trying again.
  "/telemetry/v1/metrics":
    post:
      summary: OTLP/HTTP metric ingest
      tags:
      - Telemetry
      security:
      - bearerAuth: []
      parameters:
      - "$ref": "#/components/parameters/OrgSlugRequired"
      - "$ref": "#/components/parameters/TelemetrySinkSelector"
      - "$ref": "#/components/parameters/TelemetrySinkSelectorAlias"
      requestBody:
        required: true
        content:
          application/x-protobuf:
            schema:
              type: string
              format: binary
      responses:
        '200':
          description: Accepted by the upstream telemetry store.
        '400':
          description: The sink selector is missing or conflicts with its alias; fix the headers before retrying because the request is not retryable as sent.
        '401':
          description: The bearer token is missing or unverifiable; obtain a valid token before retrying.
        '403':
          description: The token is not scoped to write telemetry for this org or telemetry is not enabled; obtain the required access before retrying.
        '404':
          "$ref": "#/components/responses/TelemetryOpaqueNotFound"
        '413':
          description: The body exceeded the 4 MiB cap; reduce the export batch before retrying because the request is not retryable as sent.
        '415':
          description: |
            `Content-Type` was not `application/x-protobuf`, or `Content-Encoding` was
            something other than `gzip`/`identity`. Fix the content type or encoding before
            retrying because the request is not retryable as sent.
        '502':
          description: The telemetry sink registry or the upstream collector could not be reached; back off and retry.
        default:
          description: |
            Any other status is RELAYED from the upstream OTLP collector
            unmodified, body and content-type included, rather than being re-shaped into
            a gateway error envelope. Treat unlisted statuses as upstream's own and follow
            the relayed status, body, and retry guidance before trying again.
  "/telemetry/v1/logs":
    post:
      summary: OTLP/HTTP log ingest
      tags:
      - Telemetry
      security:
      - bearerAuth: []
      parameters:
      - "$ref": "#/components/parameters/OrgSlugRequired"
      - "$ref": "#/components/parameters/TelemetrySinkSelector"
      - "$ref": "#/components/parameters/TelemetrySinkSelectorAlias"
      requestBody:
        required: true
        content:
          application/x-protobuf:
            schema:
              type: string
              format: binary
      responses:
        '200':
          description: Accepted by the upstream telemetry store.
        '400':
          description: The sink selector is missing or conflicts with its alias; fix the headers before retrying because the request is not retryable as sent.
        '401':
          description: The bearer token is missing or unverifiable; obtain a valid token before retrying.
        '403':
          description: The token is not scoped to write telemetry for this org or telemetry is not enabled; obtain the required access before retrying.
        '404':
          "$ref": "#/components/responses/TelemetryOpaqueNotFound"
        '413':
          description: The body exceeded the 4 MiB cap; reduce the export batch before retrying because the request is not retryable as sent.
        '415':
          description: |
            `Content-Type` was not `application/x-protobuf`, or `Content-Encoding` was
            something other than `gzip`/`identity`. Fix the content type or encoding before
            retrying because the request is not retryable as sent.
        '502':
          description: The telemetry sink registry or the upstream collector could not be reached; back off and retry.
        default:
          description: |
            Any other status is RELAYED from the upstream OTLP collector
            unmodified, body and content-type included, rather than being re-shaped into
            a gateway error envelope. Treat unlisted statuses as upstream's own and follow
            the relayed status, body, and retry guidance before trying again.
components:
  parameters:
    OrgSlugRequired:
      name: x-org-slug
      in: header
      required: true
      schema:
        type: string
        minLength: 1
        maxLength: 128
      description: |
        The org to act on. REQUIRED on the write plane. It is a
        selector, not an authenticator, the tenant and the caller's authorized orgs
        both come from the verified token, and an org the token is not scoped for is
        refused.
    TelemetrySinkSelector:
      name: x-ts-sink-id
      in: header
      required: true
      schema:
        type: string
        minLength: 1
        maxLength: 256
      description: |
        Canonical OTLP write sink selector. Resolves only an ACTIVE sink belonging to your
        verified organization. Empty, comma-joined, duplicated, control-character, and
        over-length values are refused. Required unless supplied through the
        x-mlflow-experiment-id alias; omitting both is a 400.
    TelemetrySinkSelectorAlias:
      name: x-mlflow-experiment-id
      in: header
      required: false
      deprecated: true
      schema:
        type: string
        minLength: 1
        maxLength: 256
      description: |
        Alias of x-ts-sink-id with identical semantics. If both headers are present,
        their values must be exactly equal or the request returns 400 before any
        downstream call.
  responses:
    TelemetryOpaqueNotFound:
      description: |
        The uniform telemetry 404. Absence, an unauthorized org, a malformed target, a
        registry record that failed validation, and an upstream response the gateway
        refuses to relay are all indistinguishable here by design, so the response does
        not distinguish absent from forbidden and the endpoint cannot be used to probe
        for another org's sinks or traces. No `WWW-Authenticate` and no
        upstream body is ever relayed. Each of these cases does record a distinguishing
        reason in the service log. Verify the org, target, and authorization before
        retrying; if they appear correct, contact the platform operator because the response
        cannot identify the cause.
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/TelemetryNotFound"
  schemas:
    TelemetryNotFound:
      type: object
      properties:
        statusCode:
          type: integer
          example: 404
        error:
          type: string
          example: Not Found
        message:
          type: string
          example: Not Found
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

Telemetry Read API (MLflow-native)

openapi: 3.0.3
info:
  title: TetraScience Telemetry Read API (MLflow-native)
  version: 1.0.0
  description: |-
    These endpoints are what an MLflow client calls on your behalf. Most readers should point an MLflow client at the base URL rather than calling these endpoints by hand.

    ## Authentication

    All endpoints require a Tetra token, which an MLflow client sends as `Authorization: Bearer <token>` from `DATABRICKS_TOKEN`, and your organization, supplied one of two ways: the `x-org-slug` header, as on the write plane, or an `/org/{orgSlug}` prefix on the base URL. A stock `mlflow` client has no setting for an arbitrary header but does concatenate its configured base URL onto every request, so the path form is what lets it read without any plugin.

    ## Base URL

    All endpoints are served behind `/ai-platform`, without `/v1`. Each one is served twice, bare and under `/org/{orgSlug}`, sharing a single authorization path.
servers:
- url: https://gateway.tetrascience.com/ai-platform/org/{orgSlug}
  description: Org-scoped base URL (US MT). Point a stock MLflow client here and send no organization header.
  variables:
    orgSlug:
      default: your-org-slug
      description: Your organization slug. In the URL form it must start with a letter or digit and contain only letters, digits, and hyphens.
- url: https://gateway.tetrascience.com/ai-platform
  description: TetraScience AWS API Gateway (US MT). Send your organization in the `x-org-slug` header.
tags:
- name: Telemetry
paths:
  "/api/4.0/mlflow/traces/search-long-running":
    post:
      summary: Start an asynchronous trace search
      description: |
        Called by `mlflow.search_traces()`. The body is strictly validated and fully
        reconstructed from validated fields before forwarding, so a caller cannot
        redirect the query at another org's data.

        `sql_warehouse_id` is optional and should not be sent: the gateway always
        forwards the warehouse bound to the resolved sink. Sending a DIFFERENT value
        is refused with the opaque 404.

        `locations` must be exactly one entry naming the caller's own sink. A
        multi-location search is not supported today.
      tags:
      - Telemetry
      security:
      - bearerAuth: []
      parameters:
      - "$ref": "#/components/parameters/OrgSlugReadPlane"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/TelemetrySearchTracesRequest"
      responses:
        '200':
          description: A `SearchTracesOperation` in snake_case. While `done:false`, `name` is a gateway-minted operation capability, never `operations/{id}`.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/TelemetrySearchTracesOperation"
        '404':
          "$ref": "#/components/responses/TelemetryOpaqueNotFound"
        '429':
          "$ref": "#/components/responses/TelemetryRetryable"
        '503':
          "$ref": "#/components/responses/TelemetryRetryable"
  "/api/4.0/mlflow/traces/search/operations/{op}":
    get:
      summary: Poll an asynchronous trace search
      tags:
      - Telemetry
      security:
      - bearerAuth: []
      parameters:
      - "$ref": "#/components/parameters/OrgSlugReadPlane"
      - name: op
        in: path
        required: true
        schema:
          type: string
        description: A gateway-minted operation capability from `search-long-running`. Short-lived and bound to the original query; a raw upstream operation id is refused.
      responses:
        '200':
          description: The operation, completing to `done:true` with `response.trace_infos`.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/TelemetrySearchTracesOperation"
        '404':
          "$ref": "#/components/responses/TelemetryOpaqueNotFound"
        '429':
          "$ref": "#/components/responses/TelemetryRetryable"
        '503':
          "$ref": "#/components/responses/TelemetryRetryable"
  "/api/4.0/mlflow/traces/{target}/batchGet":
    get:
      summary: Fetch spans for known trace ids
      description: Reached by `mlflow.get_trace()` and by `search_traces(include_spans=True)`. Arguments travel in the query string, never in a body.
      tags:
      - Telemetry
      security:
      - bearerAuth: []
      parameters:
      - "$ref": "#/components/parameters/OrgSlugReadPlane"
      - name: target
        in: path
        required: true
        schema:
          type: string
        description: The fully qualified trace location, in the form `catalog.schema.sinkId`, not a bare sink id.
      - name: location_id
        in: query
        required: true
        schema:
          type: string
        description: Exactly one entry, equal to `target`.
      - name: trace_ids
        in: query
        required: true
        description: |
          One to 100 trace ids, repeated as `trace_ids=a&trace_ids=b`. Each must match
          `^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$`. An empty list, more than 100, or one
          malformed id refuses the whole request with the uniform 404. Query keys other than
          `location_id`, `trace_ids` and `sql_warehouse_id` are refused the same way.
        schema:
          type: array
          minItems: 1
          maxItems: 100
          items:
            type: string
            pattern: "^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"
      - name: sql_warehouse_id
        in: query
        required: false
        schema:
          type: string
        description: Optional; omit it. Repeating it is refused, because which value was honoured would not be answerable from the request alone.
      responses:
        '200':
          description: The requested spans.
        '404':
          "$ref": "#/components/responses/TelemetryOpaqueNotFound"
        '429':
          "$ref": "#/components/responses/TelemetryRetryable"
        '503':
          "$ref": "#/components/responses/TelemetryRetryable"
  "/api/2.0/sql/warehouses/{id}":
    get:
      summary: SQL warehouse status
      description: The preflight an MLflow client performs before a trace search. Only the warehouse bound to your own sink is addressable.
      tags:
      - Telemetry
      security:
      - bearerAuth: []
      parameters:
      - "$ref": "#/components/parameters/OrgSlugReadPlane"
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Warehouse state.
        '404':
          "$ref": "#/components/responses/TelemetryOpaqueNotFound"
        '429':
          "$ref": "#/components/responses/TelemetryRetryable"
        '503':
          "$ref": "#/components/responses/TelemetryRetryable"
  "/api/2.0/sql/warehouses/{id}/start":
    post:
      summary: Start a stopped SQL warehouse
      tags:
      - Telemetry
      security:
      - bearerAuth: []
      parameters:
      - "$ref": "#/components/parameters/OrgSlugReadPlane"
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Start accepted.
        '404':
          "$ref": "#/components/responses/TelemetryOpaqueNotFound"
        '429':
          "$ref": "#/components/responses/TelemetryRetryable"
        '503':
          "$ref": "#/components/responses/TelemetryRetryable"
components:
  parameters:
    OrgSlugReadPlane:
      name: x-org-slug
      in: header
      required: false
      schema:
        type: string
        minLength: 1
        maxLength: 128
      description: |
        Optional on the read plane ONLY, and only because the org can arrive in the URL
        instead. Every request must still name exactly one organization, by this header or
        by an `/org/{orgSlug}` prefix on the base URL. A request carrying neither is
        refused during authentication with `Missing orgSlug header`, before any route
        handler runs. A request carrying both, naming DIFFERENT organizations, fails
        closed and renders as the uniform 404: answering for either one risks serving an
        org the caller did not mean.

        Either form is a SELECTOR, never an authenticator. Authorization is decided
        against the verified token, so naming an org the token does not carry yields no
        policies and is refused. Selection can only narrow what the token already allows.

        The write plane still requires this header.
  responses:
    TelemetryOpaqueNotFound:
      description: |
        The uniform telemetry 404. Absence, an unauthorized org, a malformed target, a
        registry record that failed validation, and an upstream response the gateway
        refuses to relay are all indistinguishable here by design, so the response does
        not distinguish absent from forbidden and the endpoint cannot be used to probe
        for another org's sinks or traces. No `WWW-Authenticate` and no
        upstream body is ever relayed. Each of these cases does record a distinguishing
        reason in the service log. Verify the org, target, and authorization before
        retrying; if they appear correct, contact the platform operator because the response
        cannot identify the cause.
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/TelemetryNotFound"
    TelemetryRetryable:
      description: |
        The one carve-out from the uniform 404. Answering 404 for an outage would tell a
        caller their traces do not exist when the truth is that we could not look, so
        transient failures answer as themselves with `Retry-After`. A 429 means the org's
        read budget or the upstream telemetry store is saturated; back off for at least
        `Retry-After` before retrying. A 503 means the service or one of its dependencies
        is temporarily unavailable; back off and retry after `Retry-After`. Messages come
        from a closed, frozen table, and no upstream text is ever interpolated.
      headers:
        Retry-After:
          schema:
            type: string
          description: Seconds to wait before retrying.
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/TelemetryRetryableBody"
  schemas:
    TelemetrySearchTracesRequest:
      type: object
      required:
      - locations
      additionalProperties: false
      description: |
        Strictly validated and then fully rebuilt before forwarding, the caller cannot inject a
        target. Any property not listed here is refused with the uniform 404, as is any unknown
        key nested inside `locations`.
      properties:
        locations:
          type: array
          minItems: 1
          maxItems: 1
          description: Exactly one entry, naming the caller's own sink. More than one is refused.
          items:
            type: object
            required:
            - type
            - mlflow_experiment
            additionalProperties: false
            properties:
              type:
                type: string
                enum:
                - MLFLOW_EXPERIMENT
              mlflow_experiment:
                type: object
                required:
                - experiment_id
                additionalProperties: false
                properties:
                  experiment_id:
                    type: string
                    minLength: 1
                    maxLength: 256
                    description: The `sinkId`. Named `experiment_id` because this is MLflow's own wire format, which the gateway does not get to rename. Must equal the resolved sink; any other value is refused. Values longer than 256 characters are refused.
        max_results:
          type: integer
          minimum: 1
          maximum: 1000
          default: 100
        filter:
          type: string
          maxLength: 10000
        order_by:
          type: array
          maxItems: 8
          items:
            type: string
            minLength: 1
            maxLength: 1024
          description: At most 8 entries; each must be a non-empty string of at most 1024 characters. An empty-string entry is refused, not ignored.
        page_token:
          type: string
          description: A gateway-minted page capability from a previous response, not a raw upstream token.
        sql_warehouse_id:
          type: string
          maxLength: 1024
          description: Optional; do not send it. The gateway always forwards the warehouse bound to the resolved sink, so omitting it and sending the matching value behave identically. A different value is refused.
    TelemetrySearchTracesOperation:
      type: object
      properties:
        name:
          type: string
          description: A gateway-minted operation capability. Never `operations/{id}`, pass it verbatim to the poll endpoint.
        done:
          type: boolean
        response:
          type: object
          properties:
            trace_infos:
              type: array
              items:
                type: object
              description: Passed through from the upstream telemetry store untouched.
            next_page_token:
              type: string
              description: Replaced with a gateway-minted page capability.
    TelemetryNotFound:
      type: object
      properties:
        statusCode:
          type: integer
          example: 404
        error:
          type: string
          example: Not Found
        message:
          type: string
          example: Not Found
    TelemetryRetryableBody:
      type: object
      properties:
        statusCode:
          type: integer
          enum:
          - 429
          - 503
        error:
          type: string
          enum:
          - Too Many Requests
          - Service Unavailable
        message:
          type: string
          description: One of a closed set of messages, each stating explicitly that the response is not a claim about whether the caller's traces exist.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

Documentation Feedback

Do you have questions about our documentation or suggestions for how we can improve it? Start a discussion in TetraConnect Hub. For access, see Access the TetraConnect Hub.

📘

NOTE

Feedback isn't part of the official TetraScience product documentation. TetraScience doesn't warrant or make any guarantees about the feedback provided, including its accuracy, relevance, or reliability. All feedback is subject to the terms set forth in the TetraConnect Hub Community Guidelines.


Did this page help you?