The Template Builder scripting API provides a TypeScript-based interface for controlling and customizing the behavior of graphics templates within Viz Pilot Edge. Scripts are authored in the Monaco editor inside Template Builder, and execute at runtime in Viz Pilot Edge when users interact with templates.

Scripts have access to the template's payload fields, MOS metadata, life cycle events, view management, MSE playout control, etc, all through a set of globally available objects and functions documented below.

Global Objects

vizrt

The primary global object for interacting with the scripting API. Provides access to template fields, environment variables, Pilot metadata, MOS data, views, life cycle callbacks and spell check.

declare const vizrt: {
readonly $env: Partial<Readonly<Record<string, string>>>
readonly $pilot: PilotData
readonly $data: Partial<Record<string, string>>
readonly fields: Payload
readonly views: readonly View[]
onViewActivated: undefined | ViewActivatedCallback
onCreate: undefined | (() => void)
onLoad: undefined | (() => void)
onClick: undefined | ((name: string) => void)
onUpdate: undefined | ((fields: Payload, action: string) => void | Promise<void>)
onAfterSave: undefined | (() => void)
onBeforeSave: undefined | (() => boolean | Promise<boolean>)
readonly spellCheck: (languageCode?: string, fields?: readonly string[]) => Promise<boolean>
/** @deprecated Use `app.jumpToPreviewPoint` instead. */
readonly jumpToPreviewPoint: (name: string) => void
}

Property

Type

Description

$env

Partial<Readonly<Record<string, string>>>

Read-only access to environment variables defined for the template.

$pilot

PilotData

Read-only access to Pilot metadata including MOS data, Viz Mosart configuration, and element info.

$data

Partial<Record<string, string>>

Temporary key-value data store, accessible from dynamic drop-down editors.

fields

Payload

The template's payload fields. The Payload type is generated per model and provides strongly-typed access to every field defined in the template.

views

readonly View[]

Array of views (tabs) defined in the template model. Excludes the "All" tab which is a UI-only concept.

app

Global object providing access to application-level commands such as UI notifications, MSE connections and preview navigation.

declare const app: {
readonly notify: (severity: "warning" | "info" | "error" | "success", message: string) => void
readonly createMseConnection: (url: string) => MseConnection
readonly jumpToFieldPreview: (path: string) => void
readonly jumpToPreviewPoint: (name: string) => void
}

Method

Description

notify(severity, message)

Displays a notification toast in the UI with the given severity level and message text.

createMseConnection(url)

Creates a connection to a Media Sequencer Engine (MSE) at the specified REST URL. Returns an MseConnection object for playout control.

jumpToFieldPreview(path)

Navigates the graphics preview to the field identified by the given path.

jumpToPreviewPoint(name)

Navigates the graphics preview to a named preview point.

Callbacks

Life cycle callbacks allow scripts to respond to events in the template life cycle. Assign a function to the corresponding property on the vizrt object to register a handler.

vizrt.onCreate

Called when a template is opened in Viz Pilot Edge, which creates a new Data Element. Typically used to initialize default values for fields.

  • Not triggered when creating a Data Element from an existing one (for example, duplicate).

  • Not triggered from Template Builder.

vizrt.onCreate = () => {
vizrt.fields.$headline.value = "Default Headline"
}

vizrt.onLoad

Called when an existing data element is opened in Viz Pilot Edge. This event also fires in browse mode when a data element is selected. Use this event to prepare the MOS XML that is sent to the newsroom, which is relevant when data elements are sent directly from browse mode.

  • Not triggered from Template Builder.

vizrt.onLoad = () => {
if (!vizrt.fields.$headline.value) {
vizrt.fields.$headline.value = "Fallback"
}
}

vizrt.onUpdate

This event is invoked by the Script Runner when the template is configured to use the Update Service. Note that this handler executes in a Node.js server process and, therefore, may expose a different JavaScript API. See Update Service for more details.

  • Not triggered from Template Builder or Viz Pilot Edge.

vizrt.onUpdate = async (fields: Payload, action: string) => {
fields.headline.value = "Updated by automation"
}

vizrt.onBeforeSave

Called before a save operation. Return false (or a Promise<false>) to cancel the save, return true to proceed.

