SDK & REST ingestion
Pasting a trace into the playground is great for a one-off. To catch silent failures continuously, send your runs to Lumni as they finish. Every ingested run is normalized and passed through all five detectors automatically.
Authentication
Section titled “Authentication”Ingestion is authenticated with a per-tenant API key sent as a bearer token. Keep it server-side.
export LUMNI_API_KEY="sk_live_…"Send a run
Section titled “Send a run”The core endpoint is POST /v1/ingest/runs. A run is the full execution plus
its ordered steps.
curl -sS https://agentf.lumniverse.com/v1/ingest/runs \ -H "authorization: Bearer $LUMNI_API_KEY" \ -H 'content-type: application/json' \ -d '{ "userRequestText": "Refund my last order", "success": true, "outcomeSummary": "Your refund has been processed.", "metadata": { "model": "gpt-4o", "costUsd": 0.021 }, "steps": [ { "stepKind": "tool", "stepName": "issue_refund", "status": "failed", "errorMessage": "502 Bad Gateway", "inputSummary": "{ order_id: 8842 }" }, { "stepKind": "model", "outputSummary": "Your refund has been processed." } ] }'import os, requests
requests.post( "https://agentf.lumniverse.com/v1/ingest/runs", headers={"authorization": f"Bearer {os.environ['LUMNI_API_KEY']}"}, json={ "userRequestText": "Refund my last order", "success": True, "outcomeSummary": "Your refund has been processed.", "metadata": {"model": "gpt-4o", "costUsd": 0.021}, "steps": [ { "stepKind": "tool", "stepName": "issue_refund", "status": "failed", "errorMessage": "502 Bad Gateway", "inputSummary": "{ order_id: 8842 }", }, {"stepKind": "model", "outputSummary": "Your refund has been processed."}, ], }, timeout=10,)await fetch("https://agentf.lumniverse.com/v1/ingest/runs", { method: "POST", headers: { authorization: `Bearer ${process.env.LUMNI_API_KEY}`, "content-type": "application/json", }, body: JSON.stringify({ userRequestText: "Refund my last order", success: true, outcomeSummary: "Your refund has been processed.", metadata: { model: "gpt-4o", costUsd: 0.021 }, steps: [ { stepKind: "tool", stepName: "issue_refund", status: "failed", errorMessage: "502 Bad Gateway", inputSummary: "{ order_id: 8842 }" }, { stepKind: "model", outputSummary: "Your refund has been processed." }, ], }),});The run above trips the False Success detector: a tool failed, but the final message claimed the refund went through.
What to include
Section titled “What to include”You don’t need to capture everything, but the more of these you send, the sharper the detectors get:
-
userRequestText— powers Missing Tool Call (did the agent do the verb the user asked for?). -
Step
status/errorCode/errorMessage— the failure signal for False Success and loop detection. -
stepKind— so Lumni can tell tool steps from model steps. -
retryCountand repeated tool calls with the sameinputSummary— feeds Expensive Loop. -
metadata.modelandmetadata.inputTokens— feeds Context Overflow. -
metadata.costUsd— lets Lumni estimate wasted spend on runaway loops.
Other ingest paths
Section titled “Other ingest paths”- Streaming raw events instead of assembled runs → Events & Changes
- Already emitting OpenTelemetry spans → OpenTelemetry (OTLP)
- Agent lives inside Zendesk / Intercom / a CRM → Support-tool connectors