Endpoints
All three require an API key with the
telemetry:write scope. The host column is
not decoration: see the note below on why logs differ.
Quick Setup
Set the standard OpenTelemetry environment variable to point at MeshAI:Traces and metrics go to
ingest.meshai.dev, a separate host from
api.meshai.dev. That is deliberate, not a typo: ingest runs behind an
OpenTelemetry collector that absorbs large exports and splits them into smaller
batches, so a batch too big for the API in one piece is still recorded rather
than rejected. Registry, cost and governance stay on api.meshai.dev.Logs are the exception. The collector is configured for traces and metrics
only, so /api/v1/ingest/v1/logs is served directly by api.meshai.dev. Send
logs to ingest.meshai.dev and you get a 404, which is not in OTLP’s
retryable set, so the exporter drops the batch rather than holding it, with
nothing to see server-side. That is why the Codex CLI connector points at
api.meshai.dev.Do not infer a host from a status code here. An unauthenticated request is
rejected at the edge before routing, so every path on ingest.meshai.dev
answers 401 whether or not it exists.A 200 from the ingest endpoint means your batch was accepted, not yet
stored, because the collector forwards it onward. A missing or malformed key
returns 401 immediately, but an expired key or one lacking telemetry:write
is only rejected further along. Confirm spans actually arrived in the dashboard
rather than relying on the status code.The ingest endpoint accepts OTLP protobuf (
application/x-protobuf, the stock
OTLP SDK default), OTLP JSON, and gzip-compressed bodies (Content-Encoding: gzip).
Set OTEL_EXPORTER_OTLP_PROTOCOL=http/json only if you need to force JSON.
OTEL_SERVICE_NAME sets the service.name attribute MeshAI uses to name your
auto-discovered agent. If you use a real OpenTelemetry SDK and leave it unset,
the SDK itself injects a default of unknown_service:<language> (for example
unknown_service:python). If your OTLP payload omits the service.name
resource attribute entirely, such as from a hand-rolled emitter that doesn’t
use an OTel SDK, MeshAI falls back to naming the agent unknown-agent.What Gets Extracted
When MeshAI receives trace data, it automatically:- Discovers agents from the
service.nameresource attribute (set viaOTEL_SERVICE_NAMEor your SDK’sResource). Each distinctservice.namebecomes its own agent in the registry. On the free tier only one agent is admitted: the firstservice.nameclaims the single free slot and spans from any otherservice.nameare dropped until you upgrade, so emit under oneservice.nameon the free tier and split into per-service agents once on a paid plan - Extracts token usage from
gen_ai.usage.input_tokensandgen_ai.usage.output_tokensattributes - Records model info from
gen_ai.request.modelandgen_ai.systemattributes - Records non-token activity separately, so operational spans and failed calls without usage attributes still contribute activity and error evidence without appearing as billable usage
- Records bounded span duration samples when valid start and end timestamps are present. Missing, malformed, zero, negative, or longer-than-24-hour durations are excluded from latency statistics without rejecting the span
- Registers new agents in your registry if they don’t already exist
Python Example
Using the OpenTelemetry Python SDK:Node.js Example
Framework Integration
Most agent frameworks support OpenTelemetry natively or via plugins:
Set the environment variables above and these frameworks will export traces to MeshAI automatically.
Response Format
A
200 can be returned when accepted_spans is 0. Check duplicate_spans, rejected_spans, rejected_reasons, and any partial_success value rather than inferring the outcome from the status code alone. A span without gen_ai.usage.* is recorded as non-billable activity; add usage attributes when you also want cost and token accounting.Anomaly signal coverage
Proxy and OTLP telemetry use separate reliability baselines. Both can contribute request counts and error-rate evidence. OTLP trace spans can also contribute latency when they contain a valid positive duration of no more than 24 hours. Spans without a valid duration, including synthetic spans derived from OTLP log records, remain recorded but do not become latency samples. Latency evaluation requires at least 10 samples in the baseline window, 5 in the recent window, and at least 50% duration coverage in both windows. The reported latency statistic is the mean of exact five-minute bucket p95 values. It is not a percentile recomputed across every request in the full multi-day window. Error-rate evaluation remains independent when latency is unavailable or below these gates.The expanded anomaly pipeline is live. API PR #84 activated recurring five-minute production execution on August 11, 2026. Three consecutive UTC boundaries at 20:20, 20:25, and 20:30 each had exactly one elected runner, completed in 655 ms, 350 ms, and 490 ms, and reported no errors. The initial run created 13 continuity incidents from existing gaps; the next two created no duplicates.
Metrics (Preview)
The metrics endpoint (/api/v1/ingest/v1/metrics) accepts OTLP metric exports and acknowledges them. Metrics-based anomaly detection is coming in Phase 2.