vizrt.onBeforeSave = () => {
if (!vizrt.fields.$headline.value) {
app.notify("error", "Headline is required")
return false
}
return true
}

vizrt.onAfterSave

Called after a save operation of the currently open Data Element has completed successfully.

vizrt.onAfterSave = () => {
app.notify("success", "Element saved")
}

vizrt.onClick

Called when a click event is triggered from an HTML fragment UI. The name parameter corresponds to the vizrt-click-name attribute of the clicked element.

vizrt.onClick = (name: string) => {
if (name === "reset-button") {
vizrt.fields.$headline.value = ""
}
}

vizrt.onViewActivated

Called when the active view (tab) changes in the UI. Receives the index of the newly selected view and the previously selected view. An index of undefined means the "All" tab is selected.

vizrt.onViewActivated = (selected, old) => {
if (selected !== undefined) {
console.info(`Switched to view: ${vizrt.views[selected].title}`)
}
}

Payload & Fields

Payload (Generated Interface)

The Payload type is generated at design time based on the template's VDF model. Each field defined in the model becomes a strongly-typed property on the Payload interface. The actual shape depends on the template.

Note: All field names in the generated Payload interface are prefixed with $ (for example, $headline, $body). This naming convention is applied automatically during type generation and distinguishes payload fields from built-in properties.

Access fields through vizrt.fields:

// Read a field value
const title = vizrt.fields.$headline.value
 
// Write a field value
vizrt.fields.$headline.value = "Breaking News"
 
// Access a nested field
vizrt.fields.$settings.$color.$value = "#FF0000"
 
// Listen for external changes to a field
vizrt.fields.$headline.onChanged = newValue => {
console.info("Headline changed to:", newValue)
}

Field Types

EmptyField

The base interface for all VDF fields. Represents a field with no value and no list, only behavioral properties.

Info: If hidden, readOnly, or tip is undefined at the script level, the value is inherited from the field definition in the model, and further from the parent field.

interface EmptyField {
/** Controls the visibility of the field. Inherited from parent and field definition. */
hidden: boolean
/** Controls whether the field is read-only. Inherited from parent and field definition. */
readOnly: boolean
/** The tooltip text for the field. Inherited from the field definition. */
tip: string
/** An error message to display on the field. Not inherited. */
error: string
/** The decoration object controlling display properties. */
decoration: BaseDecoration
}

ScalarField<T>

Extends EmptyField with a typed value (this is the most commonly used field type). T corresponds to the field's media type (for example, string, number, boolean, RichText, ImageAsset, etc.).

interface ScalarField<T> extends EmptyField {
/** Read/write access to the field value. */
value: T
/** Handler invoked when the value is changed from outside the script (e.g., by the user in the UI). */
onChanged?: (value: T) => void
/** Read-only access to the field's metadata key-value pairs defined in the model. */
readonly metadata: Readonly<Map<string, string>> | undefined
}

TextScalarField<T>

Extends ScalarField<T> with text-specific decoration support. Used for single-line text, multi-line text and rich text fields.

interface TextScalarField<T = string> extends ScalarField<T> {
/** Text-specific decoration with properties like maxlength. */
decoration: TextDecoration
}

VdfList<Columns>

Represents a list field containing rows of typed column values. The list is read-only (you cannot add or remove rows from script), but individual cell values can be modified.

type VdfList<Columns extends object> = ReadonlyArray<{
[Col in keyof Columns]: VdfListItem<Columns[Col]>
}>

Iterating a list example:

for (const row of vizrt.fields.$items) {
console.info(row.label.value)
}

VdfListItem<T>

A mapped type that extracts the scriptable properties from a field type when used inside a list. For fields extending EmptyField, only properties starting with $ and the value property are preserved.

type VdfListItem<T> = T extends EmptyField ? { [K in Extract<keyof T, `$${string}` | "value">]: VdfListItem<T[K]> } : T

Decoration Types

Decorations allow scripts to control the display properties of fields dynamically.

BaseDecoration

Base decoration available on all field types.

interface BaseDecoration {
/** Display label for the field in the UI. */
label?: string
}

Example:

vizrt.fields.$headline.decoration.label = "Main Title"

TextDecoration

Extended decoration for text fields, adding text-specific constraints.

