diff --git a/extensions/chaeo/router.py b/extensions/chaeo/router.py
new file mode 100644
index 0000000000000000000000000000000000000000..208aa7b9ff3e0a79b4bcdfa7d3742cd7bfa5c3e1
--- /dev/null
+++ b/extensions/chaeo/router.py
@@ -0,0 +1,42 @@
+from fastapi import APIRouter, HTTPException
+
+from extensions.chaeo.workflows import infer_object_map_from_zstack
+from model_server.session import Session
+from model_server.validators import validate_workflow_inputs
+
+router = APIRouter(
+    prefix='/chaeo',
+    tags=['chaeo'],
+)
+
+session = Session()
+
+@router.put('/classify_zstack/infer')
+def infer_px_then_ob_maps(
+        px_model_id: str,
+        ob_model_id: str,
+        input_filename: str,
+        pxmap_threshold: float,
+        pxmap_foreground_channel: int,
+        segmentation_channel: int,
+        patches_channel: int,
+        zmask_filters: dict = {'area': (1e3, 1e8)},
+) -> dict:
+    inpath = session.paths['inbound_images'] / input_filename
+    validate_workflow_inputs([px_model_id, ob_model_id], [inpath])
+
+    record = infer_object_map_from_zstack(
+        inpath,
+        session.paths['outbound_images'],
+        [
+            session.models[px_model_id]['object'],
+            session.models[px_model_id]['object']
+        ],
+        pxmap_threshold=pxmap_threshold,
+        pxmap_foreground_channel=pxmap_foreground_channel,
+        segmentation_channel=segmentation_channel,
+        patches_channel=patches_channel,
+        zmask_filters=zmask_filters,
+    )
+
+    return record
\ No newline at end of file