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/v1route 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-platformroute 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).
NOTEThe Telemetry Read API uses the
/ai-platformbase URL without/v1, and an MLflow client reaches it through the Databricks REST surface. SetMLFLOW_TRACKING_URItodatabricks, setDATABRICKS_HOSTto the org-scoped base URLhttps://<your-gateway>/ai-platform/org/<your-org-slug>, and setDATABRICKS_TOKENto your Tetra token.
DATABRICKS_HOSTnames the TetraScience gateway, not a Databricks workspace. MLflow reads that variable name because thedatabrickstracking URI selects its Databricks REST client. SettingMLFLOW_TRACKING_URIto anhttps://URL selects the open source implementation instead, which calls endpoints that the gateway doesn't serve. Use the barehttps://<your-gateway>/ai-platformbase only if your client can send anx-org-slugheader.
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: JWTTelemetry 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: JWTDocumentation 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.
NOTEFeedback 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.
Updated 8 days ago