interface TextDecoration extends BaseDecoration {
/** Maximum number of characters allowed in the text field. */
maxlength?: number
}

Example:

vizrt.fields.headline.decoration.maxlength = 50

Value Types

RichText

Represents formatted text content. RichText objects are immutable and must be created using the createRichText factory function.

interface RichText {
/** The text content without any formatting (plain text representation). */
readonly plainText: string
}

MediaAsset

Base interface for all media asset values. Contains common metadata shared by image and video assets.

interface MediaAsset {
/** The type of the media: `"image"` or `"video"`. */
readonly mediaType: MediaType
/** The display title of the asset. */
readonly title: string | undefined
/** Timestamp of the last update to the asset. */
readonly updated: Readonly<Date> | undefined
/** URL to a thumbnail representation of the asset. */
readonly thumbnailUrl?: string | undefined
/** The path to the media resource. */
readonly path: string
}

ImageAsset

Stores information about an image asset. Extends MediaAsset with dimensional metadata.

interface ImageAsset extends MediaAsset {
/** The width of the image in pixels, if available. */
readonly width: number | undefined
/** The height of the image in pixels, if available. */
readonly height: number | undefined
}

VideoAsset

Stores information about a video asset. Extends MediaAsset with dimensional and duration metadata.

interface VideoAsset extends MediaAsset {
/** The width of video frames in pixels, if available. */
readonly width: number | undefined
/** The height of video frames in pixels, if available. */
readonly height: number | undefined
/** The duration of the video in seconds, if available. */
readonly duration: number | undefined
}

Duplet

Represents a two-dimensional value (media type "application/vnd.vizrt.duplet"). The object is immutable.

class Duplet {
/** The x-value of the duplet. */
x: number
/** The y-value of the duplet. */
y: number
constructor(x: number, y: number)
}

Triplet

Represents a three-dimensional value (media type "application/vnd.vizrt.triplet"). The object is immutable.

class Triplet {
/** The x-value of the triplet. */
x: number
/** The y-value of the triplet. */
y: number
/** The z-value of the triplet. */
z: number
constructor(x: number, y: number, z: number)
}

VizMap

Represents a Viz Engine map value (media type "application/vnd.vizrt.curious.map"). Contains data in a |||-delimited envelope format (for example, Protocol=1|||XML=...|||). The object is immutable.

class VizMap {
/** The raw `|||`-delimited map string. */
readonly mapString: string
constructor(mapString: string)
}

MediaType

Union type for the supported media asset categories.

type MediaType = "image" | "video"

View Management

Views represent tabs in the payload editor UI. They are defined in the template model and allow organizing fields into logical groups.

View

Represents a single view/tab. Scripts can read the active state, activate a view programmatically, change the display title and inspect contained items.

interface View {
/** Whether this view is currently the active/selected tab. */
readonly isActive: boolean
/** Activates this view, switching the UI to display this tab. */
readonly activate: () => void
/**
* A decorative title that can be set by scripts for display purposes.
* Does not affect the underlying model. Resets to the model default on session reload.
*/
title: string
/** The items contained in this view. */
readonly items: readonly ViewItem[]
}

Switching views example:

// Activate the second view
vizrt.views[1].activate()
 
// Rename a view tab
vizrt.views[0].title = "General Settings"

ViewItem

A union type representing any item within a view. Either a field item or a UI item (fragment/iframe).

type ViewItem = FieldViewItem | UiViewItem

FieldViewItem

A field item placed within a view, identified by its field path.

interface FieldViewItem extends BaseViewItem {
readonly type: "field-item"
/** The field path identifying this item within the payload. */
readonly path: string
}

UiViewItem

A UI item (HTML fragment or iframe) placed within a view, identified by its name.

interface UiViewItem extends BaseViewItem {
readonly type: "ui-item"
/** The name identifying this UI item. */
readonly name: string
}

BaseViewItem

Base interface for all view items, providing position management within the view's grid layout.

interface BaseViewItem {
/** The current grid position and dimensions of this item. */
readonly position: Rect
/**
* Updates the position of this item. Accepts a partial `Rect` — provided
* properties are merged with the existing position.
*/
readonly setPosition: (position: Partial<Rect>) => void
/** The discriminator for the item type. */
readonly type: "field-item" | "ui-item"
/** The field path (only set for field items). */
readonly path?: string
/** The UI item name (only set for UI items). */
readonly name?: string
/** Whether the view item is hidden or not in the view
*
* **Note**: Field's hidden expression evaluation overrides this value
**/
hidden?: boolean
}

