Documentation Index Fetch the complete documentation index at: https://docs.zeroeval.com/llms.txt
Use this file to discover all available pages before exploring further.
ZeroEval accepts standard OTLP trace data at POST /v1/traces, so any OpenTelemetry-instrumented application can export directly — through a collector, or straight from your app using an OTLP exporter.
When to use OTLP
Use this integration when:
Your application already uses OpenTelemetry for instrumentation
You want to fan out traces to multiple backends (ZeroEval + Datadog, Jaeger, etc.)
You’re running infrastructure you can’t modify but can route through a collector
You prefer a vendor-neutral instrumentation layer
Endpoint Reference
POST https://api.zeroeval.com/v1/traces
Header Value AuthorizationBearer YOUR_ZEROEVAL_API_KEYContent-Typeapplication/json or application/x-protobuf
The endpoint accepts the standard ExportTraceServiceRequest payload defined in the OTLP specification . Spans are converted to ZeroEval’s internal format — trace IDs, parent-child relationships, attributes, and status are all preserved.
Option 1: OpenTelemetry Collector
Route traces through a collector when you need batching, processing, or multi-destination fan-out.
Collector Configuration
Create otel-collector-config.yaml:
receivers :
otlp :
protocols :
grpc :
endpoint : 0.0.0.0:4317
http :
endpoint : 0.0.0.0:4318
processors :
batch :
timeout : 1s
send_batch_size : 1024
exporters :
otlphttp :
endpoint : https://api.zeroeval.com
headers :
Authorization : "Bearer ${env:ZEROEVAL_API_KEY}"
traces_endpoint : https://api.zeroeval.com/v1/traces
service :
pipelines :
traces :
receivers : [ otlp ]
processors : [ batch ]
exporters : [ otlphttp ]
Run with Docker Compose
services :
otel-collector :
image : otel/opentelemetry-collector-contrib:latest
command : [ "--config=/etc/otel-collector-config.yaml" ]
volumes :
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports :
- "4317:4317"
- "4318:4318"
environment :
- ZEROEVAL_API_KEY=${ZEROEVAL_API_KEY}
restart : unless-stopped
Run with Kubernetes
apiVersion : v1
kind : ConfigMap
metadata :
name : otel-collector-config
data :
config.yaml : |
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 1s
k8sattributes:
extract:
metadata:
- k8s.namespace.name
- k8s.deployment.name
- k8s.pod.name
exporters:
otlphttp:
endpoint: https://api.zeroeval.com
headers:
Authorization: "Bearer ${env:ZEROEVAL_API_KEY}"
traces_endpoint: https://api.zeroeval.com/v1/traces
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch, k8sattributes]
exporters: [otlphttp]
---
apiVersion : v1
kind : Secret
metadata :
name : zeroeval-secret
type : Opaque
stringData :
api-key : "YOUR_ZEROEVAL_API_KEY"
---
apiVersion : apps/v1
kind : Deployment
metadata :
name : otel-collector
spec :
replicas : 2
selector :
matchLabels :
app : otel-collector
template :
metadata :
labels :
app : otel-collector
spec :
containers :
- name : otel-collector
image : otel/opentelemetry-collector-contrib:latest
args : [ "--config=/etc/config.yaml" ]
env :
- name : ZEROEVAL_API_KEY
valueFrom :
secretKeyRef :
name : zeroeval-secret
key : api-key
ports :
- containerPort : 4317
name : otlp-grpc
- containerPort : 4318
name : otlp-http
volumeMounts :
- name : config
mountPath : /etc/config.yaml
subPath : config.yaml
volumes :
- name : config
configMap :
name : otel-collector-config
---
apiVersion : v1
kind : Service
metadata :
name : otel-collector
spec :
selector :
app : otel-collector
ports :
- name : otlp-grpc
port : 4317
- name : otlp-http
port : 4318
Option 2: Direct from Python
Export OTLP traces directly from your Python application without a collector. Use the ZeroEvalOTLPProvider included in the SDK, or configure a standard OTLPSpanExporter.
Using ZeroEvalOTLPProvider
from opentelemetry import trace
from zeroeval.providers import ZeroEvalOTLPProvider
provider = ZeroEvalOTLPProvider(
api_key = "YOUR_ZEROEVAL_API_KEY" ,
service_name = "my-service"
)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer( "my-service" )
with tracer.start_as_current_span( "process_request" ) as span:
span.set_attribute( "user.id" , "12345" )
result = do_work()
span.set_attribute( "result.status" , "ok" )
Using standard OTLPSpanExporter
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
exporter = OTLPSpanExporter(
endpoint = "https://api.zeroeval.com/v1/traces" ,
headers = { "Authorization" : "Bearer YOUR_ZEROEVAL_API_KEY" }
)
provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(exporter))
trace.set_tracer_provider(provider)
Option 3: Direct from Node.js
import { NodeTracerProvider } from "@opentelemetry/sdk-node" ;
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http" ;
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base" ;
const exporter = new OTLPTraceExporter ({
url: "https://api.zeroeval.com/v1/traces" ,
headers: {
Authorization: "Bearer YOUR_ZEROEVAL_API_KEY" ,
},
});
const provider = new NodeTracerProvider ();
provider . addSpanProcessor ( new BatchSpanProcessor ( exporter ));
provider . register ();
Attribute Mapping
ZeroEval maps standard OpenTelemetry span attributes to its internal format:
OTLP Attribute ZeroEval Field Notes span.namenameSpan name span.kindkindMapped to generic, llm, etc. span.statusstatusok, error, unsetspan.start_timestarted_atNanosecond timestamp converted to ISO 8601 span.end_timeended_atNanosecond timestamp converted to ISO 8601 span.trace_idtrace_idHex-encoded trace ID span.parent_span_idparent_span_idHex-encoded span ID span.attributes.*attributesAll attributes preserved resource.service.nameService identification Used for grouping
LLM Spans
To get LLM-specific features (cost calculation, token tracking), set these attributes on your spans:
Attribute Description llm.provider or gen_ai.systemProvider name (openai, anthropic, etc.) llm.model or gen_ai.request.modelModel identifier llm.input_tokens or gen_ai.usage.prompt_tokensInput token count llm.output_tokens or gen_ai.usage.completion_tokensOutput token count
Sessions
Attach session context to your OTLP spans via attributes:
Attribute Description zeroeval.session.idSession ID for grouping traces zeroeval.session.nameHuman-readable session name
The ZeroEvalOTLPProvider stamps these automatically when you configure a session via environment variables (ZEROEVAL_SESSION_ID, ZEROEVAL_SESSION_NAME).