CHAT over NDI v1.0
Metadata Specification (v1.0)
Roberto Musso, December 2025
1. Purpose
This document defines a small XML metadata format to carry bidirectional text messages over NDI metadata streams.
Goals:
Provide a simple, interoperable chat channel between NDI endpoints (UIs, controllers, gateways).
Allow different devices/apps to map CHAT messages to their own UI (chat window, log panel, on-screen overlays, etc.).
Support multi-participant scenarios via explicit
sessionIdandsenderId.
This specification is intentionally minimal but extensible.
2. Design Overview
CHAT messages travel as NDI metadata frames whose root element is:
<ndi_metadata type="chat" version="1.0">...</ndi_metadata>Inside the root, each metadata frame carries one or more βchat sessionsβ, each containing one or more βmessagesβ.
High-level model:
<Session>A logical conversation or chat room (e.g. point-to-point, group, production channel).<Message>A single chat event (text message, status, system notification).
Typical example (single session, single message):
NDI endpoints decide how to interpret Session.id, SenderId, MessageType, etc., and how to render them in their UI.
3. Root Element
3.1 <ndi_metadata>
<ndi_metadata>Element name:
ndi_metadataAttributes:
type(required): MUST be"chat".version(optional): schema version. Current:"1.0".
Constraints:
Exactly one
<ndi_metadata>root element per NDI metadata frame.No XML prolog (
<?xml ... ?>) β the XML fragment is embedded directly in the NDI metadata payload.Implementations SHOULD ignore NDI metadata frames whose
typeis not"chat".
4. Session and Message Structure
4.1 <Session>
<Session>Represents a logical chat conversation.
Parent:
<ndi_metadata>Attributes:
id(required): identifier of the chat session.SHOULD be stable and unique within the senderβs or facilityβs context.
Recommended format: lower-case snake_case or similar (e.g.
session_production_A,session_replay_room,global_broadcast).
scope(optional): semantic scope of the session.point_to_pointβ one-to-one conversation (e.g. director β replay operator).groupβ multi-participant (e.g. βproduction teamβ).broadcastβ messages intended for anyone listening.
Implementations MAY define additional values.
Multiple <Session> elements MAY appear in one metadata frame to carry messages for separate conversations.
Example with two sessions:
4.2 <Message>
<Message>Represents a single chat event within a session.
Parent:
<Session>Children (standard elements):
<MessageId><SenderId><MessageType><Text><Lang><Format><Priority><InReplyTo>(optional)<TimestampUtc>
Order of child elements is not semantically significant, but examples use a consistent order for readability.
A single <Session> MAY contain multiple <Message> elements in one frame, for batching.
Example (session with two messages):
5. Standard Message Elements
This section defines the standard child elements of <Message>.
Unless otherwise stated, all elements are optional but recommended. Implementations SHOULD ignore unknown elements and treat missing optional elements with sensible defaults.
Standard elements:
<MessageId><SenderId><MessageType><Text><Lang><Format><Priority><InReplyTo><TimestampUtc><To>(optional destination hint)
Order of elements is not semantically significant.
5.1 <MessageId>
<MessageId>Logical identifier of the message.
Parent:
<Message>Type: string.
Usage: SHOULD be unique within the context of a session (
Session.id).Useful for de-duplication, threading, and acknowledgements.
Examples:
msg_0001d_20251206_00123replay_room_000045
If omitted, receivers MAY generate a local identifier, but SHOULD treat such messages as not safely referenceable (e.g. for threading).
5.2 <SenderId>
<SenderId>Identifier of the originator of the message.
Parent:
<Message>Type: string
Semantics:
Logical identity of the chat participant (UI, controller, device).
SHOULD be stable and unique within the chat domain (e.g. facility, production, or logical application domain).
Examples:
director_roomreplay_roomautomation_1studio_A_panel
Receivers can use SenderId to:
render distinct labels or colors,
tag messages by origin (for logs, filters),
enforce access control policies if desired.
If omitted, receivers MAY treat the message as anonymous.
5.3 <MessageType>
<MessageType>Type of the message.
Parent:
<Message>Type: string (enum)
Recommended baseline values:
textβ standard human-readable chat text.systemβ system notification (join/leave, warnings, status).typingβ typing indicator (user is composing).ackβ acknowledgement of another message (often used withInReplyTo).customβ application-specific type (requires extra semantics on top of).
Implementations:
SHOULD support at least
text.MAY define additional values as needed.
SHOULD NOT fail if encountering unknown values; instead, they MAY fall back to generic handling (e.g. render as standard text).
Examples:
If omitted, receivers MAY assume text as a default, but this is not required.
5.4 <Text>
<Text>Message content.
Parent:
<Message>Type: UTF-8 string
Semantics:
For
MessageType="text": the actual chat text.For
MessageType="system": human-readable system message (status, alerts).For other types: MAY be used as a human-friendly description; precise semantics are implementation-specific.
Implementations SHOULD support at least plain text rendering.
Example:
Size considerations
NDI metadata is not intended for very large payloads. Implementations SHOULD:
keep
<Text>reasonably short (typical chat messages),avoid using CHAT for large blobs or file transfer.
For large content, an out-of-band mechanism is recommended (e.g. URL or reference), with CHAT used to carry references plus short human-readable descriptions.
5.5 <Lang>
<Lang>Language of the message, if known.
Parent:
<Message>Type: string
Format: recommended BCP 47 language code, e.g.:
en,it,fren-US,pt-BR
If omitted, receivers MAY assume a default language or ignore language information entirely.
Example:
This field is primarily useful for:
multi-language environments,
filtering or UI adaptations based on language.
5.6 <Format>
<Format>Text formatting description.
Parent:
<Message>Type: string (enum)
Recommended values:
plainβ plain text, no markup.markdownβ Markdown or a constrained subset.htmlβ HTML snippet (use only in trusted environments).
If omitted, receivers SHOULD treat the text as plain.
Example:
Implementations that do not support rich text MAY:
ignore formatting hints,
render the content as plain text.
CHAT does not prescribe a specific Markdown or HTML subset; this is application-specific.
5.7 <Priority>
<Priority>Relative priority or urgency.
Parent:
<Message>Type: string (enum)
Recommended values:
lownormalhighcritical
Usage examples:
lowβ non-essential information, debug chatter.normalβ regular production chat.highβ attention-critical; UI may highlight or pin the message.criticalβ urgent; UI may trigger audible alerts or overlays.
Example:
If omitted, receivers SHOULD treat priority as normal.
Applications MAY map these values to their own severity or notification systems.
5.8 <InReplyTo>
<InReplyTo>Reference to another message.
Parent:
<Message>Type: string
Semantics:
Contains the
MessageIdof a previous message within the same session.Used to express:
simple reply threads,
acknowledgements (with
MessageType="ack"),correlations between command and response messages.
Example (acknowledgement):
Receivers MAY:
group messages by
InReplyTofor threaded display,use it for correlation in logs or automation,
ignore it if threading is not implemented.
If InReplyTo points to an unknown MessageId, the receiver SHOULD still accept the message but may not be able to render the full thread context.
5.9 <TimestampUtc>
<TimestampUtc>Timestamp of when the message was generated, in UTC.
Parent:
<Message>Type: string (ISO 8601 / RFC 3339)
Format:
YYYY-MM-DDThh:mm:ssZ, orYYYY-MM-DDThh:mm:ss.sssZfor millisecond precision.
Example:
Usage:
hOLA
Implementations SHOULD preserve TimestampUtc when re-emitting or relaying messages.
5.10 <To> (optional destination hint)
<To> (optional destination hint)Optional routing hint for intended recipient(s) within a session.
Parent:
<Message>Type: string
Semantics:
If
<To>is omitted, the message SHOULD be treated as broadcast to all participants in the session (Session.id).If
<To>is present, it identifies one or more intended recipients using the same logical ID space asSenderId.
Single-recipient example (unicast A β B):
Multi-recipient example (A β B and C):
Multiple recipients MAY be specified as a comma-separated list.
Implementations SHOULD trim whitespace around each ID when parsing.
Usage notes:
<To>is a hint that intermediaries (e.g. an NDI sender acting as a hub) or receivers MAY use to implement:unicast routing (only to a specific participant),
multicast routing (subset of participants),
or filtering logic at the receiver.
Applications that do not understand or use
<To>SHOULD ignore it and treat the message as broadcast.
In user-facing chat UIs, <To> is often derived from conventions in <Text> such as @recipient. Parsing such conventions is considered application logic and is out of scope for this specification.
6. Participant Identity & Multi-Endpoint Scenarios
In many NDI workflows:
A single NDI source can have multiple receivers (workstations, panels, automation, etc.).
Each receiver could send CHAT metadata back to the same source.
To keep semantics clear:
Session.ididentifies the conversation (logical room / channel).SenderIdidentifies the participant.
Recommended practices:
Stable participant IDs
Each UI or controller SHOULD use a stable SenderId (e.g. director_room, replay_room) instead of per-connection IDs.
Access control
Implementations MAY define policies:
Allow all
SenderIdfor a givenSession.id.Restrict write access to a subset of
SenderId.Treat some sessions as read-only or system-only.
Anonymous senders
If a system does not set SenderId, receivers MAY treat messages as anonymous and:
display a generic origin (
Unknown), orignore them in strictly controlled environments.
Unlike GPIO, CHAT typically does not require strict single-controller arbitration, so there is no required controllerId equivalent. However, implementations MAY combine SenderId with NDI connection information for additional policies if needed.
7. Typical Usage Patterns
7.1 Point-to-point chat (director β replay)
Use a dedicated
Session.id, e.g.session_director_replay.Both sides send
Messageelements within that session.Receivers display messages from all
SenderIdin that session.
Example:
7.2 Group chat (control room)
Session.id = "session_control_room",scope="group".Multiple participants (
SenderId) write to the same session.UI may visually distinguish participants by color or label.
7.3 System notifications
MessageType = "system".Used for join/leave notices, warnings, or status messages, possibly generated by automation rather than humans.
Example:
8. Extensibility & Vendor-Specific Fields
The core schema is intentionally small. Implementations MAY add extension elements or attributes, provided that:
Extensions do not break receivers that ignore unknown elements/attributes.
Core semantics (
Session,Message,Text,TimestampUtc, etc.) remain intact.
Examples of possible extensions:
Delivery status (e.g.
Delivered,Seen).Rich presence information (online/offline).
Additional routing hints (e.g. severity categories, channel mapping).
Recommended pattern:
Use extra child elements within
<Message>or<Session>.If needed, use XML namespaces or identifiable prefixes to avoid collisions.
9. Evolution
Senders SHOULD include a
versionattribute on<ndi_metadata>(e.g."1.0").Receivers SHOULD:
ignore unknown elements and attributes,
use sensible defaults for missing optional fields.
Future versions may:
add optional elements (delivery receipts, presence, attachments metadata),
refine recommended enums (
MessageType,Priority, etc.),define best practices for latency, batching, or message ordering.
Implementations SHOULD be written to be forward-compatible, especially regarding:
new
MessageTypevalues,new optional message fields,
additional
scopevalues for<Session>.
10. Summary
The CHAT over NDI metadata format defines:
A root
<ndi_metadata type="chat">element.A flexible hierarchy of:
<Session>(conversation container),<Message>(individual chat events).
Core message elements:
MessageId,SenderId,MessageType,Text,Lang,Format,Priority,InReplyTo,TimestampUtc.
On top of this neutral, NDI-friendly schema, endpoints are free to:
Render messages in chat windows, logs, or on-screen overlays.
Implement UI features like threading, acknowledgements, and priorities.
Evolve their internal behavior without changing the on-wire XML contract.
This approach keeps NDI metadata clean and protocol-agnostic, while enabling a simple, interoperable, bidirectional text messaging system across NDI-based workflows.
Last updated
Was this helpful?

