> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.talkif.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.talkif.ai/_mcp/server.

# Test and publish

> Talk to a draft in the browser, understand what validation checks and why, publish a version with notes, compare versions, and roll back.

Nothing reaches a phone line until you publish, and nothing should be published until you've talked to it. The builder gives you a browser call against the draft you're editing, a validator that refuses to publish anything that would fail on a real call, and a version history you can diff and roll back. This page is the loop: **test → fix → publish → compare**.

## The Flow Tester

**Test flow** in the builder toolbar opens the Flow Tester: a real-time WebRTC call between your microphone and the flow. Click the phone button, allow microphone access, and talk.

What makes it more than a demo:

* **It runs the draft as it is in the editor — unsaved edits included.** Change a prompt, hit the phone button again, hear the difference. No save, no publish.
* **It goes through the same pipeline as a phone call.** Same STT, LLM and TTS, same functions (your endpoints really get called), same validation and preparation. The only difference is the audio arrives from your browser instead of a carrier.
* **It shows the numbers a caller feels.** Per-turn **LLM TTFB** (time to first token), token counts and turn count sit next to the transcript. If TTFB is over a second here, it will be on the phone.
* **It's billed like a call**, at the same rates, and needs at least \$1.00 of available balance to start — so the cost breakdown you get afterwards is a true preview of production cost.

> **Test the paths you're worried about**
>
> Interrupt the agent mid-sentence. Give a wrong date. Ask for something the flow doesn't handle. Go silent for 15 seconds. Say goodbye and see whether it ends. A flow is ready when those calls go well, not when the happy path does.

One difference to know: a browser test has no phone number and no caller identity, so `contact.*` variables are empty and any function with an `onNull: reject` binding on caller context is hidden for that call. Test those paths with a real outbound call to your own phone.

## What validation checks

**Publish** runs the validator and refuses to publish on any error. The same checks run on save for anything you've filled in (a bad value is rejected immediately; an empty field is fine in a draft), and you can run them on demand with [`POST /flows/{flowId}/validate`](/api-reference/flows/validate-flow).

#### Structure

* Exactly one **Main Agent**, and it's the entry node.
* Every transition targets an agent that exists; no agent transitions to itself.
* Agent names are unique; function names are unique across the flow.

#### Prompts

* The Main Agent has a **System Prompt**; no other agent does (a System Prompt elsewhere would silently replace the call's persona from that point on).
* **Every** agent has an Agent Prompt.

#### Providers

* An **LLM**, an **STT** and a **TTS** provider are configured.
* Provider names are known and each model exists in the current catalogue. A model that has since been retired fails here — the fix is to pick a current one.
* Numeric settings are in range (temperature 0–2, ElevenLabs stability 0–1, …). Settings a model doesn't support — a temperature on a model that rejects it — are stripped rather than failed, so an old flow keeps publishing when a model's capabilities change.
* Language codes are valid for the chosen STT model.

#### Functions and actions

* A built-in function is `end_call` and nothing else.
* An HTTP Request references a flow function that exists and is active in this account.
* A Say action has text.

Errors name the field (`nodes.booking_agent.agentPrompt`) and a code (`required`, `invalid_model`, `out_of_range`, `duplicate_agent_name`, …). The builder shows them in the validation panel and marks the node.

## Publishing

**Publish** asks for optional **notes** — what changed — then validates and creates a new version. The version number auto-increments (`1.0.4` → `1.0.5`); from the API you can set it explicitly.

If someone else published while you had the flow open, publishing is refused with *"This flow was modified since you last loaded it"* — the API's `expectedVersion` optimistic lock. Refresh, review their change, and publish again.

After publishing:

* **Numbers on *latest*** serve the new version on their next call, immediately.
* **Numbers pinned** to the version you just replaced are moved to the new one; numbers pinned to older versions are untouched.
* **The draft stays editable.** Keep working; publish again when ready.
* **API calls** with no `flowVersion` use the new version.

Details of versions and pinning: [Flows and versions](/concepts/flows-and-versions).

## Comparing and rolling back

**Version History** lists every published version with its notes, who published it and when. Pick two to see a **diff** — what changed in prompts, transitions, functions and providers, ignoring layout.

**Restore** on any version republishes its content as a *new* version — history never rewinds, it grows. If `1.0.9` is bad, restoring `1.0.8` gives you `1.0.10` with `1.0.8`'s content, and every number on *latest* is on it at once. From the API: [`POST /flows/{flowId}/rollback/{version}`](/api-reference/flows/rollback-flow).

## A working loop

#### Edit, then talk

Change one thing — a prompt line, a model, a transition — and run the Flow Tester on the same scenario. One change per test, or you won't know what helped.

#### Watch the tester's numbers

TTFB and tokens per turn. If a change made the agent smarter but slower, decide which you wanted.

#### Publish with a note

"Shorter greeting; booking agent now reads details back." Future you, reading the version list at 2am, will be grateful.

#### Make one real call

Dial the number, or place an outbound call to your own phone. The browser can't test the carrier leg, caller identity, or voicemail.

#### Compare against the previous version's calls

The flow's stats and the cost breakdown per call are per version. If the new version costs 30% more per call, the diff tells you why.

## Next

#### [Flows and versions](/concepts/flows-and-versions)

States, versions, pinning and which version a call runs.

#### [Inbound and outbound routing](/telephony/inbound-and-outbound-routing)

Connect the published flow to a number.