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

# Test & Simulate

> Try your agent against the draft before you publish — over text, or live in-browser voice.

Every edit you make changes a **draft**. The tester lets you talk to that draft — by text or by
voice — before you publish it to phone and chat. Nothing you do here touches the live, published
version, and draft runs are **not billed**.

<Note>
  The tester always runs the **draft**. Phone and chat serve the last **published** version. If a
  change works in the tester but not on a real call, you probably haven't published yet — see
  [Versioning & Publishing](/concepts/versioning).
</Note>

## Simulate over text (and voice)

`POST /agents/{agentId}/simulate` opens a **server-sent events (SSE)** stream. Set `mode` to
`text` for the chat tester or `voice` for the in-browser voice tester. Leave `draftMode` as its
default (`true`) to run against the freshly-compiled draft.

Each SSE frame is a single audit event: the `event:` line is the event type, and the `data:` line
is the event JSON. You'll see `user_utterance`, `agent_message`, `tool_call`, `kb_retrieval`,
`guardrail`, and more stream by in real time — the same shapes you'll later read back as a
[receipt](/concepts/observe). The stream ends with `event: done` (or `event: error`).

<CodeGroup>
  ```bash curl theme={null}
  curl -N https://builder.flowyte.com/api/v1/agents/AGENT_ID/simulate \
    -H "Authorization: Bearer flowyte_sk_…" \
    -H "Content-Type: application/json" \
    -d '{"mode":"text","draftMode":true,"transcript":["What are your hours?"]}'
  ```

  ```js Node theme={null}
  const res = await fetch(
    "https://builder.flowyte.com/api/v1/agents/AGENT_ID/simulate",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer flowyte_sk_…",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ mode: "text", draftMode: true, transcript: ["What are your hours?"] }),
    },
  );
  const reader = res.body.getReader();
  // read the SSE stream until `event: done`
  ```

  ```python Python theme={null}
  import httpx

  with httpx.stream(
      "POST",
      "https://builder.flowyte.com/api/v1/agents/AGENT_ID/simulate",
      headers={"Authorization": "Bearer flowyte_sk_…"},
      json={"mode": "text", "draftMode": True, "transcript": ["What are your hours?"]},
  ) as r:
      for line in r.iter_lines():
          print(line)  # SSE frames; stops at `event: done`
  ```
</CodeGroup>

## In-browser voice with a talk-token

To test **voice** live in the browser, mint a short-lived **talk-token**. It returns the
credentials your browser needs to join a real-time voice session — a URL, a token, and a room.

<Warning>
  `POST /agents/{agentId}/talk-token` is a **dashboard-only** call. It is authenticated by your
  dashboard session, not by an API key, so it cannot be called with `flowyte_sk_…`. Use it from the
  in-browser tester.
</Warning>

With `draftMode: true` the session runs the ephemeral draft and is **not billed**. With
`draftMode: false` it runs the latest **published** version — and returns `409 no_published_version`
if the agent has never been published.

## In the API

| Action                               | Endpoint                                          | Scope                  |
| ------------------------------------ | ------------------------------------------------- | ---------------------- |
| Simulate (text / voice) over SSE     | `POST /agents/{agentId}/simulate`                 | `agents:write`         |
| Mint an in-browser voice talk-token  | `POST /agents/{agentId}/talk-token`               | dashboard session only |
| Kick a probe run (scripted scenario) | `POST /agents/{agentId}/probe/run`                | `agents:write`         |
| Poll a probe run                     | `GET /agents/{agentId}/probe/runs/{runId}`        | `agents:read`          |
| Stream probe progress (SSE)          | `GET /agents/{agentId}/probe/runs/{runId}/stream` | `agents:read`          |

<Tip>
  **Probe** runs a saved scenario end-to-end and reports whether quality gates passed — goal
  completion, per-turn latency, and language fidelity. Use it in CI to catch regressions before they
  reach callers.
</Tip>
