> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runagain.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Probes

> Capture an agent's outbound HTTP calls as spans — the tool/API side of the agent loop.

**Runagain Probes** give an agent's **outbound** HTTP(S) traffic the same treatment RunAgain gives
its LLM calls: capture it and match it to the trace that caused it. A transparent proxy runs inside
your sandbox; the agent is unchanged.

Probes are **optional** — an opt-in layer that complements OpenTelemetry span instrumentation, not a
replacement for it. An agent already emitting `gen_ai.*` spans keeps working exactly as before;
turning Probes on adds the outbound HTTP calls into the *same* traces.

<Tip>
  This release focuses on **collection** — capturing every outbound call. Deterministic **replay**
  (serving stored responses instead of hitting the real API) is on the roadmap.
</Tip>

## How it works

Every outbound call the agent makes is captured by the proxy, recorded as a `SPAN_KIND_CLIENT`
span, and stored with a fingerprint. Because the proxy reads the request's `traceparent` header, the
captured call lands **inside** the agent's existing trace, nested under the LLM or tool span that
made it — no extra correlation step.

<Steps>
  <Step title="The agent makes a request">
    Its HTTP client sends the call through the proxy and carries a `traceparent` header.
  </Step>

  <Step title="The proxy captures it">
    Request + response are recorded, secrets in headers are redacted, and a fingerprint is computed.
  </Step>

  <Step title="It becomes a span in the trace">
    The interaction is posted to the collector and appears in the trace explorer, nested under the
    calling span with an `http` badge (method + status).
  </Step>
</Steps>

## Modes

| Mode          | Real API? | Captures? | Use it for                                                  |
| ------------- | --------- | --------- | ----------------------------------------------------------- |
| `learn`       | yes       | yes       | Recording production/dev traffic into traces (the default). |
| `passthrough` | yes       | no        | Proxying without capture — scope which traffic is traced.   |

Replay-oriented modes (`replay`, `hybrid`) are designed but not yet available.

## Request fingerprint

Each captured call gets a **fingerprint** — the key that identifies it (and, later, matches a live
request to a stored response). It is intentionally **not** URL-only: it canonicalizes method, host,
normalized path, selected query params, and normalized JSON body, and ignores volatile values
(timestamps, request IDs, auth headers, signatures, pagination cursors, idempotency keys).
Per-integration ignore rules are configurable.

## What's stored

The full request (method, host, path, query, headers, body) and response (status, headers, body)
are stored on the span — request in `input`, response in `output`, offloaded to blob storage for
large bodies. Secrets are redacted **inside the sandbox**, before anything is sent. These promoted
fields are filterable: `http_method`, `http_host`, `http_path`, `http_status_code`,
`http_fixture_set`, `http_scenario`, `http_replayed`.

See the [sandbox proxy integration](/integrations/sandbox-proxy) to set it up, and
[Observability](/concepts/observability) for how spans and traces fit together.
