agentspeed.
Ingest API

Report a run in one call

When your agent finishes a run, send one authenticated POST to agentspeed.com/api/v1/runs. Agents auto-provision on first use. Generate a key under any project’s API keys tab.

Privacy: AgentSpeed is metadata-first. The API has no field for prompts or model output, rejects unknown fields, and strips any content-bearing keys before storing. We keep metrics about your runs, never their contents.
curl
curl -X POST https://agentspeed.com/api/v1/runs \
  -H "Authorization: Bearer $AGENTSPEED_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "agent": "checkout-assistant",
  "status": "succeeded",
  "model": "claude-opus-4-8",
  "inputTokens": 1200,
  "outputTokens": 340,
  "costUsd": 0.0185,
  "score": 0.92,
  "durationMs": 4200,
  "idempotencyKey": "run_123",
  "spans": [
    {
      "name": "vector search",
      "type": "retrieval",
      "status": "ok",
      "durationMs": 180,
      "order": 0
    },
    {
      "name": "completion",
      "type": "llm",
      "status": "ok",
      "durationMs": 4000,
      "order": 1,
      "inputTokens": 1200,
      "outputTokens": 340
    }
  ],
  "events": [
    {
      "level": "info",
      "message": "order #4823 placed"
    }
  ]
}'
TypeScript / Node
// Node 18+ / TypeScript: report one run after your agent finishes.
const res = await fetch("https://agentspeed.com/api/v1/runs", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.AGENTSPEED_API_KEY}`,
    "Content-Type": "application/json",
    // Optional: dedupe retries. Re-sending the same key upserts the run.
    "Idempotency-Key": runId,
  },
  body: JSON.stringify({
    agent: "checkout-assistant",
    status: "succeeded",            // "succeeded" | "failed" | "timeout"
    model: "claude-opus-4-8",
    inputTokens: 1200,
    outputTokens: 340,
    costUsd: 0.0185,
    score: 0.92,                    // quality score 0–1 (any number you compute)
    durationMs: 4200,
    spans: [
      { type: "retrieval", name: "vector search", status: "ok", durationMs: 180, order: 0 },
      { type: "llm", name: "completion", status: "ok", durationMs: 4000, order: 1 },
    ],
    events: [{ level: "info", message: "order #4823 placed" }],
  }),
});
if (!res.ok) throw new Error(`ingest failed: ${res.status} ${await res.text()}`);
const { run } = await res.json();
console.log("reported run", run.id);
Python
# Python 3: report one run after your agent finishes.
import os, requests

resp = requests.post(
    "https://agentspeed.com/api/v1/runs",
    headers={
        "Authorization": f"Bearer {os.environ['AGENTSPEED_API_KEY']}",
        # Optional: dedupe retries. Re-sending the same key upserts the run.
        "Idempotency-Key": run_id,
    },
    json={
        "agent": "checkout-assistant",
        "status": "succeeded",          # "succeeded" | "failed" | "timeout"
        "model": "claude-opus-4-8",
        "inputTokens": 1200,
        "outputTokens": 340,
        "costUsd": 0.0185,
        "score": 0.92,                  # quality score 0-1 (any number you compute)
        "durationMs": 4200,
        "spans": [
            {"type": "retrieval", "name": "vector search", "status": "ok", "durationMs": 180, "order": 0},
            {"type": "llm", "name": "completion", "status": "ok", "durationMs": 4000, "order": 1},
        ],
        "events": [{"level": "info", "message": "order #4823 placed"}],
    },
    timeout=10,
)
resp.raise_for_status()
print("reported run", resp.json()["run"]["id"])

Fields

agentstring, requiredSlug for the agent. Auto-provisioned on first run, no pre-registration.
statusenum, required"succeeded" | "failed" | "timeout".
modelstringModel identifier, e.g. claude-opus-4-8.
inputTokens / outputTokensint ≥ 0Token counts for the run.
costUsdnumber ≥ 0Run cost in USD.
scorenumber 0–1Optional quality score (eval/judge result or a mapped rating). A number, never content.
startedAtISO 8601Run start; defaults to receipt time.
durationMsint ≥ 0Wall-clock duration in milliseconds.
errorType / errorMessagestringShort error class + message (a log line, not model output).
idempotencyKeystringOptional. Dedupes retries (or send the Idempotency-Key header).
spans[]array{ type, name, status, durationMs, order } (+ optional model, tokens, cost).
events[]array{ level, message }, log lines only.

Send a quality score

score is the one field worth adding even if you skip the rest. Attach any deterministic number in 0–1 that you already compute — a rubric pass/fail, a schema-validation result, a thumbs-up rate, a downstream conversion — and we roll it up into average quality per agent and per model over time. That is how you catch the silent regression where success holds at 99% but answer quality slid.

We aggregate the number you send. We don’t run a judge, manage a dataset, or see your prompts or outputs — it’s quality monitoring on live production traffic, not evals.

Responses