diff --git a/godot-addon/addons/godotiq/godotiq_runtime.gd b/godot-addon/addons/godotiq/godotiq_runtime.gd
index 34c1f6b..8556542 100644
--- a/godot-addon/addons/godotiq/godotiq_runtime.gd
+++ b/godot-addon/addons/godotiq/godotiq_runtime.gd
@@ -132,6 +132,16 @@ func _take_screenshot(params: Dictionary) -> void:
 	var scale: float = clampf(params.get("scale", 0.5), 0.1, 1.0)
 	var quality: float = clampf(params.get("quality", 0.5), 0.1, 1.0)
 	var fmt: String = params.get("format", "webp")
+	var region: Array = params.get("region", [])
+
+	# Apply region crop before scaling
+	if region.size() == 4:
+		var rx: int = clampi(int(region[0]), 0, img.get_width())
+		var ry: int = clampi(int(region[1]), 0, img.get_height())
+		var rw: int = clampi(int(region[2]), 1, img.get_width() - rx)
+		var rh: int = clampi(int(region[3]), 1, img.get_height() - ry)
+		img = img.get_region(Rect2i(rx, ry, rw, rh))
+
 	var w := img.get_width()
 	var h := img.get_height()
 
diff --git a/godot-addon/addons/godotiq/godotiq_server.gd b/godot-addon/addons/godotiq/godotiq_server.gd
index 1b41808..d8673da 100644
--- a/godot-addon/addons/godotiq/godotiq_server.gd
+++ b/godot-addon/addons/godotiq/godotiq_server.gd
@@ -202,7 +202,7 @@ func _process(_delta: float) -> void:
 		_pending_screenshot = null
 		_do_editor_screenshot(
 			s["peer_id"], s["id"], s["viewport_3d"],
-			s["camera"], s["original_transform"], true, s["scale"], s["quality"], s["fmt"]
+			s["camera"], s["original_transform"], true, s["scale"], s["quality"], s["fmt"], s.get("region", [])
 		)
 
 	# 4a. Process deferred scene open -> play
@@ -1331,15 +1331,17 @@ func _handle_editor_screenshot(peer_id: int, id: String, params: Dictionary) ->
 		_pending_screenshot = {
 			"peer_id": peer_id, "id": id, "viewport_3d": viewport_3d,
 			"camera": camera, "original_transform": original_transform,
-			"scale": scale, "quality": quality, "fmt": fmt,
+			"scale": scale, "quality": quality, "fmt": fmt, "region": region,
 		}
 		return
 
+	var region: Array = params.get("region", [])
+
 	# No camera move — capture current viewport texture immediately
-	_do_editor_screenshot(peer_id, id, viewport_3d, camera, original_transform, false, scale, quality, fmt)
+	_do_editor_screenshot(peer_id, id, viewport_3d, camera, original_transform, false, scale, quality, fmt, region)
 
 
-func _do_editor_screenshot(peer_id: int, id: String, viewport_3d: SubViewport, camera: Camera3D, original_transform: Transform3D, restore_camera: bool, scale: float, quality: float, fmt: String) -> void:
+func _do_editor_screenshot(peer_id: int, id: String, viewport_3d: SubViewport, camera: Camera3D, original_transform: Transform3D, restore_camera: bool, scale: float, quality: float, fmt: String, region: Array = []) -> void:
 	var img := viewport_3d.get_texture().get_image()
 	if img == null:
 		if restore_camera and camera != null:
