API reference · v0.1.0

Traces HTTP API

Tempo-compatible trace query and OTLP/Zipkin HTTP ingestion API. OTLP and Jaeger gRPC services are documented separately. Generated from the OpenAPI 3.1 document shipped with the server.

Base URLs

Writers serve every /write route and readers serve every /read route. The operator creates a Service for each, named after the Traces resource. Any writer accepts any write and forwards it to the owning shard, so plain round-robin load balancing is enough. OTLP/gRPC is served on 4317 and Jaeger gRPC on 14250 on every writer, outside this HTTP API.

Authentication

Requests use HTTP basic auth. Each NamespaceAuthentication grants one username read or write on one namespace, with the password held in a Secret. Probes and self-metrics are unauthenticated.

Namespaces

Data is partitioned into tenant namespaces, and every data route carries one as /read/ns/{namespace} or /write/ns/{namespace}. A Tempo data source pointed at http://traces-reader.telemetry:3200/read/ns/default works unchanged.

Errors and backpressure

Errors use the Tempo error envelope with a 4xx or 5xx status. When object storage falls behind, writers reject new batches with 429 and a Retry-After header; configure your agent to retry them.
Resource

traces

Trace lookup by ID. Readers merge partial traces from every shard the ID could route to.

Get trace (v1)

GET/read/ns/{namespace}/api/traces/{trace_id}
Fetches a full trace by its 32-character hex ID. Returns OTLP JSON by default; send a protobuf Accept header for protobuf.

Path parameters

  • namespacestringrequired
    Tenant namespace. A NamespaceAuthentication for this database must grant the caller access to it.
  • trace_idstringrequired
    32-character hexadecimal trace ID

Responses

  • 200Tempo v1 trace responseapplication/jsonapplication/x-protobuf
    ›TraceResponse
    • batchesobjectrequired
  • 404Trace not found
Request
curl http://traces-reader.telemetry:3200/read/ns/default/api/traces/4bf92f3577b34da6a3ce929d0e0e4736 \
  -u reader:$PASSWORD
Response · 200
{
  "batches": [
    {
      "resource": {
        "attributes": [
          {
            "key": "service.name",
            "value": {
              "stringValue": "checkout"
            }
          }
        ]
      },
      "scopeSpans": []
    }
  ]
}

Get trace (v2)

GET/read/ns/{namespace}/api/v2/traces/{trace_id}
Tempo v2 trace lookup. Same lookup as v1, wrapped in the v2 response envelope.

Path parameters

  • namespacestringrequired
    Tenant namespace. A NamespaceAuthentication for this database must grant the caller access to it.
  • trace_idstringrequired
    32-character hexadecimal trace ID

Responses

  • 200Tempo v2 trace responseapplication/jsonapplication/x-protobuf
    ›TraceResponse
    • batchesobjectrequired
  • 404Trace not found
Request
curl http://traces-reader.telemetry:3200/read/ns/default/api/v2/traces/4bf92f3577b34da6a3ce929d0e0e4736 \
  -u reader:$PASSWORD
Response · 200
{
  "trace": {
    "batches": [
      {
        "resource": {
          "attributes": [
            {
              "key": "service.name",
              "value": {
                "stringValue": "checkout"
              }
            }
          ]
        },
        "scopeSpans": []
      }
    ]
  }
}
Resource

ingest

OTLP/HTTP and Zipkin ingestion. OTLP/gRPC and Jaeger gRPC are served on separate ports.

Zipkin spans

POST/write/ns/{namespace}/api/v2/spans
Zipkin v2 JSON span ingestion. Legacy Zipkin reporters rarely retry rejected batches, so put an OpenTelemetry Collector in front when loss is unacceptable.

Path parameters

  • namespacestringrequired
    Tenant namespace. A NamespaceAuthentication for this database must grant the caller access to it.

Request body

application/json
  • annotationsarray of ZipkinAnnotation | null
    ›Show child attributes
    • timestampinteger · int64required
      Minimum 0
    • valuestringrequired
  • durationinteger · int64 | null
    Minimum 0
  • idstringrequired
  • localEndpointZipkinEndpoint | null
    ›Show child attributes
    • ipv4string | null
    • ipv6string | null
    • portinteger · int32 | null
      Minimum 0
    • serviceNamestring | null
  • namestring | null
  • parentIdstring | null
  • remoteEndpointZipkinEndpoint | null
    ›Show child attributes
    • ipv4string | null
    • ipv6string | null
    • portinteger · int32 | null
      Minimum 0
    • serviceNamestring | null
  • tagsmap of string | null
  • timestampinteger · int64 | null
    Minimum 0
  • traceIdstringrequired

Responses

  • 202Zipkin spans accepted
  • 400Invalid Zipkin requestapplication/json
    ›ErrorEnvelope
    • errorstringrequired
Request
curl -X POST "http://traces-writer.telemetry:3200/write/ns/default/api/v2/spans" \
  -u writer:$PASSWORD \
  -H 'Content-Type: application/json' \
  --data-binary @- <<'EOF'
[
  {
    "traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
    "id": "00f067aa0ba902b7",
    "name": "post /pay",
    "timestamp": 1791464400000000,
    "duration": 412000,
    "localEndpoint": {
      "serviceName": "checkout"
    },
    "tags": {
      "http.method": "POST"
    }
  }
]
EOF

OTLP traces

POST/write/ns/{namespace}/v1/traces
OTLP/HTTP ExportTraceServiceRequest, protobuf or JSON. OTLP/gRPC (4317) and Jaeger gRPC (14250) are also served on the pod.

Path parameters

  • namespacestringrequired
    Configured tenant namespace

Request body

application/jsonapplication/x-protobuf
OTLP ExportTraceServiceRequest.

Responses

  • 200OTLP traces accepted
  • 400Invalid OTLP requestapplication/json
    ›ErrorEnvelope
    • errorstringrequired
  • 413Request exceeds configured limit
Request
curl -X POST "http://traces-writer.telemetry:3200/write/ns/default/v1/traces" \
  -u writer:$PASSWORD \
  -H 'Content-Type: application/json' \
  --data-binary @- <<'EOF'
{
  "resourceSpans": [
    {
      "resource": {
        "attributes": [
          {
            "key": "service.name",
            "value": {
              "stringValue": "checkout"
            }
          }
        ]
      },
      "scopeSpans": [
        {
          "spans": [
            {
              "traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
              "spanId": "00f067aa0ba902b7",
              "name": "POST /pay",
              "kind": 2,
              "startTimeUnixNano": "1791464400000000000",
              "endTimeUnixNano": "1791464400412000000"
            }
          ]
        }
      ]
    }
  ]
}
EOF
Resource

operations

Probes and data source checks.

Liveness

GET/-/healthy
Returns 200 while the process is running. Use it as the Kubernetes liveness probe; it is unprefixed and not namespace-scoped.

Responses

  • 200Process is healthy
Request
curl http://traces-reader.telemetry:3200/-/healthy

Readiness

GET/-/ready
Returns 200 once every storage shard assigned to this pod is open, and 503 while shards are still being acquired or handed off. Use it as the readiness probe.

Responses

  • 200Server is ready
  • 503Assigned shards are not ready
Request
curl http://traces-reader.telemetry:3200/-/ready

Echo

GET/read/ns/{namespace}/api/echo
Tempo-compatible echo used by Grafana to validate the data source.

Path parameters

  • namespacestringrequired
    Tenant namespace. A NamespaceAuthentication for this database must grant the caller access to it.

Responses

  • 200Tempo-compatible echo
Request
curl http://traces-reader.telemetry:3200/read/ns/default/api/echo \
  -u reader:$PASSWORD