diff --git a/src/calng/DetectorAssembler.py b/src/calng/DetectorAssembler.py
index e8651345c7540effe94a070e46072d904daeb06d..aa5f00eced4bc4cc7b3620747ca2004360d35753 100644
--- a/src/calng/DetectorAssembler.py
+++ b/src/calng/DetectorAssembler.py
@@ -1,3 +1,4 @@
+import enum
 import functools
 import pickle
 import re
@@ -36,13 +37,13 @@ from karabo import version as karaboVersion
 from . import scenes
 from ._version import version as deviceVersion
 
-output_schema = Schema()
+assembled_schema = Schema()
 (
-    NODE_ELEMENT(output_schema).key("image").commit(),
+    NODE_ELEMENT(assembled_schema).key("image").commit(),
 
-    NDARRAY_ELEMENT(output_schema).key("image.data").commit(),
+    NDARRAY_ELEMENT(assembled_schema).key("image.data").commit(),
 
-    UINT64_ELEMENT(output_schema).key("trainId").readOnly().commit(),
+    UINT64_ELEMENT(assembled_schema).key("trainId").readOnly().commit(),
 )
 
 preview_schema = Schema()
@@ -58,6 +59,12 @@ xtdf_source_re = re.compile(r".*\/DET\/(\d+)CH0:xtdf")
 daq_source_re = re.compile(r".*\/DET\/.*?(\d+):daqOutput")
 
 
+class BridgeOutputOptions(enum.Enum):
+    MATCHED = "matched"
+    ASSEMBLED = "assembled"
+    PREVIEW = "preview"
+
+
 # TODO: merge scene with TrainMatcher's nice overview
 @KARABO_CLASSINFO("DetectorAssembler", deviceVersion)
 class DetectorAssembler(TrainMatcher.TrainMatcher):
@@ -97,6 +104,11 @@ class DetectorAssembler(TrainMatcher.TrainMatcher):
             .defaultValue("image.data")
             .commit(),
 
+            OUTPUT_CHANNEL(expected)
+            .key("assembledOutput")
+            .dataSchema(assembled_schema)
+            .commit(),
+
             NODE_ELEMENT(expected)
             .key("preview")
             .description(
@@ -107,6 +119,12 @@ class DetectorAssembler(TrainMatcher.TrainMatcher):
             )
             .commit(),
 
+            OUTPUT_CHANNEL(expected)
+            .key("preview.output")
+            .dataSchema(preview_schema)
+            .description("See description of parent node, 'preview'.")
+            .commit(),
+
             UINT32_ELEMENT(expected)
             .key("preview.downsamplingFactor")
             .description(
@@ -129,11 +147,6 @@ class DetectorAssembler(TrainMatcher.TrainMatcher):
             .reconfigurable()
             .commit(),
 
-            OUTPUT_CHANNEL(expected)
-            .key("preview.output")
-            .dataSchema(preview_schema)
-            .commit(),
-
             UINT32_ELEMENT(expected)
             .key("preview.trainStride")
             .displayedName("Train stride")
@@ -142,15 +155,25 @@ class DetectorAssembler(TrainMatcher.TrainMatcher):
             .defaultValue(10)
             .commit(),
 
+            STRING_ELEMENT(expected)
+            .key("outputForBridgeOutput")
+            .displayedName("Bridge output")
+            .description(
+                "The bridge can send the same data as any one of the three Karabo "
+                "output channels. If this setting is 'matched', it will follow "
+                "'output', if 'assembled', it will follow 'assembledOutput' and if "
+                "'preview', it will follow 'preview.output'."
+            )
+            .options(",".join(option.value for option in BridgeOutputOptions))
+            .assignmentOptional()
+            .defaultValue("matched")
+            .reconfigurable()
+            .commit(),
+
             INPUT_CHANNEL(expected)
             .key("geometryInput")
             .displayedName("Geometry input")
             .commit(),
-
-            OUTPUT_CHANNEL(expected)  # can OVERWRITE_ELEMENT even do this?
-            .key("output")
-            .dataSchema(output_schema)
-            .commit(),
         )
 
     def initialization(self):
@@ -166,6 +189,7 @@ class DetectorAssembler(TrainMatcher.TrainMatcher):
         self.KARABO_SLOT(self.requestScene)
 
         self.ask_for_geometry()
+        self.assembled_output = self.signalSlotable.getOutputChannel("assembledOutput")
         self.preview_output = self.signalSlotable.getOutputChannel("preview.output")
         self.start()
 
@@ -241,9 +265,18 @@ class DetectorAssembler(TrainMatcher.TrainMatcher):
 
         my_timestamp = Timestamp(Epochstamp(), Trainstamp(train_id))
         my_source = self.getInstanceId()
+        bridge_output_choice = BridgeOutputOptions(
+            self.unsafe_get("outputForBridgeOutput")
+        )
 
         module_indices_unfilled = set(range(self._stack_input_buffer.shape[0]))
         for source, (data, source_timestamp) in sources.items():
+            # regular TrainMatcher output
+            self.output.write(data, ChannelMetaData(source, source_timestamp))
+            if bridge_output_choice is BridgeOutputOptions.MATCHED:
+                self.zmq_output.write(source, data, source_timestamp)
+
+            # prepare for assembly
             # TODO: handle failure to "parse" source, get data out
             module_index = self._source_to_index(source)
             self._stack_input_buffer[module_index] = np.squeeze(
@@ -251,6 +284,10 @@ class DetectorAssembler(TrainMatcher.TrainMatcher):
             )
             module_indices_unfilled.discard(module_index)
 
+        self.output.update()
+        if bridge_output_choice is BridgeOutputOptions.MATCHED:
+            self.zmq_output.update()
+
         for module_index in module_indices_unfilled:
             self._stack_input_buffer[module_index].fill(0)
             # TODO: configurable treatment of missing modules
@@ -266,10 +303,11 @@ class DetectorAssembler(TrainMatcher.TrainMatcher):
             train_id,
         )
         output_metadata = ChannelMetaData(my_source, my_timestamp)
-        self.output.write(output_hash, output_metadata)
-        self.output.update()
-        self.zmq_output.write(my_source, output_hash, my_timestamp)
-        self.zmq_output.update()
+        self.assembled_output.write(output_hash, output_metadata)
+        self.assembled_output.update()
+        if bridge_output_choice is BridgeOutputOptions.ASSEMBLED:
+            self.zmq_output.write(my_source, output_hash, my_timestamp)
+            self.zmq_output.update()
 
         if train_id % self.unsafe_get("preview.trainStride") == 0:
             downsampling_factor = self.unsafe_get("preview.downsamplingFactor")
@@ -293,8 +331,18 @@ class DetectorAssembler(TrainMatcher.TrainMatcher):
                 "trainId",
                 train_id,
             )
-            self.preview_output.write(output_hash, output_metadata)
+            self.preview_output.write(
+                output_hash,
+                output_metadata,
+            )
             self.preview_output.update()
+            if bridge_output_choice is BridgeOutputOptions.PREVIEW:
+                self.zmq_output.write(
+                    my_source,
+                    output_hash,
+                    my_timestamp,
+                )
+                self.zmq_output.update()
 
         self.rate_out.update()