@@ -1347,6 +1349,14 @@ func _do_editor_screenshot(peer_id: int, id: String, viewport_3d: SubViewport, c
 		_send_error(peer_id, id, "CAPTURE_FAILED", "Failed to capture editor viewport image")
 		return
 
+	# Apply region crop before scaling
+	if region.size() == 4:
+		var rx: int = clampi(int(region[0]), 0, img.get_width())
+		var ry: int = clampi(int(region[1]), 0, img.get_height())
+		var rw: int = clampi(int(region[2]), 1, img.get_width() - rx)
+		var rh: int = clampi(int(region[3]), 1, img.get_height() - ry)
+		img = img.get_region(Rect2i(rx, ry, rw, rh))
+
 	if scale < 1.0 and scale > 0.0:
 		var new_width: int = int(img.get_width() * scale)
 		var new_height: int = int(img.get_height() * scale)
diff --git a/src/godotiq/tools/bridge/__init__.py b/src/godotiq/tools/bridge/__init__.py
index eb5e3d2..1321ed8 100644
--- a/src/godotiq/tools/bridge/__init__.py
+++ b/src/godotiq/tools/bridge/__init__.py
@@ -46,6 +46,7 @@ async def godotiq_screenshot(
     quality: float = 0.5,
     camera_position: list[float] | None = None,
     camera_target: list[float] | None = None,
+    region: list[float] | None = None,
     detail: str = "normal",
     ctx: Context = None,
 ) -> dict:
@@ -58,12 +59,14 @@ async def godotiq_screenshot(
         quality: Encoding quality (0.1-1.0). Use 0.3 for routine checks, 0.8 for detail.
         camera_position: [x, y, z] — Editor only. Move camera before capture.
         camera_target: [x, y, z] — Editor only. Camera looks at this point.
+        region: [x, y, width, height] — Crop to this pixel region before encoding. Zoom into specific areas without increasing total response size.
         detail: Output verbosity — "brief" (summary), "normal" (default), or "full" (everything).
     """
     try:
         return await _screenshot(
             viewport=viewport, scale=scale, format=format, quality=quality,
             camera_position=camera_position, camera_target=camera_target,
+            region=region,
         )
     except BridgeConnectionError as e:
         return {"error": str(e), "hint": "Enable the GodotIQ addon in Godot editor and ensure it is running."}
diff --git a/src/godotiq/tools/bridge/screenshot.py b/src/godotiq/tools/bridge/screenshot.py
index 1afc5b1..da739e3 100644
--- a/src/godotiq/tools/bridge/screenshot.py
+++ b/src/godotiq/tools/bridge/screenshot.py
@@ -16,6 +16,7 @@ async def screenshot(
     quality: float = 0.5,
     camera_position: list[float] | None = None,
     camera_target: list[float] | None = None,
+    region: list[float] | None = None,
 ) -> dict:
     """Capture a screenshot from the game or editor viewport.
 
@@ -26,6 +27,7 @@ async def screenshot(
         quality: Encoding quality (0.1-1.0). Lower = smaller file. Default 0.5.
         camera_position: [x, y, z] — Editor only. Temporarily move camera here before capture.
         camera_target: [x, y, z] — Editor only. Camera looks at this point.
+        region: [x, y, width, height] — Crop region in pixels. Applied before scaling.
 
     Returns:
         Dict with image (base64), format, width, height.
@@ -44,6 +46,11 @@ async def screenshot(
         return {"error": "camera_position must have exactly 3 elements [x, y, z]"}
     if camera_target is not None and len(camera_target) != 3:
         return {"error": "camera_target must have exactly 3 elements [x, y, z]"}
+    if region is not None:
+        if len(region) != 4:
+            return {"error": "region must have exactly 4 elements [x, y, width, height]"}
+        if region[2] <= 0 or region[3] <= 0:
+            return {"error": "region width and height must be positive"}
 
     bridge = await get_bridge()
 
@@ -53,11 +60,16 @@ async def screenshot(
             params["camera_position"] = camera_position
         if camera_target is not None:
             params["camera_target"] = camera_target
+        if region is not None:
+            params["region"] = region
         result = await bridge.request("editor_screenshot", params=params, timeout=10.0)
     else:
+        game_params = {"viewport": viewport, "scale": scale, "format": format, "quality": quality}
+        if region is not None:
+            game_params["region"] = region
         result = await bridge.request_with_retry(
             "screenshot",
-            params={"viewport": viewport, "scale": scale, "format": format, "quality": quality},
+            params=game_params,
             max_retries=SCREENSHOT_MAX_RETRIES,
             retry_delay=SCREENSHOT_RETRY_DELAY,
         )
diff --git a/tests/test_bridge/test_editor_screenshot.py b/tests/test_bridge/test_editor_screenshot.py
index 7abb772..fb2c8f5 100644
--- a/tests/test_bridge/test_editor_screenshot.py
+++ b/tests/test_bridge/test_editor_screenshot.py
@@ -150,3 +150,49 @@ class TestEditorScreenshot:
         with patch("godotiq.tools.bridge.screenshot.get_bridge", return_value=mock_bridge):
             result = await screenshot(viewport="editor")
             assert "size_warning" not in result
+
+    # --- Region crop tests ---
+
+    @pytest.mark.asyncio
+    async def test_region_param_passed_to_editor(self):
+        """Region parameter should be included in editor screenshot params."""
+        mock_bridge = AsyncMock()
+        mock_bridge.request = AsyncMock(return_value={"image": "base64"})
+        with patch("godotiq.tools.bridge.screenshot.get_bridge", return_value=mock_bridge):
+            await screenshot(viewport="editor", region=[100, 200, 300, 400])
+            params = mock_bridge.request.call_args[1]["params"]
+            assert params["region"] == [100, 200, 300, 400]
+
+    @pytest.mark.asyncio
+    async def test_region_param_passed_to_game(self):
+        """Region parameter should be included in game screenshot params."""
+        mock_bridge = AsyncMock()
+        mock_bridge.request_with_retry = AsyncMock(return_value={"image": "base64"})
+        with patch("godotiq.tools.bridge.screenshot.get_bridge", return_value=mock_bridge):
+            await screenshot(viewport="game", region=[0, 0, 640, 480])
+            params = mock_bridge.request_with_retry.call_args.kwargs["params"]
+            assert params["region"] == [0, 0, 640, 480]
+
+    @pytest.mark.asyncio
+    async def test_region_not_passed_when_none(self):
+        """Region should not be in params when not provided."""
+        mock_bridge = AsyncMock()
+        mock_bridge.request = AsyncMock(return_value={"image": "base64"})
+        with patch("godotiq.tools.bridge.screenshot.get_bridge", return_value=mock_bridge):
+            await screenshot(viewport="editor")
+            params = mock_bridge.request.call_args[1]["params"]
+            assert "region" not in params
+
+    @pytest.mark.asyncio
+    async def test_region_validation_wrong_length(self):
+        """Region with != 4 elements should return error."""
+        result = await screenshot(viewport="editor", region=[100, 200])
+        assert "error" in result
+        assert "4 elements" in result["error"]
+
+    @pytest.mark.asyncio
+    async def test_region_validation_non_positive_dimensions(self):
+        """Region with width or height <= 0 should return error."""
+        result = await screenshot(viewport="editor", region=[0, 0, 0, 100])
+        assert "error" in result
+        assert "positive" in result["error"].lower() or "width" in result["error"].lower()