Rect

Defines a rectangle within the view's 2D grid layout system. All values are in grid units.

type Rect = {
/** The x-coordinate (column) of this rectangle. */
readonly x: number
/** The y-coordinate (row) of this rectangle. */
readonly y: number
/** The width of this rectangle in grid columns. */
readonly width: number
/** The height of this rectangle in grid rows. */
readonly height: number
}

Repositioning a field and a UI component in a view example:

const items = vizrt.views[0].items
const headlineItem = items.find(item => item.type === "field-item" && item.path === "headline")
headlineItem?.setPosition({ x: 0, y: 0, width: 12, height: 2 })
 
const myFragment = items.find(item => item.type === "ui-item" && item.name === "fragment")
myFragment?.setPosition({ x: 6, y: 0, width: 5, height: 14 })

Pilot Data

PilotData

Provides read-only access to Pilot-specific metadata associated with the current template, including MOS data, Viz Mosart configuration, and Data Element information.

type PilotData = {
/** Read-only Mosart configuration defaults. */
readonly mosartConfig?: MosartConfig
/** Mosart timing panel state, editable by scripts. */
readonly mosartTimingPanel?: MosartTimingPanel
/** MOS item data — description, slug, abstract, timing, and MEM blocks. */
readonly mos: MOS
/** Information about the current Data Element, if available. */
readonly element?: PilotElementInfo
}

PilotElementInfo

Contains identification information for the current Data Element.

type PilotElementInfo = {
/** The unique identifier of the Data Element. */
readonly elementId?: string
}

MOS & MEM

MOS

Provides read/write access to MOS (Media Object Server) item fields (the standard metadata associated with newsroom items). Also provides access to MEM blocks and Viz Mosart timing values.

type MOS = {
/** Mosart timing values (playout channel, timing, in/out modes). */
mosart?: MosartTimingValues
/** Continue count for Mosart playout automation. */
continueCount?: number
/** The MOS item description. */
description?: string
/** The MOS item abstract. */
abstract?: string
/** The MOS item slug. */
slug?: string
/** Access to MOS External Metadata (MEM) blocks. */
readonly mem: MEMAccess
}

Setting MOS metadata example:

vizrt.$pilot.mos.description = "Election results lower third"
vizrt.$pilot.mos.slug = "ELECTION-2026"

MEMAccess

Provides CRUD operations for MOS External Metadata (MEM) blocks. MEM blocks are XML fragments stored within MOS items, each identified by a unique schema URL.

type MEMAccess = {
/** Retrieves a MEM block by its schema URL, or `undefined` if not found. */
readonly get: (schema: string) => MEMBlock | undefined
/** Creates or updates a MEM block. */
readonly set: (block: MEMBlock) => void
/** Removes a MEM block by its schema URL. */
readonly delete: (schema: string) => void
}

Managing MEM blocks example:

// Set a custom MEM block
vizrt.$pilot.mos.mem.set({
schema: "http://example.com/schemas/custom-metadata",
payload: "<metadata><key>value</key></metadata>",
scope: "OBJECT",
})
 
// Read a MEM block
const block = vizrt.$pilot.mos.mem.get("http://example.com/schemas/custom-metadata")
if (block) {
console.info("MEM payload:", block.payload)
}
 
// Remove a MEM block
vizrt.$pilot.mos.mem.delete("http://example.com/schemas/custom-metadata")

MEMBlock

Represents a single MOS External Metadata block.

type MEMBlock = {
/** The schema URL uniquely identifying this MEM block type. */
readonly schema: string
/** The XML payload content of the MEM block. */
readonly payload: string
/** The scope of the MEM block, determining its visibility and lifecycle. */
readonly scope: "PLAYLIST" | "STORY" | "OBJECT"
}

Scope

Description

"PLAYLIST"

The MEM block is scoped to the entire playlist.

"STORY"

The MEM block is scoped to the current story.

"OBJECT"

The MEM block is scoped to the individual MOS object.

