# What should a demo tour script say? A template

- URL: https://getroomi.com/guides/demo-tour-script-template
- Updated: 2026-10-12

A demo tour script has three to six steps, one idea each, in the order you would pitch it. Start with who it is for, then the moment the product matters, then what the business gets. Each step names its screen, says what to notice and stands on its own, so a viewer can start anywhere.

This guide gives you the template twice: as a table to plan with, and as the lines of `pitch.json` it becomes. Then a worked example, and how to write each step. Every column is a field of the room’s tour, so what you write here is what the viewer reads. [Writing the tour](https://getroomi.com/docs/story) is the full reference, and [pitch.json](https://getroomi.com/docs/pitch-json) has every field. If the tour is taking the place of a deck, [sending a demo instead of a deck](https://getroomi.com/guides/how-to-send-a-demo-instead-of-a-deck) covers the rest of the switch.

## What is a demo tour script?

A demo tour script is what the room says when you are not in it. A live demo script is what you say on a call, with the prospect’s questions steering you. A tour script is written in advance, so anyone you send the link to gets the same pitch, in your order, whenever they open it.

| | A live demo script | A tour script |
|---|---|---|
| Who speaks | You, on a call | The room, in your words |
| When it runs | At the time you booked | Whenever the viewer opens their link |
| When someone goes off-script | You follow them | They leave the tour to explore, and can start again at any step |
| What you learn | What they said on the call | On Pro, how far each person took the tour, and where they stopped |

You need both. The tour does the first pitch for you, and the call picks up from where each person stopped. [How to pitch an idea to a client](https://getroomi.com/guides/how-to-pitch-an-idea-to-a-client) shows how the two fit one pitch.

## How long should a demo tour be?

Three to six steps, each with one idea. That is the room’s own guidance for a tour, not a statistic about attention. Three is the least that covers who it is for, the moment it matters and what the business gets. Past six, a tour starts to read like a manual.

The room takes longer tours. A viewer who wants more than the tour shows can leave it and explore the demo on their own, so the tour does not have to cover everything.

## The template

Plan the tour as a table first. Each row is a step, and each column is the field of `pitch.json` it fills. The square brackets are yours to replace.

| Step | Its job | Title (`title`, 60 characters at most) | What to notice (`say`, 300 characters at most) | Screen (`path`) | Frame (`device`) |
|---|---|---|---|---|---|
| 1 | Who it is for | [The person, at the moment they open it] | [What is waiting for them, in their words] | [/the-first-page/] | The app’s own |
| 2 | The moment it matters | [The one idea that sets it apart] | [What changes, with the demo’s own invented figure] | [/where-it-happens/] | The app’s own |
| 3 | How it pays | [The part that makes the business money] | [What the business sees because of it] | [/where-the-money-is/] | The app’s own |
| 4 | The proof | [The claim only this product makes] | [The screen that shows it is true] | [/the-proof/] | The app’s own |
| 5 | Another view | [The same thing on a phone] | [Why that matters to them, away from a desk] | [/the-first-page/] | phone |

Each step also has an `id`, a short name in lower case such as `briefing`, and the `app` it is seen in. A demo with one app names the same one every time. A step can point at one part of its page (`point`), and on a live app it can run calls first (`run`); both are optional.

The same five steps, as they go into `pitch.json`:

```json
"story": [
  {
    "id": "who",
    "title": "[The person, at the moment they open it]",
    "say": "[What is waiting for them, in their words]",
    "app": "[your app's id]",
    "path": "/the-first-page/"
  },
  {
    "id": "moment",
    "title": "[The one idea that sets it apart]",
    "say": "[What changes, with the demo's own invented figure]",
    "app": "[your app's id]",
    "path": "/where-it-happens/"
  },
  {
    "id": "pays",
    "title": "[The part that makes the business money]",
    "say": "[What the business sees because of it]",
    "app": "[your app's id]",
    "path": "/where-the-money-is/"
  },
  {
    "id": "proof",
    "title": "[The claim only this product makes]",
    "say": "[The screen that shows it is true]",
    "app": "[your app's id]",
    "path": "/the-proof/"
  },
  {
    "id": "phone",
    "title": "[The same thing on a phone]",
    "say": "[Why that matters to them, away from a desk]",
    "app": "[your app's id]",
    "path": "/the-first-page/",
    "device": "phone"
  }
]
```

The five steps, in the order a viewer meets them:

1. **Who it is for** — the viewer meets someone like them, at the moment the product opens.
2. **The moment it matters** — the one idea that sets the product apart, shown happening.
3. **How it pays** — the part of the product that makes the business money.
4. **The proof** — the claim only this product makes, on the screen that shows it.
5. **Another view** — the same product on a phone, or in a second person’s hands.

## A worked example: Columbus

Columbus is the invented demo our own docs use. It is a private-markets introduction service. On one side is a register of family offices, which it calls houses, and on the other a catalogue of deals. Between them is a suitability score, with its reasons written out. Every house, deal and figure in it is invented. It is a static build, so no step runs anything.

| Step | Its job | `title` | What `say` asks the viewer to notice | `path` | `device` |
|---|---|---|---|---|---|
| 1 | Who it is for | What needs the house today | An invented family office opens on what is waiting for it, and what closes soonest | `/` | The app’s own |
| 2 | The moment it matters | A score with its reasons | One deal scored against the house’s own mandate, every axis with its reason, and the one that binds named | `/transactions/kestrel/overview/` | The app’s own |
| 3 | How it pays | A seat at the table | Several houses sharing one round, and what this house would hold | `/transactions/anvil/structure/` | The app’s own |
| 4 | The proof | The score, held to account | The score given on the day the house committed, beside what happened since | `/portfolio/thornbury/overview/` | The app’s own |
| 5 | Another view | The same briefing on a phone | The first page again, folded to fit a phone, for reading between meetings | `/` | phone |

Here is the story as it stands in Columbus’s `pitch.json`. Every figure in it is one the demo’s own pages show.

```json
"apps": [{ "id": "columbus", "name": "Columbus", "path": "/", "device": "laptop" }],
"story": [
  {
    "id": "briefing",
    "title": "What needs the house today",
    "say": "Arundel House, an invented family office, opens Columbus on a concierge rather than a feed: two things are waiting on them, one closes in four days, and nothing else needs them today.",
    "app": "columbus",
    "path": "/"
  },
  {
    "id": "score",
    "title": "A score with its reasons",
    "say": "Project Kestrel scores 74 against the house's own mandate. Each of the eight axes gives its reason, and the binding one is named: a 10–12% target sits below the house's 12–18% floor.",
    "app": "columbus",
    "path": "/transactions/kestrel/overview/"
  },
  {
    "id": "table",
    "title": "A seat at the table",
    "say": "Four family offices take Project Anvil's £40m round between them. Arundel House's seat is £12.0m, and the cap table shows what it would hold: 7.4% fully diluted.",
    "app": "columbus",
    "path": "/transactions/anvil/structure/"
  },
  {
    "id": "audited",
    "title": "The score, held to account",
    "say": "Columbus keeps the score it gave on the day the house committed, and sets it beside what happened: Thornbury scored 91 at entry and has returned 2.00× since. Old scores are never revised.",
    "app": "columbus",
    "path": "/portfolio/thornbury/overview/"
  },
  {
    "id": "phone",
    "title": "The same briefing on a phone",
    "say": "On a phone the navigation folds into a drawer and tables become cards, so a principal can read what is waiting on them between meetings.",
    "app": "columbus",
    "path": "/",
    "device": "phone"
  }
]
```

Why it is written the way it is:

- **One app, five pages.** Columbus is one product, so the room shows one app. Each step opens the page it talks about, and the viewer can click on from there.
- **Every step stands on its own.** Each step names its page, so a viewer who jumps to step three sees what the step describes, wherever they had clicked before.
- **The phone is a frame, not an app.** The last step is the first page again, drawn at a phone’s size. When the viewer moves on, the laptop comes back.
- **The words are about the business, not the room.** Every line is about Arundel House and its deals, never about buttons.
- **No `point`.** Columbus’s code names nothing stable on these pages to ring, so the steps leave it out rather than guess.

## How do you write each step?

Give each step one idea, and write its words for the viewer, not for yourself. Name the screen the step is about, so it opens there whatever the viewer clicked before. Point only at something the demo’s code names. And make every step stand on its own, because a viewer can start at any of them.

- **One idea a step.** If a title needs “and”, it is two steps.
- **Write `say` for the viewer.** What to notice and why it matters, in the product’s words, with figures the screen itself shows. Nothing about the room or its buttons.
- **Name the screen.** Give every step a `path`, so it opens at its page. Without one, the app is shown wherever the viewer left it.
- **Point at something stable.** An id or a `data-` attribute the demo’s own code names, on the page the step opens. Never a generated class name. Leave `point` out rather than guess.
- **Set up the step’s own state.** On a live app, a step can make calls on the viewer’s copy before it shows, such as setting the demo’s clock and playing a scenario. Then it works even for a viewer who jumps straight to it. [Container demos](https://getroomi.com/docs/containers) has a worked example.
- **One app per product.** A phone is a frame, not a second app: give the step `"device": "phone"`. A separate app is a separate surface, such as a coach’s tablet beside a client’s phone.

## How do you turn the script into a tour?

Ask Claude to add the tour when it deploys the demo, or paste the steps into `story` in `pitch.json` yourself. Then check it: `roomi validate` reads the story without building anything, and `roomi deploy` rehearses it before anything goes live. Nothing is published until you say yes to what the rehearsal shows.

1. **From Claude.** In the chat where you built the demo, ask Claude to deploy it to Roomi with a tour. It drafts the story from the demo’s screens and shows it to you first. [Deploying from Claude](https://getroomi.com/docs/claude) covers the connector.
2. **From a coding agent.** `roomi init` leaves `PITCH.md` in the project, which tells Claude Code, Cursor or any other agent how to write the tour. Give it this template and ask it to fill in the story.
3. **By hand.** Paste the template into `pitch.json`, replace every bracket, and run `roomi validate`. Each problem it finds names the field and the docs entry that explains it.
4. **Rehearse.** `roomi deploy` checks that every step’s page is in the build. On a live app it runs every step’s calls on a copy and prints `ok` or `FAIL` for each.
5. **Take the tour yourself.** `roomi dev` serves the real room around your demo on your own machine, and nothing in it is recorded or sent.
6. **Publish.** `roomi deploy --commit` puts it live, exactly as rehearsed.

When you send each person their link, tell them who you are and how to reach you about their data. Say that the room records what they do there and shows it to you. The [terms](https://getroomi.com/terms) ask every publisher to say so. [The follow-up email templates](https://getroomi.com/guides/follow-up-email-after-sending-a-demo) include the email that sends the link.

Write the first step tonight: who it is for, at the moment they open it. The rest of the tour follows from that. [Pricing](https://getroomi.com/pricing) has what each plan includes.

## Questions people ask

### Can Claude write the tour for me?

Yes. Ask Claude to deploy the demo with a tour, and it drafts the steps from the demo’s own screens and shows them to you before anything is published. Change any line you like, then say yes.

### What if a viewer goes off the script?

Nothing breaks. They can leave the tour at any point to explore the demo on their own, and start it again at any step from the room’s outline.

### Can a step change what the demo shows?

On a live app, yes. A step can run the demo’s own scenarios on that viewer’s copy before it shows, so the screen is in the right state. A static demo’s steps open pages and point at things.

### How do I know where people stop?

On Pro and up, the Analytics screen shows how many people reached each step, in order, and how many finished the tour or left it to explore. Each viewer’s journey says how far they took it.

### Can I change the script after sending?

Yes. Edit the story and deploy again. Everyone opening a link gets the new tour from their next page load, and nobody’s link changes.

## About the author

**[Kaz Kato](https://getroomi.com/about)**, Co-founder & CTO, Roomi. Kaz co-founded Roomi with Tesh, whom he has built with since 2017: two startups that failed, one venture studio that didn’t, and an exit.

## Related guides

- [How do you send a working demo instead of a pitch deck?](https://getroomi.com/guides/how-to-send-a-demo-instead-of-a-deck)

- [How do you pitch an idea to a client?](https://getroomi.com/guides/how-to-pitch-an-idea-to-a-client)

- [What should your follow-up email say after you send a demo? Templates](https://getroomi.com/guides/follow-up-email-after-sending-a-demo)
