While the WhyOps Proxy is the easiest way to instrument your agents automatically, you can send events directly toDocumentation Index
Fetch the complete documentation index at: https://whyops.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
whyops-analyse when you need custom tools, non-LLM reasoning steps, or internal framework logic in the graph.
When to use manual events
Use manual events for anything the proxy cannot see by itself:- your actual tool execution input/output
- retries inside your framework
- orchestration steps outside the LLM boundary
- runtime crashes after the LLM asked for a tool
- internal thinking blocks or planning state you choose to expose
Manual Events Reference
Detailed event payload shapes, recommended runtime patterns, idempotency guidance, and tool pipeline examples.
SDK Runtime Guides
Use the published SDKs if you want the same event model with typed helpers instead of raw JSON payloads.
Endpoint Overview
Base URL:https://a.whyops.com/api (or your self-hosted URL)
Authentication:
You must include an API key generated from the WhyOps Dashboard in the Authorization header.
userId, projectId, and environmentId.
If you do not use API key auth, you must send all of these headers manually:
Optional headers
You can optionally sendX-External-User-Id to link traces to your application’s user entities:
The ingestion pipeline
What happens on ingest
WhyOps validates the payload, merges auth context, enqueues the event when Redis is available, processes it sequentially per trace, resolves sampling plus missing step or span identifiers, and persists the final event totrace_events.
If queueing is unavailable, the controller falls back to direct synchronous processing.
Ingesting Events
Use the/events/ingest endpoint to send one or more events.
POST /api/events/ingest
Accepts a single event object or an array of event objects.
- Request
TypeScript Runtime Guide
Use the
@whyops/sdk trace builder instead of hand-rolling the event payloads in Node.js or Bun services.Python Runtime Guide
Use the
whyops sync and async trace helpers instead of posting raw REST payloads in Python services.Response behavior
202 Acceptedwhen the event was queued successfully201 Createdwhen it falls back to direct processing400for validation or missing auth context409when a trace is already bound to a different agent version
Other useful endpoints
POST /api/eventsprocesses events directly instead of queue-first and accepts the same payload shape.POST /api/events/tool-resultis a convenience endpoint that automatically setseventType: "tool_call_response".GET /api/events/helpreturns the machine-readable help payload for supported event types.GET /api/events?traceId=...&include=content,metadataandGET /api/events/:id?include=content,metadatalet you inspect stored events while debugging.
Event schema summary
Every event you send must conform to this schema:| Field | Type | Required | Description |
|---|---|---|---|
eventType | string | Yes | See below for allowed types. |
traceId | string | Yes | 1-128 chars. Groups events into a single agent run. |
agentName | string | Yes | 1-255 chars. Identifies the specific agent. |
spanId | string | No | Links related requests and responses (e.g. tool calls). |
stepId | integer | No | Used for ordering events sequentially (>= 1). |
parentStepId | integer | No | Used to build nested tree structures (>= 1). |
timestamp | string | No | ISO 8601 string. Defaults to the time received. |
content | any | No | The actual payload (e.g., messages, tool outputs). |
metadata | object | No | Additional context (e.g., latency, tokens, model used). |
idempotencyKey | string | No | Prevents duplicate event ingestion. |
externalUserId | string | No | Your application user ID to link traces to end-user entities. |
How step and span resolution works
If you do not sendstepId, WhyOps auto-increments from the last event in that trace.
If you do not send parentStepId, WhyOps uses the previous step as parent.
If you do not send spanId, WhyOps generates one for you.
Recommendation:
- explicitly set
spanIdfor request/response pairs - optionally let WhyOps generate
stepIdunless you already have a stable internal step model
Allowed event types
To ensure accurate static analysis and graph rendering, you must use one of the predefined event types.LLM Interactions
user_message: user input to the model or the full message history.llm_response: model response content and optional tool calls. Requiresmetadata.modelandmetadata.provider.embedding_request: input payload sent to an embedding provider.embedding_response: output summary from an embedding provider. Requiresmetadata.modelandmetadata.provider.llm_thinking: internal reasoning blocks such as Anthropic thinking.
Tool Execution
tool_call: legacy combined tool call event; backend splits it intotool_call_request+tool_call_responseautomatically.tool_call_request: a request to execute a tool. Requiresmetadata.tool.tool_call_response: the output returned from a tool execution. Requiresmetadata.tool.tool_result: tool results returned back to the model by your framework.
Errors
error: upstream API failures, tool crashes, framework exceptions, or app-side failures.