MosartTimingValues

Defines the Viz Mosart playout timing configuration for a template. These values control how the graphics element is triggered and removed during broadcast automation.

type MosartTimingValues = {
/** The playout channel name. */
channel: string
/** The start time for playout. */
start: string
/** The duration of playout. */
duration: string
/** The in-transition mode. */
inMode: InMode
/** The out-transition mode. */
outMode: OutMode
/** Whether this element is used as a locator graphic. */
isLocator: boolean
}

MosartConfig

Read-only Viz Mosart configuration defaults for the template. These values are set by the system and cannot be modified by scripts.

type MosartConfig = {
/** Whether the Mosart timing panel should be displayed. */
readonly showTimingPanel: boolean
/** The default playout destination channels. */
readonly destinations: readonly string[]
/** Whether the "is Locator" checkbox should be shown by default in the timing panel. */
readonly showIsLocator: boolean
}

MosartTimingPanel

The editable state of the Viz Mosart timing panel for the current template. Scripts can control which options are available and the panel's default expanded state.

type MosartTimingPanel = {
/** The playout destinations available for this template. */
destinations: readonly string[]
/** Whether to display the "is Locator" checkbox. */
showIsLocator: boolean
/** Whether to display the "Continue Count" option. */
showContinueCount: boolean
/** Whether the timing panel is expanded by default. Defaults to `true`. */
expanded: boolean
}

InMode

The in-transition mode for Viz Mosart playout automation.

type InMode = "auto" | "manual"

Value

Description

"auto"

The graphic is taken on-air automatically by the automation system.

"manual"

The graphic requires manual triggering by an operator.

OutMode

The out-transition mode for Vi Mosart playout automation.

type OutMode = "auto" | "story-end" | "background-end" | "open-end"

Value

Description

"auto"

The graphic is taken off-air automatically after its duration.

"story-end"

The graphic remains on-air until the current story ends.

"background-end"

The graphic remains on-air until the background element ends.

"open-end"

The graphic remains on-air indefinitely until manually removed.

MSE Connection & Playout

MseConnection

Provides methods for controlling graphics playout through a Media Sequencer Engine (MSE). Create an instance using app.createMseConnection(url).

type MseConnection = {
sendVizCommand: (target: PlayoutTarget<undefined>, ...commands: readonly string[]) => void
take: (target: PlayoutTarget<VizLayer>) => void
update: (target: PlayoutTarget<VizLayer>) => void
continue: (target: PlayoutTarget<VizLayer | string>) => void
out: (target: PlayoutTarget<VizLayer | string>) => void
checkConnection: () => Promise<boolean>
}

Method

Description

sendVizCommand(target, ...commands)

Sends one or more raw Viz Engine commands through the MSE. The layer property on the target is not used.

take(target)

Executes a take command, bringing the graphic on-air on the specified target and layer.

update(target)

Executes an update command, refreshing the on-air graphic with current field values.

continue(target)

Executes a continue command, advancing the graphic to its next animation state.

out(target)

Executes an out command, removing the graphic from air on the specified target.

checkConnection()

Returns a Promise<boolean> indicating whether the MSE connection is valid.

Playout workflow example:

const mse = app.createMseConnection("http://mse-host:8580")
 
const target = { profile: "STUDIO_A", channel: "GFX", layer: "MAIN" as const }
 
// Check connection first
const connected = await mse.checkConnection()
if (connected) {
mse.take(target)
}

PlayoutTarget<Layer>

Identifies the MSE profile, channel and optional Viz Engine layer for a playout operation.

type PlayoutTarget<Layer> = {
/** The MSE profile name. */
readonly profile: string
/** The MSE channel name within the profile. */
readonly channel: string
/** The Viz Engine layer to target. Defaults to `"MAIN"` if omitted. */
readonly layer?: Layer
}

VizLayer

The available Viz Engine rendering layers.

type VizLayer = "MAIN" | "FRONT" | "BACK"

Layer

Description

"MAIN"

The primary rendering layer for the main graphics scene.

"FRONT"

The front layer, rendered on top of the main layer.

"BACK"

The back layer, rendered behind the main layer.

Factory Functions

createRichText

Creates an immutable RichText object from a plain text string.

