NDI adapters expose a managed source in Callaba as a named NDI device for downstream systems. Use this when the source arrives as SRT, RTMP, or a conference participant, but the receiving side needs NDI.
In production, this module solves a handoff problem: keep ingest and source control where they are, while publishing a stable NDI output for a switcher, graphics engine, multiviewer, or room workflow.
ndi_device_name that operators recognize.For recurring events, create adapters ahead of time and reuse the same device names. After startup, verify runtime health with process stats instead of relying on saved configuration alone.
Each preset below creates the same result: a discoverable NDI device backed by a different source type.
Use this when remote cameras or contribution feeds arrive over SRT, but the control room or graphics system expects NDI.
{
"restream_name": "Camera 1 to Cloud NDI via SRT",
"input": {
"input_type": "INPUT_TYPE_SRT_SOFTWARE",
"application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API",
"input_module_id": "66015d2997300f9385d32c00",
"input_stream_url": "",
"input_stream_listen_port": {},
"input_settings": {},
"input_stream_id": "",
"entity_name": "Camera 1 to Cloud NDI via SRT",
"module_name": "MODULE_RESTREAM"
},
"output": {
"output_type": "OUTPUT_TYPE_NDI_DEVICE",
"application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API",
"output_stream_url": "",
"output_stream_listen_port": {},
"output_settings": {
"ndi_device_name": "Cloud NDI Camera 1",
"timestamp_offset": 0,
"av_stream_control_mode": "AV_STREAM_CONTROL_VIDEO_AUDIO"
},
"output_stream_key": "",
"entity_name": "Camera 1 to Cloud NDI via SRT",
"module_name": "MODULE_RESTREAM"
},
"module_name": "MODULE_NDI_ADAPTERS",
"active": true
}
Use this when a venue, encoder, or cloud workflow publishes RTMP and the downstream production stack needs an NDI source with a fixed name.
{
"restream_name": "RTMP stage feed to Cloud NDI",
"input": {
"input_type": "INPUT_TYPE_RTMP_SOFTWARE",
"application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API",
"input_module_id": "66015d2997300f9385d32c10",
"input_stream_url": "",
"input_stream_listen_port": {},
"input_settings": {},
"input_stream_id": "",
"entity_name": "RTMP stage feed to Cloud NDI",
"module_name": "MODULE_RESTREAM"
},
"output": {
"output_type": "OUTPUT_TYPE_NDI_DEVICE",
"application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API",
"output_stream_url": "",
"output_stream_listen_port": {},
"output_settings": {
"ndi_device_name": "Cloud NDI Stage Feed",
"timestamp_offset": 0,
"av_stream_control_mode": "AV_STREAM_CONTROL_VIDEO_AUDIO"
},
"output_stream_key": "",
"entity_name": "RTMP stage feed to Cloud NDI",
"module_name": "MODULE_RESTREAM"
},
"module_name": "MODULE_NDI_ADAPTERS",
"active": true
}
Use this to expose a single speaker or guest from a conference as an NDI source for switching, recording, replay, or graphics.
{
"restream_name": "Speaker feed to Cloud NDI",
"input": {
"input_type": "INPUT_TYPE_MODULE_CONFERENCES_PARTICIPANT",
"application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API",
"input_module_id": "66015d2997300f9385d32c20",
"input_stream_url": "",
"input_stream_listen_port": {},
"input_settings": {},
"input_stream_id": "",
"entity_name": "Speaker feed to Cloud NDI",
"module_name": "MODULE_RESTREAM"
},
"output": {
"output_type": "OUTPUT_TYPE_NDI_DEVICE",
"application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API",
"output_stream_url": "",
"output_stream_listen_port": {},
"output_settings": {
"ndi_device_name": "Cloud NDI Speaker",
"timestamp_offset": 0,
"av_stream_control_mode": "AV_STREAM_CONTROL_VIDEO_AUDIO"
},
"output_stream_key": "",
"entity_name": "Speaker feed to Cloud NDI",
"module_name": "MODULE_RESTREAM"
},
"module_name": "MODULE_NDI_ADAPTERS",
"active": true
}
Keep SRT, RTMP, or conference ingest under centralized control and present the destination side as NDI. This is the common fit when engineering prefers managed contribution protocols but operators still work from NDI sources.
Set ndi_device_name to the label operators expect, such as Cloud NDI Camera 1 or Cloud NDI Speaker. Stable naming reduces source-selection mistakes during rehearsals, fast changes, and recurring shows.
A saved adapter does not guarantee a usable NDI output. Start it intentionally, confirm it is running, and check process stats before air or before routing it to another system.
Use this when a managed source must be published on the network as an NDI device for switchers, graphics systems, or other production clients.
Callaba saves it as a reusable bridge job backed by the restream engine with an NDI-device output, so the object follows the restream schema while staying scoped to MODULE_NDI_ADAPTERS. If operators launch it from vMix, the examples below include a ready-to-adapt vMix Script.
Use this preset when one managed SRT server should show up as a named Cloud NDI output.
This is the most direct operator-facing bridge from an existing SRT ingest boundary into an NDI device contract.
curl --request POST \--url http://localhost/api/restream/create \--header 'x-access-token: <your_api_token>' \--header 'Content-Type: application/json' \--data '{"restream_name": "Camera 1 to Cloud NDI via SRT","input": {"input_type": "INPUT_TYPE_SRT_SOFTWARE","application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API","input_module_id": "66015d2997300f9385d32c00","input_stream_url": "","input_stream_listen_port": {},"input_settings": {},"input_stream_id": "","entity_name": "Camera 1 to Cloud NDI via SRT","module_name": "MODULE_RESTREAM"},"output": {"output_type": "OUTPUT_TYPE_NDI_DEVICE","application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API","output_stream_url": "","output_stream_listen_port": {},"output_settings": {"ndi_device_name": "Cloud NDI Camera 1","timestamp_offset": 0,"av_stream_control_mode": "AV_STREAM_CONTROL_VIDEO_AUDIO"},"output_stream_key": "","entity_name": "Camera 1 to Cloud NDI via SRT","module_name": "MODULE_RESTREAM"},"module_name": "MODULE_NDI_ADAPTERS","active": true}'
This is useful for hardware or software sources that already terminate on RTMP inside the platform.
curl --request POST \--url http://localhost/api/restream/create \--header 'x-access-token: <your_api_token>' \--header 'Content-Type: application/json' \--data '{"restream_name": "GoPro RTMP to Cloud NDI","input": {"input_type": "INPUT_TYPE_RTMP_GOPRO","application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API","input_module_id": "66015d2997300f9385d32c10","input_stream_url": "","input_stream_listen_port": {},"input_settings": {},"input_stream_id": "","entity_name": "GoPro RTMP to Cloud NDI","module_name": "MODULE_RESTREAM"},"output": {"output_type": "OUTPUT_TYPE_NDI_DEVICE","application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API","output_stream_url": "","output_stream_listen_port": {},"output_settings": {"ndi_device_name": "Cloud NDI GoPro","timestamp_offset": 0,"av_stream_control_mode": "AV_STREAM_CONTROL_VIDEO_AUDIO"},"output_stream_key": "","entity_name": "GoPro RTMP to Cloud NDI","module_name": "MODULE_RESTREAM"},"module_name": "MODULE_NDI_ADAPTERS","active": true}'
Use this preset when one participant feed from a video call should be surfaced back into an NDI-aware production environment.
This is the conference-side variant of the same adapter pattern.
curl --request POST \--url http://localhost/api/restream/create \--header 'x-access-token: <your_api_token>' \--header 'Content-Type: application/json' \--data '{"restream_name": "Speaker feed to Cloud NDI","input": {"input_type": "INPUT_TYPE_MODULE_CONFERENCES_PARTICIPANT","application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API","input_module_id": "66015d2997300f9385d32c20","input_stream_url": "","input_stream_listen_port": {},"input_settings": {},"input_stream_id": "","entity_name": "Speaker feed to Cloud NDI","module_name": "MODULE_RESTREAM"},"output": {"output_type": "OUTPUT_TYPE_NDI_DEVICE","application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API","output_stream_url": "","output_stream_listen_port": {},"output_settings": {"ndi_device_name": "Cloud NDI Speaker","timestamp_offset": 0,"av_stream_control_mode": "AV_STREAM_CONTROL_VIDEO_AUDIO"},"output_stream_key": "","entity_name": "Speaker feed to Cloud NDI","module_name": "MODULE_RESTREAM"},"module_name": "MODULE_NDI_ADAPTERS","active": true}'
Dashboard label: Adapter name.
Human-facing name of the NDI adapter job.
Dashboard label: Source Input.
Real supported runtime families include managed SRT server inputs, managed RTMP server inputs, and conference-participant inputs.
Identifier of the selected source entity in the create form.
Dashboard label: Target Output.
This module pins the output side to OUTPUT_TYPE_NDI_DEVICE.
Dashboard label: NDIĀ® Device Name.
Name of the Cloud NDI output device to create.
Dashboard label: Timestamp offset (ns).
Optional timestamp shift in nanoseconds.
Dashboard label: AV Stream Control.
Controls whether the adapter should publish audio, video, or both.
The UI saves this job as MODULE_NDI_ADAPTERS even though it uses the restream backend paths.
Dashboard label: Enable once created.
Controls whether the adapter should start active.
curl --request POST \--url http://localhost/api/restream/create \--header 'x-access-token: <your_api_token>' \--header 'Content-Type: application/json' \--data '{"restream_name": "Camera 1 to Cloud NDI via SRT","input": {"input_type": "INPUT_TYPE_SRT_SOFTWARE","application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API","input_module_id": "66015d2997300f9385d32c00","input_stream_url": "","input_stream_listen_port": {},"input_settings": {},"input_stream_id": "","entity_name": "Camera 1 to Cloud NDI via SRT","module_name": "MODULE_RESTREAM"},"output": {"output_type": "OUTPUT_TYPE_NDI_DEVICE","application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API","output_stream_url": "","output_stream_listen_port": {},"output_settings": {"ndi_device_name": "Cloud NDI Camera 1","timestamp_offset": 0,"av_stream_control_mode": "AV_STREAM_CONTROL_VIDEO_AUDIO"},"output_stream_key": "","entity_name": "Camera 1 to Cloud NDI via SRT","module_name": "MODULE_RESTREAM"},"module_name": "MODULE_NDI_ADAPTERS","active": true}'
Identifiers and the saved adapter name.
Saved source definition for the adapter.
Saved NDI output definition for the adapter.
Module marker, active state, and backend-managed timestamps.
The model exposes success: true for successful responses.
{"_id": "67f200000000000000000001","id": "67f200000000000000000001","restream_name": "Camera 1 to Cloud NDI via SRT","input": [{"_id": "67f200000000000000000010","id": "67f200000000000000000010","input_type": "INPUT_TYPE_SRT_SOFTWARE","input_module_id": "66015d2997300f9385d32c00","module_name": "MODULE_RESTREAM"}],"output": [{"_id": "67f200000000000000000020","id": "67f200000000000000000020","output_type": "OUTPUT_TYPE_NDI_DEVICE","output_settings": {"ndi_device_name": "Cloud NDI Camera 1","timestamp_offset": 0,"av_stream_control_mode": "AV_STREAM_CONTROL_VIDEO_AUDIO"},"module_name": "MODULE_RESTREAM"}],"module_name": "MODULE_NDI_ADAPTERS","active": true,"created": "2026-03-24T11:00:00.000Z","modified": "2026-03-24T11:00:00.000Z","success": true}
Use this with paginated adapter tables or quick bridge inventory checks.
It reports how many NDI adapter jobs are stored under MODULE_NDI_ADAPTERS.
NDI adapter list calls scope this to module_name: MODULE_NDI_ADAPTERS.
curl --request POST \--url http://localhost/api/restream/getCount \--header 'x-access-token: <your_api_token>' \--header 'Content-Type: application/json' \--data '{"filter": {"module_name": "MODULE_NDI_ADAPTERS"}}'
Total number of saved NDI adapter jobs visible to the authenticated user.
{"count": 1}
Use this for operator dashboards and inventory views that need every saved NDI bridge job.
It lists adapter jobs through the standard restream store, filtered to MODULE_NDI_ADAPTERS, so the objects match the restream job shape.
Optional page size for the adapter list.
Optional offset for paginated listing.
Optional sort descriptor. The store defaults to { created: 1 }.
Adapter listings filter to module_name: MODULE_NDI_ADAPTERS.
curl --request POST \--url http://localhost/api/restream/getAll \--header 'x-access-token: <your_api_token>' \--header 'Content-Type: application/json' \--data '{"limit": 10,"skip": 0,"sort": {"created": 1},"filter": {"module_name": "MODULE_NDI_ADAPTERS"}}'
The backend returns a bare array of restream objects filtered to NDI adapters.
[{"_id": "67f200000000000000000001","id": "67f200000000000000000001","restream_name": "Camera 1 to Cloud NDI via SRT","input": [{"_id": "67f200000000000000000010","id": "67f200000000000000000010","input_type": "INPUT_TYPE_SRT_SOFTWARE","input_module_id": "66015d2997300f9385d32c00","module_name": "MODULE_RESTREAM"}],"output": [{"_id": "67f200000000000000000020","id": "67f200000000000000000020","output_type": "OUTPUT_TYPE_NDI_DEVICE","output_settings": {"ndi_device_name": "Cloud NDI Camera 1","timestamp_offset": 0,"av_stream_control_mode": "AV_STREAM_CONTROL_VIDEO_AUDIO"},"module_name": "MODULE_RESTREAM"}],"module_name": "MODULE_NDI_ADAPTERS","active": true,"created": "2026-03-24T11:00:00.000Z","modified": "2026-03-24T11:00:00.000Z","success": true}]
Use this when an operator opens one NDI bridge for inspection, editing, or controlled restart.
It loads the saved source mapping, NDI output settings, and active intent for that adapter.
Identifier of the adapter job you want to load.
curl --request POST \--url http://localhost/api/restream/getById \--header 'x-access-token: <your_api_token>' \--header 'Content-Type: application/json' \--data '{"id": "67f200000000000000000001"}'
The populated restream-backed adapter object.
{"_id": "67f200000000000000000001","id": "67f200000000000000000001","restream_name": "Camera 1 to Cloud NDI via SRT","input": [{"_id": "67f200000000000000000010","id": "67f200000000000000000010","input_type": "INPUT_TYPE_SRT_SOFTWARE","input_module_id": "66015d2997300f9385d32c00","module_name": "MODULE_RESTREAM"}],"output": [{"_id": "67f200000000000000000020","id": "67f200000000000000000020","output_type": "OUTPUT_TYPE_NDI_DEVICE","output_settings": {"ndi_device_name": "Cloud NDI Camera 1","timestamp_offset": 0,"av_stream_control_mode": "AV_STREAM_CONTROL_VIDEO_AUDIO"},"module_name": "MODULE_RESTREAM"}],"module_name": "MODULE_NDI_ADAPTERS","active": true,"created": "2026-03-24T11:00:00.000Z","modified": "2026-03-24T11:00:00.000Z","success": true}
Use this when the bridge is already provisioned and you need to repoint the source, adjust NDI output settings, or change its active intent.
The adapter stays on the same restream-backed contract under MODULE_NDI_ADAPTERS, so you can revise the bridge without replacing it.
Identifier of the adapter job being updated.
The update contract mirrors create and stays on the restream-backed payload shape.
curl --request POST \--url http://localhost/api/restream/update \--header 'x-access-token: <your_api_token>' \--header 'Content-Type: application/json' \--data '{"restream_name": "Camera 1 to Cloud NDI updated","input": {"input_type": "INPUT_TYPE_SRT_SOFTWARE","application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API","input_module_id": "66015d2997300f9385d32c00","input_stream_url": "","input_stream_listen_port": {},"input_settings": {},"input_stream_id": "","entity_name": "Camera 1 to Cloud NDI via SRT","module_name": "MODULE_RESTREAM"},"output": {"output_type": "OUTPUT_TYPE_NDI_DEVICE","application": "IO_APPLICATION_CALLABA_CLOUD_INGRESS_API","output_stream_url": "","output_stream_listen_port": {},"output_settings": {"ndi_device_name": "Cloud NDI Camera 1","timestamp_offset": 0,"av_stream_control_mode": "AV_STREAM_CONTROL_VIDEO_AUDIO"},"output_stream_key": "","entity_name": "Camera 1 to Cloud NDI via SRT","module_name": "MODULE_RESTREAM"},"module_name": "MODULE_NDI_ADAPTERS","active": false,"id": "67f200000000000000000001"}'
The backend returns the updated adapter object.
{"_id": "67f200000000000000000001","id": "67f200000000000000000001","restream_name": "Camera 1 to Cloud NDI updated","input": [{"_id": "67f200000000000000000010","id": "67f200000000000000000010","input_type": "INPUT_TYPE_SRT_SOFTWARE","input_module_id": "66015d2997300f9385d32c00","module_name": "MODULE_RESTREAM"}],"output": [{"_id": "67f200000000000000000020","id": "67f200000000000000000020","output_type": "OUTPUT_TYPE_NDI_DEVICE","output_settings": {"ndi_device_name": "Cloud NDI Camera 1","timestamp_offset": 0,"av_stream_control_mode": "AV_STREAM_CONTROL_VIDEO_AUDIO"},"module_name": "MODULE_RESTREAM"}],"module_name": "MODULE_NDI_ADAPTERS","active": false,"created": "2026-03-24T11:00:00.000Z","modified": "2026-03-24T11:15:00.000Z","success": true}
Use this at show start or handoff when a saved source should become available on the network as an NDI device.
It activates the existing bridge job without changing its configuration, which makes it a good fit for button-driven operator workflows.
Identifier of the adapter job to start.
curl --request POST \--url http://localhost/api/restream/start \--header 'x-access-token: <your_api_token>' \--header 'Content-Type: application/json' \--data '{"id": "67f200000000000000000001"}'
The backend marks the adapter as active and returns the updated object.
{"_id": "67f200000000000000000001","id": "67f200000000000000000001","restream_name": "Camera 1 to Cloud NDI via SRT","input": [{"_id": "67f200000000000000000010","id": "67f200000000000000000010","input_type": "INPUT_TYPE_SRT_SOFTWARE","input_module_id": "66015d2997300f9385d32c00","module_name": "MODULE_RESTREAM"}],"output": [{"_id": "67f200000000000000000020","id": "67f200000000000000000020","output_type": "OUTPUT_TYPE_NDI_DEVICE","output_settings": {"ndi_device_name": "Cloud NDI Camera 1","timestamp_offset": 0,"av_stream_control_mode": "AV_STREAM_CONTROL_VIDEO_AUDIO"},"module_name": "MODULE_RESTREAM"}],"module_name": "MODULE_NDI_ADAPTERS","active": true,"created": "2026-03-24T11:00:00.000Z","modified": "2026-03-24T11:20:00.000Z","success": true}
Use this to withdraw an NDI device from the network while keeping the saved bridge ready for later reuse.
It is the normal operational companion to start when the feed should go dark but the adapter configuration should stay intact.
Identifier of the adapter job to stop.
curl --request POST \--url http://localhost/api/restream/stop \--header 'x-access-token: <your_api_token>' \--header 'Content-Type: application/json' \--data '{"id": "67f200000000000000000001"}'
The backend marks the adapter as inactive and returns the updated object.
{"_id": "67f200000000000000000001","id": "67f200000000000000000001","restream_name": "Camera 1 to Cloud NDI via SRT","input": [{"_id": "67f200000000000000000010","id": "67f200000000000000000010","input_type": "INPUT_TYPE_SRT_SOFTWARE","input_module_id": "66015d2997300f9385d32c00","module_name": "MODULE_RESTREAM"}],"output": [{"_id": "67f200000000000000000020","id": "67f200000000000000000020","output_type": "OUTPUT_TYPE_NDI_DEVICE","output_settings": {"ndi_device_name": "Cloud NDI Camera 1","timestamp_offset": 0,"av_stream_control_mode": "AV_STREAM_CONTROL_VIDEO_AUDIO"},"module_name": "MODULE_RESTREAM"}],"module_name": "MODULE_NDI_ADAPTERS","active": false,"created": "2026-03-24T11:00:00.000Z","modified": "2026-03-24T11:25:00.000Z","success": true}
Use this to retire an NDI bridge that should no longer appear in operator workflows or be started again.
Because adapters are restream-backed, removal follows the normal job lifecycle; delete only after the NDI output is no longer needed on the network.
Identifier of the adapter job to delete.
curl --request DELETE \--url http://localhost/api/restream/remove \--header 'x-access-token: <your_api_token>' \--header 'Content-Type: application/json' \--data '{"id": "67f200000000000000000001"}'
The docs use the previously loaded adapter object as the reference shape for a successful remove flow.
{"_id": "67f200000000000000000001","id": "67f200000000000000000001","restream_name": "Camera 1 to Cloud NDI via SRT","input": [{"_id": "67f200000000000000000010","id": "67f200000000000000000010","input_type": "INPUT_TYPE_SRT_SOFTWARE","input_module_id": "66015d2997300f9385d32c00","module_name": "MODULE_RESTREAM"}],"output": [{"_id": "67f200000000000000000020","id": "67f200000000000000000020","output_type": "OUTPUT_TYPE_NDI_DEVICE","output_settings": {"ndi_device_name": "Cloud NDI Camera 1","timestamp_offset": 0,"av_stream_control_mode": "AV_STREAM_CONTROL_VIDEO_AUDIO"},"module_name": "MODULE_RESTREAM"}],"module_name": "MODULE_NDI_ADAPTERS","active": true,"created": "2026-03-24T11:00:00.000Z","modified": "2026-03-24T11:00:00.000Z","success": true}
Use this during live operations when you need to know whether the NDI bridge is actually running and moving media.
It reads the live process status rather than the saved job definition, which makes it the right check before or during a show.
curl --request POST \--url http://localhost/api/restream/getStat \--header 'x-access-token: <your_api_token>' \--header 'Content-Type: application/json' \--data '{}'
Current process-stat rows used by the adapter listing and operational checks.
Current runtime bitrate values for the adapter process.
Current FFmpeg-style progress values for the running bridge.
[{"processData": {"id": "67f200000000000000000001","bitrate": "3200.5kbits/s","bitrate_kbits": 3200,"fps": "30","speed": "1.00x","progress": "continue"}}]