# Replay a real recorded session

> Send a real person's recorded user turns to a registered agent and compare its new responses with the originals.

Canonical page: https://anectico.com/docs/agents/replay-a-recorded-session/


Anectico can replay the exact user-authored turns from one recorded agent session against an agent
you registered. It sends the turns in their original order and compares each new response with what
the original agent returned.

This sends a real person's real words outside Anectico. Every replay must be requested explicitly,
and every request must confirm that transfer. Anectico never sends the person's identity to the
target agent. It uses the canonical person identity only to link the result back to the person who
owned the original session.

## Before you start

You need:

- a recorded agent session containing complete user messages and agent responses;
- an agent asset that is enabled for outbound A2A driving;
- an API key with `agents:write` and `agents:content:read`; and
- a project content policy that permits model transcripts to be stored and exported.

See [Drive one registered agent](/docs/agents/drive-an-agent) to save the target credential and
enable the agent. The target URL cannot be supplied or overridden by a replay request.

## Start one replay

```bash
curl -sS -X POST \
  https://app.anectico.com/api/v1/assets/<asset-id>/session-replays \
  -H "Authorization: Bearer $ANECTICO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": {"project_id": "<project-id>"},
    "session_key": "<recorded-session-key>",
    "confirm_real_person_content_export": true
  }'
```

The confirmation applies only to this request. It is not saved as a project setting, and omitting
it produces a durable `REFUSED` result without reading or sending the session.

Before the first send, Anectico verifies the whole recording. It refuses to replay more than eight
turns and stops without sending anything if a turn is missing, reordered, has no exact user-authored
text, has withheld or fragmented content, contains conflicting person identities, or ends without
an explicitly completed final run that owns one unambiguous original agent response. Completion
order decides which recorded response is final; the time a nested operation started does not.
Anectico also binds the validated user text to the exact bytes sent. It never substitutes a redacted
or earlier message and never reports a shorter recording as a successful replay.

For a confirmed replay, Anectico checks target containment and the current export and storage
decisions before recording replay progress. A contained target is stopped before the source is
loaded. An export-denied turn may still appear with its exact recorded words when storage is
permitted, but it is explicitly unsent and cannot reach the target.

Each verified turn then uses the same outbound safety path as a one-message drive: the registered
destination and credential stay fixed for that send, the request has a 15-second deadline, and its
outcome gets a drive-attempt record. Content policy is checked again before each export and before
each response is retained. A policy change can therefore stop turn four after three turns were sent;
the result reports `turns_sent: 3` and `turns_total: 8` with the reason.

Projects may start at most three session replays per hour. Every turn also counts toward the
ordinary limit of 10 drive attempts per project per minute. Exceeding either limit is a refusal or
stopped result, never silent truncation.

## Read the comparison

A replay result contains:

- the recorded session key, canonical person ID, and target asset ID;
- total, attempted, sent, compared, matched, and differed turn counts;
- the exact recorded user text for every turn;
- the original and replayed response text arrays;
- the bounded A2A reply as `replay_reply_json` (base64 in REST JSON);
- response byte sizes and SHA-256 digests; and
- a comparison kind plus the first differing byte in the canonical JSON response arrays.

`MATCH` means both response text arrays are byte-for-byte equal. `TEXT_CHANGED` means at least one
text value differs. `MESSAGE_COUNT_CHANGED` means the number of response text parts differs. This is
an exact comparison, not a semantic score: punctuation, whitespace, and capitalization count as
changes.

The top-level status is intentionally strict:

| Status | Meaning |
| --- | --- |
| `COMPLETED` | Every recorded user turn was sent and every response was compared. |
| `STOPPED` | The recording or an in-progress replay could not continue. Read `stop_code` and the counters. |
| `REFUSED` | The replay did not start, for example because confirmation was missing or the project limit was reached. |
| `STARTED` | Intent and current progress are durable, but no terminal result was recorded yet. Treat this as interrupted or still running, never as success. |

Common `stop_code` values include `recorded_content_withheld`, `no_user_authored_text`,
`recording_incomplete`, `person_unresolved`, `person_mismatch`, `turn_limit`,
`content_export_denied`, `content_export_unconfirmed`, `content_store_denied`,
`content_store_unconfirmed`, `agent_reply_incomplete`, and `driver_<outcome>`.
If result recording itself fails, the call still returns `STOPPED` rather than an availability error.
Its `persistence_*_failed` code identifies whether recording failed while starting the replay,
applying its replay limit, preparing turns, recording pre-send progress, recording a send outcome,
recording a comparison, completing, or saving another terminal result. Treat that result as failed,
never as evidence that a containment or content-policy check passed.

## Retrieve the durable result

```bash
curl -sS \
  "https://app.anectico.com/api/v1/agent-session-replays/<replay-id>?project_id=<project-id>" \
  -H "Authorization: Bearer $ANECTICO_TOKEN"
```

The read requires `agents:read`. Exact message and response content is returned only when the reader
also has `agents:content:read` and the current read policy permits it. Otherwise the counters,
comparison, digests, and stop state remain visible while the content fields are empty and
`content_withheld` explains why.

- [Drive one registered agent](/docs/agents/drive-an-agent) — configure and test the target first
- [Agent inventory](/docs/agents/agent-inventory) — find the asset and recorded session
- [Permissions and safety](/docs/agents/permissions-and-safety) — narrow the replay credential
