Skip to content

Sending Traces

Mibo accepts traces on a single endpoint, POST /public/traces, with two supported request shapes. Both produce the same canonical trace internally — pick whichever fits your stack.

Both paths are first-class. Neither is a workaround for the other.

You’re on… Use
A service emitting OTel via the Anthropic / OpenAI / Traceloop / OpenLLMetry SDKs OTLP
n8n self-hosted ≥ 2.19 with N8N_OTEL_TRACING_ENABLED=true OTLP
n8n Cloud (no host-level OTel) Your API — see Send traces from n8n for all options
Flowise self-hosted with native OTel enabled OTLP
Flowise Cloud (no host-level OTel) Your API via the Flowise template
Anything else with an HTTP endpoint — LangChain agents, your own code, scripts, curl Your API

If you can choose OTLP, it usually wins — your existing exporter is already batched, retried, and instrumented. Your API exists so users on managed hosts (n8n Cloud, Flowise Cloud, anything where you can’t touch host env vars) get the same first-class trace ingestion.

  • Endpoint: POST https://api.mibo-ai.com/public/traces
  • Auth: x-api-key header. See API Keys & Trace Routing.
  • Identity: Your API uses the x-request-id HTTP header. Present → replaces the trace with that id. Absent → server-generated UUID, so each POST creates a new trace. For a single-trace OTLP request, Mibo uses x-request-id when present, then the trace’s traceId to merge later batches. Mibo splits a multi-trace OTLP batch by traceId and ignores its x-request-id.
  • Agent resolution: Your API uses a single-agent key automatically; otherwise it requires platformId (top level) or metadata.mibo.platform_id. OTLP always requires a service.name resource attribute that matches the agent’s OTLP service name. The API key must also be allowed to write to that matched agent.
  • Canonical span model: spans with span_id, parent_span_id, name, attributes, optional timing and status. span.name is always the user-facing display label of the step.
OTLP Your API
Body shape resourceSpans[].scopeSpans[].spans[] (OTel envelope) { spans: [...] } (flat)
Attributes encoding OTel key/value list ({ key, value: { stringValue: "..." } }) Plain JSON object
Batching Multi-POST: server merges by traceId/span_id One POST per trace; create-or-replace by externalId
Best for Long-lived processes, SDK-instrumented services Synchronous flows, short scripts, managed-host integrations

Mibo reads the same attributes on both paths — gen_ai.response.text, gen_ai.usage.input_tokens, gen_ai.tool.name, http.response.status_code, and the rest of the GenAI / HTTP semconv keys. Your assertions don’t change.

Whichever path you send on, these are the attributes assertions look up. Emit what you have; missing data surfaces as missing instrumentation in the dashboard rather than silent pass/fail.

Attribute What it powers
gen_ai.response.text Semantic assertions, response_regex, default text extraction
gen_ai.output.messages Same as above when present (preferred over response.text)
gen_ai.usage.input_tokens / output_tokens / reasoning.output_tokens token_limit
gen_ai.tool.name + gen_ai.tool.call.arguments tool_call (the span becomes a child tool call of its parent)
http.response.status_code http_status
Span name node_call (case-insensitive substring match)
Root span start/end_time_unix_nano response_time.max_ms

See Assertion Reference for the full mapping.