Skip to content

Wire envelope spec

The three SDKs (Python, Node, Go) send the exact same JSON envelope to POST /api/v1/ai/ingest with Authorization: Bearer aiv_.... You can also POST directly without an SDK; the envelope is the contract.

Endpoint

POST /api/v1/ai/ingest
Host: api.monsys.ai
Authorization: Bearer aiv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json

Top-level envelope

{
"trace_id": "uuid", // client-generated UUIDv4 (required)
"root_op": "rag.chat", // free-text label (required)
"status": "ok" | "error" | "partial", // (required)
"started_at": "2026-05-12T09:50:00Z", // RFC3339 (required)
"ended_at": "2026-05-12T09:50:01Z", // RFC3339 (optional)
"user_session_hash": "", // SHA256 of session id, optional
"sampling_decision": "full", // "full" | "head" | "summary"
"spans": [ ... ] // 1..N spans (required)
}

Span

{
"span_id": "uuid", // UUIDv4 (required)
"parent_span_id": "uuid", // "" for root span
"op": "openai.chat", // free-text (required)
"provider": "openai", // canonical provider name
"model": "gpt-4o-mini", // model id
"started_at": "2026-05-12T09:50:00.001Z",
"ended_at": "2026-05-12T09:50:00.987Z",
"status": "ok", // "ok" | "error" | "refused" | "partial"
"input_tokens": 42,
"output_tokens": 17,
"prompt": "...", // raw — redacted on the hub
"completion": "...", // raw — redacted on the hub
"system_msg": "...",
"tool_io": "...", // tool call or function result
"attributes": { ... }, // optional top-level metadata
"events": [ { ... }, ... ] // optional event stream
}

Canonical provider names

Providerprovider value
OpenAIopenai
Anthropic Claudeanthropic
Google Geminigoogle
Mistral AImistral
Azure OpenAIazure
Local (Ollama)ollama

Other providers are accepted but get no pricing lookup (cost = 0).

Pricing lookup

On ingest the hub looks up ai_model_pricing by (provider, model). Match is exact — new models not in the table get total_cost_micro_eur = 0. Request an update via info@be-hosted.be (pricing changelog page — coming soon).

The pricing row used is pinned per span via a pricing_snapshot_id FK — backfilling prices does not change historical costs.

Response

{
"received": true,
"trace_id": "uuid",
"spans": 3,
"pii_hits": 1,
"total_cost_micro_eur": 603290
}

HTTP status:

  • 200 — processed (see body)
  • 401 — token invalid or revoked
  • 403 — tenant has ai_observability_enabled = false
  • 400 — invalid envelope (see error in body)
  • 5xx — hub-side error; the SDK does not retry (failures are silent)

Example curl

Terminal window
curl -X POST https://api.monsys.ai/api/v1/ai/ingest \
-H "Authorization: Bearer aiv_xxxx" \
-H "Content-Type: application/json" \
-d '{
"trace_id": "0e2216d5-7b6d-448a-924c-c7a08b1a7e4a",
"root_op": "manual_test",
"status": "ok",
"started_at": "2026-05-12T09:50:00Z",
"ended_at": "2026-05-12T09:50:01Z",
"sampling_decision": "full",
"spans": [{
"span_id": "a1b2c3d4-e5f6-4789-9abc-def012345678",
"parent_span_id": "",
"op": "openai.chat",
"provider": "openai", "model": "gpt-4o-mini",
"started_at": "2026-05-12T09:50:00.001Z",
"ended_at": "2026-05-12T09:50:00.987Z",
"status": "ok",
"input_tokens": 22, "output_tokens": 12,
"prompt": "My IBAN is BE68 5390 0754 7034.",
"completion": "I cannot help with banking details.",
"attributes": {}, "events": []
}]
}'

OpenTelemetry GenAI compat

We map OTel GenAI semantic conventions onto this envelope internally, but don’t accept OTLP directly yet. Reason: OTLP/HTTP binary overhead is overkill for one-call-per-trace. If you have an OTel-only stack, write a thin adapter from OTel span → our envelope (see envelope-from-otel.md — coming soon).