Teleprompter
The teleprompter feature turns your speaker screen into a scrolling script display — like the rigs used on TV news and professional broadcasts, but in any browser. A Notion-style block editor for writing the script, true-WPM pacing for natural delivery, karaoke-style highlighting for the live line, customizable cue indicators, section badges, top progress bar, manual scroll override, and 35+ display settings.
The teleprompter renders exclusively on the Speaker screen. It is never visible on Audience or Staff screens — your audience sees a clean presentation while the speaker reads the script on their confidence monitor. If multiple presenters need to see the teleprompter, generate a separate Speaker screen link for each one.
Quick Start
- Open the Teleprompter panel in the controller.
- Click Add teleprompter (or Upload .txt or .md to start from a file).
- Click the script title to open the editor and write your content.
- Pick a session from the dropdown — the teleprompter auto-attaches to that session's lifecycle.
- Start the session. The script begins scrolling on the speaker screen automatically.
The Notion-style Script Editor
The teleprompter editor is not a textarea — it's a block editor inspired by Notion. Each line is its own block; formatting lives inline within blocks; sections are first-class.
Slash menu (/)
Type / at the start of any line to open the insert menu:
| Block | Inserts | Notes |
|---|---|---|
| Heading | A larger title block | Use sparingly — one per major segment |
| Section | A `## Section · Name` marker that drives the section badge on the speaker view | Position, shape, and color of the badge are customizable |
| Quote | A blockquote, indented with a left border on the speaker view | Good for scripture, attributions, callouts |
| Divider | Horizontal rule between blocks | Visual separator — does not appear on the speaker view |
| List | Bulleted or numbered list | Each item is its own scrollable line |
Inline format toolbar
Select a run of text and the inline toolbar appears with:
| Format | Markdown | Shortcut |
|---|---|---|
| Bold | **text** | Cmd/Ctrl+B |
| Italic | *text* | Cmd/Ctrl+I |
| Underline | __text__ | Cmd/Ctrl+U |
| Strikethrough | ~~text~~ | — |
| Inline code | `text` | — |
| Color | {c:#hex}text{/c} | Picker |
| Highlight | {h:#hex}text{/h} | Picker |
| Highlight (default) | ==text== | — |
Storage is plain markdown so you can paste from Google Docs, Notion, or any modern editor and the formatting round-trips. Pasted near-black or near-white inline colors are filtered out automatically so foreign body text doesn't end up invisible on the dark speaker view.
Section markers
Sections drive the section badge that appears at the top of the speaker view as the speaker crosses into a new segment. The marker syntax:
## Section · Welcome
Friends, before we begin —
welcome to those joining us for the first time.
## Section · Reading
For God so loved the world…
You can write ## Section · Name, ## Welcome, or just ## Name — the editor parses heading-level markers and surfaces the label in the badge.
Per-line autosave
Every keystroke saves with a short debounce. Default behavior:
- Editing while paused: 500 ms debounce
- Editing while playing: 100 ms debounce (live edits land on the speaker view almost instantly)
Close the tab, kill the laptop, hand off to another operator — the script is on the server.
Upload a file
Two upload paths:
- Empty-state upload — when no teleprompters exist yet, the panel shows an Upload .txt or .md button. Picking a file creates a new teleprompter populated with the file contents and uses the filename (without extension) as the title.
- Per-card upload — each script card has an Upload Script action in its menu that replaces the script text with the file contents.
Supported formats: .txt, .md, .text. Maximum file size: 50 KB of text.
Linking to Sessions & Auto-Play
The teleprompter inherits the session's lifecycle, so you don't have to start it separately.
How attach + play works
- Pick a session in the script's session dropdown.
- The script is now attached to that session — visible in the panel header as a link icon on the card.
- When the session starts, the script's
is_visibleandis_playingboth flip to true. The speaker view shows the script and starts scrolling. - When the session pauses,
is_playingflips to false. The script stays visible but freezes mid-scroll — the speaker still sees their place. - When the session stops, both flags flip to false. The script panel hides and resets to position 0.
Pause keeps the script visible (frozen, not gone) so the speaker can still see their cue. Stop clears the panel completely and rewinds to the top. The Stop button on each TP card is available whenever the script is visible OR playing — so you can hide a stale playing-but-no-controller TP without un-attaching it.
Multiple teleprompters per event
Each session can carry its own teleprompter. As the rundown advances, the speaker view auto-switches to the next session's script — sermon notes, then worship lyrics, then announcements, in order. No manual cue required.
Plan limits
Free tier ships with one teleprompter per event. Limits scale with your plan tier:
- See Compare plans for current per-tier teleprompter quotas.
- When you hit the cap, the Add teleprompter button in the panel header swaps to an Upgrade for more pill that links to
/dashboard/billing.
Playback Controls
Per-card controls on the controller:
| Control | What it does |
|---|---|
| Play | Start scrolling from the current position. Sets is_visible + is_playing both true. |
| Pause | Freeze the script in place. Stays visible — speaker keeps their cue. |
| Stop | Hide the panel and reset to position 0. Available while the script is visible OR playing. |
| Reset Position | Rewind to position 0 without changing visibility or playing state. |
| Position scrubber | Drag the visual scrubber to manually jump to any line. Updates the speaker view in real time. |
| Pace (WPM) | Words per minute, 60–300. Default 120. Drives both `true_wpm` per-line pacing and `constant` lines/min pacing. |
Keyboard shortcuts
When the controller is focused:
| Action | Key |
|---|---|
| Play / Pause | Space |
| Scrub backward / forward | ← / → |
| Reset to top | 0 |
| Open slash menu (in editor) | / |
| Bold / Italic / Underline (in editor) | Cmd/Ctrl+B / I / U |
See the full list at Keyboard shortcuts.
Pacing Modes — true-WPM vs constant
Pacing controls how the per-line scroll duration is computed.
true_wpm (default, recommended)
Every line gets a dwell time proportional to its actual word count. A 12-word line dwells twice as long as a 6-word line at the same WPM setting. Headers and sparse lines fly by; dense paragraphs get the time they need.
duration_seconds = (line_word_count / pace_wpm) × 60
This is what professional teleprompters do. It's the default for all new teleprompters.
constant (legacy)
Every line gets the same duration regardless of length. This is the old behavior and is kept for users who built their pacing around it. Switch via Settings → Playback → Pacing mode.
If your speaker is rushing short lines and stalling on long ones, you're probably on constant. Switch to true_wpm and the cadence will track natural speech.
Speaker View — How It Renders
The speaker view is a vertically scrolling script with a fixed cue indicator marking the current reading line.
Line states
- Current line — full opacity, your chosen
current_line_color, with optional karaoke-style progress fill animating across it - Previous lines —
previous_line_color(default mid-grey), opacity fades by distance (1 line back: 70%, 2 lines: 40%, 3+: 20%) - Upcoming lines —
unread_line_color(default mid-grey), same opacity fade by distance
Font sizes scale responsively to the viewport.
Manual scroll override
Manual scroll is enabled by default. The speaker can flick the script with their finger or scroll wheel without un-pausing the timer. After a configurable resume delay (default 5 s of no input), the cue catches up and resumes auto-scroll from where the speaker left off.
To disable: Settings → Manual Scroll → Manual scroll enabled (off).
All Display Settings
Every teleprompter has its own settings. Open the gear icon on any card to see all 35+ options grouped into 5 tabs.
The settings modal footer has a Reset to defaults button on the left. Clicking it snaps every field back to the canonical defaults (listed below) without saving — review, then click Save changes to commit, or Cancel to discard.
Script tab
Editor pane for the script text itself plus title, notes, and labels. See The Notion-style Script Editor above.
Playback tab
| Setting | Options | Default |
|---|---|---|
| Pace (WPM) | 60–400 words per minute | 65 |
| Pacing mode | true_wpm | constant | true_wpm |
| Manual scroll enabled | On / Off | On |
| Manual scroll resume seconds | 1–30 seconds of inactivity before auto-scroll resumes | 5 |
Lines tab — typography & current-line styling
| Setting | Options | Default |
|---|---|---|
| Font family | Inter, Roboto, Lato, Open Sans, Montserrat, Source Sans, Arial, Georgia, Times, Courier, JetBrains Mono, Lexend | JetBrains Mono |
| Font size | 24, 28, 32, 36, 40, 48, 56, 64, 72, 80 px | 28 px |
| Text alignment | Left | Center | Right | Left |
| Letter spacing | 0–4 px | 0.25 px |
| Line height | 0.8–2.4 | 1 |
| Current line color | Any hex via picker | #FFFFFF (white) |
| Current line weight | 100–900 | 700 (bold) |
| Previous line color | Any hex | #8E8E8E (mid-grey) |
| Unread line color | Any hex | #8E8E8E (mid-grey) |
| Highlight scope | line | sentence | paragraph | line |
| Background color | Hex | none | None (transparent) |
| Background opacity | 0–1 | 0.6 |
| Border color | Hex | #444444 |
| Border thickness | 0–8 px (0 = no border) | 0 px |
| Padding around current line | 0–32 px | 12 px |
| Glow enabled | On / Off | Off |
| Glow color | Any hex | #FFFFFF |
| Karaoke / progress fill enabled | On / Off | On |
| Karaoke fill color | Any hex | #22C55E (green) |
| Karaoke fill direction | Left → right | Right → left | ltr |
Cue tab — the indicator that marks the current line
| Setting | Options | Default |
|---|---|---|
| Cue visible | On / Off | On |
| Cue shape | caret | bracket | arrow | dot | arrow |
| Cue color | Any hex | #FF0000 (red) |
| Cue position (horizontal) | Left | Center | Right | Left |
| Cue position (vertical) | Top | Middle | Bottom | Top |
| Cue thickness | 4–24 (relative scale) | 10 |
| Cue opacity | 0–1 | 0.85 |
| Cue drop shadow | On / Off | On |
Overlays tab — badge, top progress bar, chrome dim
| Setting | Options | Default |
|---|---|---|
| Section badge enabled | On / Off | On |
| Section badge color | Any hex | #F59E0B (amber) |
| Section badge text color | Any hex | #171717 (near-black) |
| Section badge shape | rounded | pill | square | outline | pill |
| Section badge position | Left | Center | Right | Left |
| Section badge full width | On / Off (banner across the top) | Off |
| Section badge drop shadow | On / Off | On |
| Section badge uppercase | On / Off | On |
| Top progress bar enabled | On / Off | On |
| Top progress bar height | 1–24 px | 10 px |
| Top progress bar color (start) | Any hex | #22C55E (green) |
| Top progress bar color (end) | Any hex | #EF4444 (red) |
| Top progress bar drop shadow | On / Off | Off |
| Show progress bar while active | On / Off | Off |
| Dim chrome while TP active | On / Off — fades the timer + session UI so the script gets focus | On |
Mirror Mode for Glass Teleprompters
Professional teleprompters use a sheet of glass angled in front of the camera. The speaker reads text reflected in the glass while looking directly at the audience (or camera). Because the glass reflects the image, the text needs to be mirrored horizontally so it reads correctly.
When generating the speaker screen link, set the Mirror option in Link Options:
| Mirror option | When to use it |
|---|---|
| None | Normal screen display — floor monitors, laptops, tablets |
| Horizontal | Glass teleprompter setups — text reads correctly through the reflective glass |
| Vertical | Ceiling-mounted or inverted screen installations |
| Both | Flip both horizontally and vertically (180° rotation) |
Hardware Controllers & API
Drive the teleprompter from external hardware via the public /v1/ REST API:
- Bitfocus Companion / Stream Deck — bind play / pause / scrub / jump-to-section to physical buttons
- vMix, OBS, QLab — fire HTTP requests on cue
- Custom scripts — every action is a single HTTP call
See the API documentation for the full endpoint list and authentication.
Multi-Device Sync
Every connected speaker view stays in lockstep. Open the same shared link on a confidence monitor, an iPad, and a laptop — they all show the same script, same cue position, same timing. Late-joining devices receive the full state on connect and catch up instantly.
This is the same multi-link sync architecture used by sessions and timers. See Live connections for the full sync model.
Multi-Script Management
Selection mode
Toggle selection mode in the panel header to show checkboxes on each card for bulk operations:
- Reset positions — Reset all selected scripts to 0%
- Delete — Delete all selected scripts
- Bulk relabel — Apply a label to every selected script
Status indicators
- Active count — header pill shows how many scripts are currently visible
- Card color — red background when playing, dark grey when paused or stopped
- Link icon — indicates the script is attached to a session
Stale detection
If a script is marked as playing but no position updates land for 10 seconds, a yellow warning appears on the speaker screen: "No controller connected." The Stop button on the card stays available so you can clear the stale state without un-attaching.
Auto-Pause on Messages
The teleprompter automatically pauses when you send a message to the speaker screen, so the announcement doesn't overlap with the script. Scrolling resumes when the message is dismissed.
How sync works under the hood
Live edits to script text use a short debounce to keep typing responsive. Scroll position broadcasts every 2% change to minimize network traffic without losing sync between viewers. Setting changes broadcast immediately and persist via the Animal Pattern (REST → broadcast → DB write with retry) so every connected client converges to the same state in under a second.