declare function createRichText(plainText: string, escape?: boolean): RichText

Parameter

Type

Default

Description

plainText

string

The plain text content.

escape

boolean

true

When true, escapes HTML characters (<, >) so they display literally. Set to false if the text is already properly formatted.

Example:

vizrt.fields.$body.value = createRichText("Breaking news: <important>")
// The "<important>" text is escaped and displayed literally

Formatted Text fields can be assigned by creating an object of type RichText in the method createRichText:

vizrt.fields.$name.onChanged = value => {
vizrt.fields["$01-richtext"].value = createRichText(
`<fo:wrapper bold="false" italic="false" underline="false">Hello </fo:wrapper>` +
`<fo:wrapper bold="true" italic="true" underline="true">${value}!</fo:wrapper>`, false)
}

Info: The second argument to the method is set to false. This ensures the formatted text is sent to the Viz Engine unescaped. If set to true, the text is escaped, but the formatting is lost.

false: When the actual RichText XML should be sent to the Viz Engine.
true: When the text does not contain RichText, but contains characters that require escaping, such as < and >.

createImageAsset

Creates an ImageAsset object that can be assigned to Image fields.

declare function createImageAsset(image: string, title?: string): ImageAsset

Parameter

Type

Description

image

string

External URL, Graphic Hub image path or UUID.

title

string

Optional display title. Not required for Graphic Hub images.

Example:

vizrt.fields.$insta.$image2.value = createImageAsset("IMAGE*&lt;520E0100-56BD-5C4D-884D-5598ACFD75A4&gt;")
vizrt.fields.$insta.$image2.value = createImageAsset("IMAGE*01_GLOBALS/IMAGE/logo_wide")
vizrt.fields.$insta.$image2.value = createImageAsset("https://images.pexels.com/photos/169647/pexels-photo-169647.jpeg", "HEY")

createVideoAsset

Creates a VideoAsset from a local file path on the playout engine.

declare function createVideoAsset(video: string, title?: string): VideoAsset

Parameter

Type

Description

video

string

The file path to the video on the playout engine. Can be a full path or relative to the clip root on the Viz Engine.

title

string

Optional display title for the video.

Example:

vizrt.fields.$00Video.value = createVideoAsset("C:\\clips\\CVJPHFMXDHBGZFMF.mxf", "Title")
vizrt.fields.$00Video.value = createVideoAsset("opener.mxf", "Title")

createImageAssetFromXml

Creates an ImageAsset from a raw XML string containing an atom:entry representation of the image.

declare function createImageAssetFromXml(imageXml: string): ImageAsset

createVideoAssetFromXml

Creates a VideoAsset from a raw XML string containing an atom:entry representation of the video.

declare function createVideoAssetFromXml(videoXml: string): VideoAsset

Utility Functions

reportErrors

Catches and reports errors from callback or asynchronous functions to the UI. Use this to wrap catch handlers in promise chains so that exceptions are surfaced to the user rather than silently swallowed.

declare function reportErrors(f: () => void, stage: string): void

Parameter

Type

Description

f

() => void

A function to execute. Any exception thrown within it is reported to the UI.

stage

string

A descriptive label for the operation, shown in the error notification.

Example:

fetch("https://api.example.com/data")
.then(response => response.json())
.then(data => {
vizrt.fields.$headline.value = data.title
})
.catch(e =>
reportErrors(() => {
throw e
}, "fetch data"),
)

Spell Check

vizrt.spellCheck

Invokes the spell check dialog on text fields. The user can review and correct misspelled words interactively.

readonly spellCheck: (languageCode?: string, fields?: readonly string[]) => Promise<boolean>

Parameter

Type

Default

Description

languageCode

string

"en_US"

The dictionary language code (e.g., "en_US", "nb_NO"). If omitted, uses the vizrt-spellcheck-language environment variable, or defaults to "en_US".

fields

readonly string[]

all text fields

An array of field paths to check. If omitted, all applicable text fields are checked.

Returns Promise<boolean>, resolves to true if the spell check completed, or false if the user cancelled.

Example:

// Check all text fields in Norwegian
const completed = await vizrt.spellCheck("nb_NO")
 
// Check specific fields only
await vizrt.spellCheck("en_US", ["headline", "body"])