Privacy
Metadata-first, enforced at the API
AgentSpeed stores metrics and metadata about your runs, never their contents. This is not just a policy line. It is enforced in code at the ingest boundary, so prompt and output text cannot be stored even if something tries to send it.
This page explains the approach. For the formal document, see our Privacy Policy.
What we keep, what we never see
Stored (metadata)
- Run status (succeeded / failed / timeout) and timing
- Latency, and p50/p95 rollups
- Token counts and computed cost
- A quality score (a number 0–1) when you choose to send one
- Model name, agent name, span names, tool names
- Error type and the short error message you send
- Log-line severity and a short message label
Never reaches our database
- Prompts or system prompts
- Model outputs / completions
- Message or conversation content
- Retrieved documents or tool inputs/outputs
- Anything under prompt, output, messages, content, choices, …
How it's enforced
- There is no content field. The ingest contract has no place for prompt or output text, anywhere in a run, span, or event. The shape only describes metrics and metadata.
- Known content keys are stripped before validation. A denylist drops fields like
prompt,completion,messages,content,output, and their variants, recursively, even if your SDK attaches them by habit. They are removed before anything is parsed. - The schema is strict. After stripping, validation runs in strict mode, so any remaining unrecognized key is rejected with a 422 rather than quietly stored.
- We log that it happened, not what it was. When a content key is stripped we record the key name (e.g.
prompt), never its value, so the drop is auditable without leaking anything.
The whole payload, in the open
A run report is just this. There is nowhere in it for prompt or output text:
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"
}
]
}'Journey canaries follow the same rule: a run records each step's pass/fail and timing, not the page contents it read or any prompt used to evaluate it.