Computer Use enables programmatic control of desktop environments within sandboxes. It provides mouse, keyboard, screenshot, screen recording, and display operations for automating GUI interactions and testing desktop applications.
Computer Use and VNC work together to enable both manual and automated desktop interactions. VNC provides the visual interface for users to manually interact with the desktop, while Computer Use provides the programmatic API for AI agents to automate operations.
Computer Use is available for Linux. Windows and macOS support is currently in private alpha.
- GUI application testing: automate interactions with native applications, click buttons, fill forms, and validate UI behavior
- Visual testing & screenshots: capture screenshots of applications, compare UI states, and perform visual regression testing
- Desktop automation: automate repetitive desktop tasks, file management through GUI, and complex workflows
Start Computer Use
Section titled “Start Computer Use”Start all computer use processes (Xvfb, xfce4, x11vnc, novnc) in the Sandbox.
result = sandbox.computer_use.start()print("Computer use processes started:", result.message)const result = await sandbox.computerUse.start();console.log('Computer use processes started:', result.message);result = sandbox.computer_use.startputs "Computer use processes started: #{result.message}"err := sandbox.ComputerUse.Start(ctx)if err != nil { log.Fatal(err)}defer sandbox.ComputerUse.Stop(ctx)
fmt.Println("Computer use processes started")var result = sandbox.computerUse.start();System.out.println("Computer use processes started: " + result.getMessage());curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/start' \ --request POSTStop Computer Use
Section titled “Stop Computer Use”Stop all computer use processes in the Sandbox.
result = sandbox.computer_use.stop()print("Computer use processes stopped:", result.message)const result = await sandbox.computerUse.stop();console.log('Computer use processes stopped:', result.message);result = sandbox.computer_use.stopputs "Computer use processes stopped: #{result.message}"err := sandbox.ComputerUse.Stop(ctx)if err != nil { log.Fatal(err)}
fmt.Println("Computer use processes stopped")var result = sandbox.computerUse.stop();System.out.println("Computer use processes stopped: " + result.getMessage());curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/stop' \ --request POSTGet status
Section titled “Get status”Get the status of all computer use processes.
response = sandbox.computer_use.get_status()print("Computer use status:", response.status)const status = await sandbox.computerUse.getStatus();console.log('Computer use status:', status.status);response = sandbox.computer_use.statusputs "Computer use status: #{response.status}"status, err := sandbox.ComputerUse.GetStatus(ctx)if err != nil { log.Fatal(err)}
fmt.Printf("Computer use status: %v\n", status["status"])var response = sandbox.computerUse.getStatus();System.out.println("Computer use status: " + response.getStatus());curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/status'Get process status
Section titled “Get process status”Get the status of a specific VNC process.
xvfb_status = sandbox.computer_use.get_process_status("xvfb")novnc_status = sandbox.computer_use.get_process_status("novnc")const xvfbStatus = await sandbox.computerUse.getProcessStatus('xvfb');const noVncStatus = await sandbox.computerUse.getProcessStatus('novnc');xvfb_status = sandbox.computer_use.get_process_status("xvfb")no_vnc_status = sandbox.computer_use.get_process_status("novnc")curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/process/{processName}/status'Restart process
Section titled “Restart process”Restart a specific VNC process.
result = sandbox.computer_use.restart_process("xfce4")print("XFCE4 process restarted:", result.message)const result = await sandbox.computerUse.restartProcess('xfce4');console.log('XFCE4 process restarted:', result.message);result = sandbox.computer_use.restart_process("xfce4")puts "XFCE4 process restarted: #{result.message}"curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/process/{processName}/restart' \ --request POSTGet process logs
Section titled “Get process logs”Get logs for a specific VNC process.
logs = sandbox.computer_use.get_process_logs("novnc")print("NoVNC logs:", logs)const logsResp = await sandbox.computerUse.getProcessLogs('novnc');console.log('NoVNC logs:', logsResp.logs);logs = sandbox.computer_use.get_process_logs("novnc")puts "NoVNC logs: #{logs}"curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/process/{processName}/logs'Get process errors
Section titled “Get process errors”Get error logs for a specific VNC process.
errors = sandbox.computer_use.get_process_errors("x11vnc")print("X11VNC errors:", errors)const errorsResp = await sandbox.computerUse.getProcessErrors('x11vnc');console.log('X11VNC errors:', errorsResp.errors);errors = sandbox.computer_use.get_process_errors("x11vnc")puts "X11VNC errors: #{errors}"curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/process/{processName}/errors'Mouse operations
Section titled “Mouse operations”Click the mouse at the specified coordinates. button is one of left, right, or middle (case-insensitive; defaults to left); other values return an error.
# Single left clickresult = sandbox.computer_use.mouse.click(100, 200)
# Double clickdouble_click = sandbox.computer_use.mouse.click(100, 200, "left", True)
# Right clickright_click = sandbox.computer_use.mouse.click(100, 200, "right")// Single left clickconst result = await sandbox.computerUse.mouse.click(100, 200);
// Double clickconst doubleClick = await sandbox.computerUse.mouse.click(100, 200, 'left', true);
// Right clickconst rightClick = await sandbox.computerUse.mouse.click(100, 200, 'right');# Single left clickresult = sandbox.computer_use.mouse.click(x: 100, y: 200)
# Double clickdouble_click = sandbox.computer_use.mouse.click(x: 100, y: 200, button: 'left', double: true)
# Right clickright_click = sandbox.computer_use.mouse.click(x: 100, y: 200, button: 'right')// Single left clickresult, err := sandbox.ComputerUse.Mouse().Click(ctx, 100, 200, nil, nil)if err != nil { log.Fatal(err)}
// Double clickdoubleClick := trueresult, err = sandbox.ComputerUse.Mouse().Click(ctx, 100, 200, nil, &doubleClick)
// Right clickrightButton := "right"result, err = sandbox.ComputerUse.Mouse().Click(ctx, 100, 200, &rightButton, nil)// Single left clicksandbox.computerUse.click(100, 200);
// Double clicksandbox.computerUse.doubleClick(100, 200);
// Right clicksandbox.computerUse.click(100, 200, "right");curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/mouse/click' \ --request POST \ --header 'Content-Type: application/json' \ --data '{ "button": "left", "double": true, "x": 100, "y": 200}'Move the mouse cursor to the specified coordinates.
result = sandbox.computer_use.mouse.move(100, 200)print(f"Mouse moved to: {result.x}, {result.y}")const result = await sandbox.computerUse.mouse.move(100, 200);console.log(`Mouse moved to: ${result.x}, ${result.y}`);result = sandbox.computer_use.mouse.move(x: 100, y: 200)puts "Mouse moved to: #{result.x}, #{result.y}"result, err := sandbox.ComputerUse.Mouse().Move(ctx, 100, 200)if err != nil { log.Fatal(err)}
fmt.Printf("Mouse moved to: %v, %v\n", result["x"], result["y"])var result = sandbox.computerUse.moveMouse(100, 200);System.out.println("Mouse moved to: " + result.getX() + ", " + result.getY());curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/mouse/move' \ --request POST \ --header 'Content-Type: application/json' \ --data '{ "x": 1, "y": 1}'Drag the mouse from start coordinates to end coordinates.
result = sandbox.computer_use.mouse.drag(50, 50, 150, 150)print(f"Drag ended at {result.x}, {result.y}")const result = await sandbox.computerUse.mouse.drag(50, 50, 150, 150);console.log(`Drag ended at ${result.x}, ${result.y}`);result = sandbox.computer_use.mouse.drag(start_x: 50, start_y: 50, end_x: 150, end_y: 150)puts "Drag ended at #{result.x}, #{result.y}"result, err := sandbox.ComputerUse.Mouse().Drag(ctx, 50, 50, 150, 150, nil)if err != nil { log.Fatal(err)}
fmt.Printf("Dragged to %v, %v\n", result["x"], result["y"])var result = sandbox.computerUse.drag(50, 50, 150, 150);System.out.println("Drag ended at: " + result.getX() + ", " + result.getY());curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/mouse/drag' \ --request POST \ --header 'Content-Type: application/json' \ --data '{ "button": "left", "endX": 200, "endY": 300, "startX": 100, "startY": 100}'Scroll
Section titled “Scroll”Scroll the mouse wheel at the specified coordinates. direction is up or down (other values return an error). amount is the number of scroll wheel ticks to send — one tick is roughly one notch of a physical mouse wheel, which moves a few lines in most apps. Defaults to 1 if omitted.
# Scroll upscroll_up = sandbox.computer_use.mouse.scroll(100, 200, "up", 3)
# Scroll downscroll_down = sandbox.computer_use.mouse.scroll(100, 200, "down", 5)// Scroll upconst scrollUp = await sandbox.computerUse.mouse.scroll(100, 200, 'up', 3);
// Scroll downconst scrollDown = await sandbox.computerUse.mouse.scroll(100, 200, 'down', 5);# Scroll upscroll_up = sandbox.computer_use.mouse.scroll(x: 100, y: 200, direction: 'up', amount: 3)
# Scroll downscroll_down = sandbox.computer_use.mouse.scroll(x: 100, y: 200, direction: 'down', amount: 5)// Scroll upamount := 3success, err := sandbox.ComputerUse.Mouse().Scroll(ctx, 100, 200, "up", &amount)if err != nil { log.Fatal(err)}
// Scroll downamount = 5success, err = sandbox.ComputerUse.Mouse().Scroll(ctx, 100, 200, "down", &amount)// Scroll up (negative vertical delta maps to "up")sandbox.computerUse.scroll(100, 200, 0, -3);
// Scroll downsandbox.computerUse.scroll(100, 200, 0, 5);curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/mouse/scroll' \ --request POST \ --header 'Content-Type: application/json' \ --data '{ "amount": 3, "direction": "down", "x": 100, "y": 200}'Get position
Section titled “Get position”Get the current mouse cursor position.
position = sandbox.computer_use.mouse.get_position()print(f"Mouse is at: {position.x}, {position.y}")const position = await sandbox.computerUse.mouse.getPosition();console.log(`Mouse is at: ${position.x}, ${position.y}`);position = sandbox.computer_use.mouse.positionputs "Mouse is at: #{position.x}, #{position.y}"position, err := sandbox.ComputerUse.Mouse().GetPosition(ctx)if err != nil { log.Fatal(err)}
fmt.Printf("Mouse is at: %v, %v\n", position["x"], position["y"])var position = sandbox.computerUse.getMousePosition();System.out.println("Mouse is at: " + position.getX() + ", " + position.getY());curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/mouse/position'Keyboard operations
Section titled “Keyboard operations”Types arbitrary text, including uppercase letters, symbols, and non-ASCII characters. Newlines (\n, \r, \r\n) are translated into Enter key presses; literal tab and other control characters are rejected.
sandbox.computer_use.keyboard.type("Hello, World!")
# With delay between characterssandbox.computer_use.keyboard.type("Slow typing", 100)await sandbox.computerUse.keyboard.type('Hello, World!');
// With delay between charactersawait sandbox.computerUse.keyboard.type('Slow typing', 100);sandbox.computer_use.keyboard.type(text: "Hello, World!")
# With delay between characterssandbox.computer_use.keyboard.type(text: "Slow typing", delay: 100)err := sandbox.ComputerUse.Keyboard().Type(ctx, "Hello, World!", nil)if err != nil { log.Fatal(err)}
// With delay between charactersdelay := 100err = sandbox.ComputerUse.Keyboard().Type(ctx, "Slow typing", &delay)sandbox.computerUse.typeText("Hello, World!");curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/keyboard/type' \ --request POST \ --header 'Content-Type: application/json' \ --data '{ "delay": 1, "text": ""}'Press a key with optional modifiers.
# Press Entersandbox.computer_use.keyboard.press("enter")
# Press Ctrl+Csandbox.computer_use.keyboard.press("c", ["ctrl"])
# Press Ctrl+Shift+Tsandbox.computer_use.keyboard.press("t", ["ctrl", "shift"])// Press Enterawait sandbox.computerUse.keyboard.press('enter');
// Press Ctrl+Cawait sandbox.computerUse.keyboard.press('c', ['ctrl']);
// Press Ctrl+Shift+Tawait sandbox.computerUse.keyboard.press('t', ['ctrl', 'shift']);# Press Entersandbox.computer_use.keyboard.press(key: "enter")
# Press Ctrl+Csandbox.computer_use.keyboard.press(key: "c", modifiers: ["ctrl"])
# Press Ctrl+Shift+Tsandbox.computer_use.keyboard.press(key: "t", modifiers: ["ctrl", "shift"])// Press Entererr := sandbox.ComputerUse.Keyboard().Press(ctx, "enter", nil)if err != nil { log.Fatal(err)}
// Press Ctrl+Cerr = sandbox.ComputerUse.Keyboard().Press(ctx, "c", []string{"ctrl"})
// Press Ctrl+Shift+Terr = sandbox.ComputerUse.Keyboard().Press(ctx, "t", []string{"ctrl", "shift"})// Press Entersandbox.computerUse.pressKey("enter");
// Press Ctrl+Csandbox.computerUse.pressHotkey("ctrl", "c");
// Press Ctrl+Shift+Tsandbox.computerUse.pressHotkey("ctrl", "shift", "t");curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/keyboard/key' \ --request POST \ --header 'Content-Type: application/json' \ --data '{ "key": "enter", "modifiers": []}'Hotkey
Section titled “Hotkey”Press a hotkey combination.
# Copysandbox.computer_use.keyboard.hotkey("ctrl+c")
# Pastesandbox.computer_use.keyboard.hotkey("ctrl+v")
# Alt+Tabsandbox.computer_use.keyboard.hotkey("alt+tab")// Copyawait sandbox.computerUse.keyboard.hotkey('ctrl+c');
// Pasteawait sandbox.computerUse.keyboard.hotkey('ctrl+v');
// Alt+Tabawait sandbox.computerUse.keyboard.hotkey('alt+tab');# Copysandbox.computer_use.keyboard.hotkey(keys: "ctrl+c")
# Pastesandbox.computer_use.keyboard.hotkey(keys: "ctrl+v")
# Alt+Tabsandbox.computer_use.keyboard.hotkey(keys: "alt+tab")// Copyerr := sandbox.ComputerUse.Keyboard().Hotkey(ctx, "ctrl+c")if err != nil { log.Fatal(err)}
// Pasteerr = sandbox.ComputerUse.Keyboard().Hotkey(ctx, "ctrl+v")
// Alt+Taberr = sandbox.ComputerUse.Keyboard().Hotkey(ctx, "alt+tab")// Copysandbox.computerUse.pressHotkey("ctrl", "c");
// Pastesandbox.computerUse.pressHotkey("ctrl", "v");
// Alt+Tabsandbox.computerUse.pressHotkey("alt", "tab");curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/keyboard/hotkey' \ --request POST \ --header 'Content-Type: application/json' \ --data '{ "keys": "ctrl+c"}'Supported keys
Section titled “Supported keys”keyboard.press() and keyboard.hotkey() are case-insensitive for named keys. The following are supported:
| Category | Keys |
|---|---|
| Modifiers | ctrl, alt, shift, cmd |
| Editing | enter, escape, tab, backspace, delete, space |
| Navigation | home, end, pageup, pagedown, insert, arrow keys (up, down, left, right) |
| Function keys | f1 through f24 |
| Numpad | num0–num9, num_plus, num_minus, num_asterisk, num_slash, num_decimal, num_enter, num_equal, num_lock |
| Letters and digits | a–z (case-insensitive), 0–9 |
| Punctuation | ` - = [ ] \ ; ' , . / |
| Other | capslock, menu |
Common aliases like Return → enter, control → ctrl, command / meta / win → cmd, and option → alt are normalized automatically. Unsupported or malformed inputs return an error, sometimes with a suggested alternative.
Screenshot operations
Section titled “Screenshot operations”Take full screen
Section titled “Take full screen”Take a screenshot of the entire screen.
screenshot = sandbox.computer_use.screenshot.take_full_screen()print(f"Screenshot size: {screenshot.width}x{screenshot.height}")
# With cursor visiblewith_cursor = sandbox.computer_use.screenshot.take_full_screen(True)const screenshot = await sandbox.computerUse.screenshot.takeFullScreen();console.log(`Screenshot size: ${screenshot.width}x${screenshot.height}`);
// With cursor visibleconst withCursor = await sandbox.computerUse.screenshot.takeFullScreen(true);screenshot = sandbox.computer_use.screenshot.take_full_screenputs "Screenshot size: #{screenshot.width}x#{screenshot.height}"
# With cursor visiblewith_cursor = sandbox.computer_use.screenshot.take_full_screen(show_cursor: true)screenshot, err := sandbox.ComputerUse.Screenshot().TakeFullScreen(ctx, nil)if err != nil { log.Fatal(err)}
fmt.Printf("Screenshot captured, size: %d bytes\n", *screenshot.SizeBytes)
// With cursor visibleshowCursor := truewithCursor, err := sandbox.ComputerUse.Screenshot().TakeFullScreen(ctx, &showCursor)var screenshot = sandbox.computerUse.takeScreenshot();Integer sizeBytes = screenshot.getSizeBytes();System.out.println("Screenshot payload size: " + (sizeBytes != null ? sizeBytes + " bytes" : "n/a"));
// With cursor visiblevar withCursor = sandbox.computerUse.takeScreenshot(true);curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/screenshot'Take region
Section titled “Take region”Take a screenshot of a specific region.
from daytona import ScreenshotRegion
region = ScreenshotRegion(x=100, y=100, width=300, height=200)screenshot = sandbox.computer_use.screenshot.take_region(region)print(f"Captured region: {screenshot.region.width}x{screenshot.region.height}")const region = { x: 100, y: 100, width: 300, height: 200 };const screenshot = await sandbox.computerUse.screenshot.takeRegion(region);console.log(`Captured region: ${screenshot.region.width}x${screenshot.region.height}`);region = Daytona::ComputerUse::ScreenshotRegion.new(x: 100, y: 100, width: 300, height: 200)screenshot = sandbox.computer_use.screenshot.take_region(region: region)puts "Captured region: #{screenshot.region.width}x#{screenshot.region.height}"region := types.ScreenshotRegion{X: 100, Y: 100, Width: 300, Height: 200}screenshot, err := sandbox.ComputerUse.Screenshot().TakeRegion(ctx, region, nil)if err != nil { log.Fatal(err)}
fmt.Printf("Captured region: %dx%d\n", screenshot.Width, screenshot.Height)var screenshot = sandbox.computerUse.takeRegionScreenshot(100, 100, 300, 200);Integer sizeBytes = screenshot.getSizeBytes();System.out.println("Captured region, payload size: " + (sizeBytes != null ? sizeBytes + " bytes" : "n/a"));curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/screenshot/region?x=1&y=1&width=1&height=1'Take compressed
Section titled “Take compressed”Take a compressed screenshot of the entire screen.
from daytona import ScreenshotOptions
# Default compressionscreenshot = sandbox.computer_use.screenshot.take_compressed()
# High quality JPEGjpeg = sandbox.computer_use.screenshot.take_compressed( ScreenshotOptions(format="jpeg", quality=95, show_cursor=True))
# Scaled down PNGscaled = sandbox.computer_use.screenshot.take_compressed( ScreenshotOptions(format="png", scale=0.5))// Default compressionconst screenshot = await sandbox.computerUse.screenshot.takeCompressed();
// High quality JPEGconst jpeg = await sandbox.computerUse.screenshot.takeCompressed({ format: 'jpeg', quality: 95, showCursor: true});
// Scaled down PNGconst scaled = await sandbox.computerUse.screenshot.takeCompressed({ format: 'png', scale: 0.5});# Default compressionscreenshot = sandbox.computer_use.screenshot.take_compressed
# High quality JPEGjpeg = sandbox.computer_use.screenshot.take_compressed( options: Daytona::ComputerUse::ScreenshotOptions.new(format: "jpeg", quality: 95, show_cursor: true))
# Scaled down PNGscaled = sandbox.computer_use.screenshot.take_compressed( options: Daytona::ComputerUse::ScreenshotOptions.new(format: "png", scale: 0.5))// Compressed full screen (format, quality 1-100, scale factor)var screenshot = sandbox.computerUse.takeCompressedScreenshot("png", 80, 1.0);
// High quality JPEG at full scalevar jpeg = sandbox.computerUse.takeCompressedScreenshot("jpeg", 95, 1.0);
// Scaled down PNGvar scaled = sandbox.computerUse.takeCompressedScreenshot("png", 80, 0.5);curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/screenshot/compressed'Take compressed region
Section titled “Take compressed region”Take a compressed screenshot of a specific region.
from daytona import ScreenshotRegion, ScreenshotOptions
region = ScreenshotRegion(x=0, y=0, width=800, height=600)screenshot = sandbox.computer_use.screenshot.take_compressed_region( region, ScreenshotOptions(format="webp", quality=80, show_cursor=True))print(f"Compressed size: {screenshot.size_bytes} bytes")const region = { x: 0, y: 0, width: 800, height: 600 };const screenshot = await sandbox.computerUse.screenshot.takeCompressedRegion(region, { format: 'webp', quality: 80, showCursor: true});console.log(`Compressed size: ${screenshot.size_bytes} bytes`);region = Daytona::ComputerUse::ScreenshotRegion.new(x: 0, y: 0, width: 800, height: 600)screenshot = sandbox.computer_use.screenshot.take_compressed_region( region: region, options: Daytona::ComputerUse::ScreenshotOptions.new(format: "webp", quality: 80, show_cursor: true))puts "Compressed size: #{screenshot.size_bytes} bytes"curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/screenshot/region/compressed?x=1&y=1&width=1&height=1'Screen Recording
Section titled “Screen Recording”Computer Use supports screen recording capabilities, allowing you to capture desktop sessions for debugging, documentation, or automation workflows.
Configure Recording Directory
Section titled “Configure Recording Directory”By default, recordings are saved to ~/.daytona/recordings. You can specify a custom directory by passing the DAYTONA_RECORDINGS_DIR environment variable when creating a sandbox:
from daytona import Daytona, CreateSandboxFromSnapshotParams
daytona = Daytona()sandbox = daytona.create( CreateSandboxFromSnapshotParams( snapshot="daytonaio/sandbox:0.6.0", name="my-sandbox", env_vars={"DAYTONA_RECORDINGS_DIR": "/home/daytona/my-recordings"} ))import { Daytona } from '@daytona/sdk';
const daytona = new Daytona();const sandbox = await daytona.create({ snapshot: 'daytonaio/sandbox:0.6.0', name: 'my-sandbox', envVars: { DAYTONA_RECORDINGS_DIR: '/home/daytona/my-recordings' }});require 'daytona'
daytona = Daytona::Client.newsandbox = daytona.create( snapshot: 'daytonaio/sandbox:0.6.0', name: 'my-sandbox', env_vars: { DAYTONA_RECORDINGS_DIR: '/home/daytona/my-recordings' })import ( "github.com/daytonaio/daytona/pkg/client" "github.com/daytonaio/daytona/pkg/types")
daytona := client.New()envVars := map[string]string{ "DAYTONA_RECORDINGS_DIR": "/home/daytona/my-recordings",}
sandbox, err := daytona.Create(ctx, &types.CreateSandboxParams{ Snapshot: "daytonaio/sandbox:0.6.0", Name: "my-sandbox", EnvVars: envVars,})if err != nil { log.Fatal(err)}import io.daytona.sdk.Daytona;import io.daytona.sdk.Sandbox;import io.daytona.sdk.model.CreateSandboxFromSnapshotParams;
import java.util.Map;
try (Daytona daytona = new Daytona()) { CreateSandboxFromSnapshotParams params = new CreateSandboxFromSnapshotParams(); params.setSnapshot("daytonaio/sandbox:0.6.0"); params.setName("my-sandbox"); params.setEnvVars(Map.of("DAYTONA_RECORDINGS_DIR", "/home/daytona/my-recordings")); Sandbox sandbox = daytona.create(params);}Start Recording
Section titled “Start Recording”Start a new screen recording session with an optional name identifier:
# Start recording with a custom namerecording = sandbox.computer_use.recording.start("test-1")print(f"Recording started: {recording.id}")print(f"File path: {recording.file_path}")// Start recording with a custom nameconst recording = await sandbox.computerUse.recording.start('test-1');console.log(`Recording started: ${recording.id}`);console.log(`File path: ${recording.file_path}`);# Start recording with a custom labelrecording = sandbox.computer_use.recording.start(label: 'test-1')puts "Recording started: #{recording.id}"puts "File path: #{recording.file_path}"// Start recording with a custom namename := "test-1"recording, err := sandbox.ComputerUse.Recording().Start(ctx, &name)if err != nil { log.Fatal(err)}
fmt.Printf("Recording started: %s\n", *recording.Id)fmt.Printf("File path: %s\n", *recording.FilePath)// Start recording with a custom labelvar recording = sandbox.computerUse.startRecording("test-1");System.out.println("Recording started: " + recording.getId());System.out.println("File path: " + recording.getFilePath());curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/recordings/start' \ --request POST \ --header 'Content-Type: application/json' \ --data '{ "name": "test-1"}'Stop Recording
Section titled “Stop Recording”Stop an active recording session by providing the recording ID:
# Stop the recordingstopped_recording = sandbox.computer_use.recording.stop(recording.id)print(f"Recording stopped: {stopped_recording.duration_seconds} seconds")print(f"Saved to: {stopped_recording.file_path}")// Stop the recordingconst stoppedRecording = await sandbox.computerUse.recording.stop(recording.id);console.log(`Recording stopped: ${stoppedRecording.duration_seconds} seconds`);console.log(`Saved to: ${stoppedRecording.file_path}`);# Stop the recordingstopped_recording = sandbox.computer_use.recording.stop(id: recording.id)puts "Recording stopped: #{stopped_recording.duration_seconds} seconds"puts "Saved to: #{stopped_recording.file_path}"// Stop the recordingstoppedRecording, err := sandbox.ComputerUse.Recording().Stop(ctx, *recording.Id)if err != nil { log.Fatal(err)}
fmt.Printf("Recording stopped: %f seconds\n", *stoppedRecording.DurationSeconds)fmt.Printf("Saved to: %s\n", *stoppedRecording.FilePath)// Stop the recordingvar stoppedRecording = sandbox.computerUse.stopRecording(recording.getId());System.out.println("Recording stopped: " + stoppedRecording.getDurationSeconds() + " seconds");System.out.println("Saved to: " + stoppedRecording.getFilePath());curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/recordings/stop' \ --request POST \ --header 'Content-Type: application/json' \ --data '{ "id": "recording-id"}'List Recordings
Section titled “List Recordings”Get a list of all recordings in the sandbox:
recordings_list = sandbox.computer_use.recording.list()print(f"Total recordings: {len(recordings_list.recordings)}")for rec in recordings_list.recordings: print(f"- {rec.name}: {rec.duration_seconds}s ({rec.file_size_bytes} bytes)")const recordingsList = await sandbox.computerUse.recording.list();console.log(`Total recordings: ${recordingsList.recordings.length}`);recordingsList.recordings.forEach(rec => { console.log(`- ${rec.name}: ${rec.duration_seconds}s (${rec.file_size_bytes} bytes)`);});recordings_list = sandbox.computer_use.recording.listputs "Total recordings: #{recordings_list.recordings.length}"recordings_list.recordings.each do |rec| puts "- #{rec.name}: #{rec.duration_seconds}s (#{rec.file_size_bytes} bytes)"endrecordingsList, err := sandbox.ComputerUse.Recording().List(ctx)if err != nil { log.Fatal(err)}
fmt.Printf("Total recordings: %d\n", len(recordingsList.Recordings))for _, rec := range recordingsList.Recordings { fmt.Printf("- %s: %.2fs (%d bytes)\n", *rec.Name, *rec.DurationSeconds, *rec.FileSizeBytes)}var recordingsList = sandbox.computerUse.listRecordings();System.out.println("Total recordings: " + recordingsList.getRecordings().size());for (var rec : recordingsList.getRecordings()) { System.out.println( "- " + rec.getFileName() + ": " + rec.getDurationSeconds() + "s (" + rec.getSizeBytes() + " bytes)" );}curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/recordings'Get Recording
Section titled “Get Recording”Get details about a specific recording:
recording_detail = sandbox.computer_use.recording.get("recording-id")print(f"Recording: {recording_detail.name}")print(f"Status: {recording_detail.status}")print(f"Duration: {recording_detail.duration_seconds}s")const recordingDetail = await sandbox.computerUse.recording.get('recording-id');console.log(`Recording: ${recordingDetail.name}`);console.log(`Status: ${recordingDetail.status}`);console.log(`Duration: ${recordingDetail.duration_seconds}s`);recording_detail = sandbox.computer_use.recording.get(id: 'recording-id')puts "Recording: #{recording_detail.name}"puts "Status: #{recording_detail.status}"puts "Duration: #{recording_detail.duration_seconds}s"recordingDetail, err := sandbox.ComputerUse.Recording().Get(ctx, "recording-id")if err != nil { log.Fatal(err)}
fmt.Printf("Recording: %s\n", *recordingDetail.Name)fmt.Printf("Status: %s\n", *recordingDetail.Status)fmt.Printf("Duration: %.2fs\n", *recordingDetail.DurationSeconds)var recordingDetail = sandbox.computerUse.getRecording("recording-id");System.out.println("Recording: " + recordingDetail.getFileName());System.out.println("Status: " + recordingDetail.getStatus());System.out.println("Duration: " + recordingDetail.getDurationSeconds() + "s");curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/recordings/{id}'Delete Recording
Section titled “Delete Recording”Delete a recording by ID:
sandbox.computer_use.recording.delete("recording-id")print("Recording deleted successfully")await sandbox.computerUse.recording.delete('recording-id');console.log('Recording deleted successfully');sandbox.computer_use.recording.delete(id: 'recording-id')puts 'Recording deleted successfully'err := sandbox.ComputerUse.Recording().Delete(ctx, "recording-id")if err != nil { log.Fatal(err)}
fmt.Println("Recording deleted successfully")sandbox.computerUse.deleteRecording("recording-id");System.out.println("Recording deleted successfully");curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/recordings/{id}' \ --request DELETEDownload Recording
Section titled “Download Recording”Download a recording file from the sandbox to your local machine. The file is streamed efficiently without loading the entire content into memory, making it suitable for large recordings.
# Download recording to local filesandbox.computer_use.recording.download(recording.id, "local_recording.mp4")print("Recording downloaded successfully")
# Or with custom pathimport osdownload_path = os.path.join("recordings", f"recording_{recording.id}.mp4")sandbox.computer_use.recording.download(recording.id, download_path)// Download recording to local fileawait sandbox.computerUse.recording.download(recording.id, 'local_recording.mp4');console.log('Recording downloaded successfully');
// Or with custom pathconst downloadPath = `recordings/recording_${recording.id}.mp4`;await sandbox.computerUse.recording.download(recording.id, downloadPath);# Download recording to local filesandbox.computer_use.recording.download(id: recording.id, local_path: 'local_recording.mp4')puts 'Recording downloaded successfully'
# Or with custom pathdownload_path = "recordings/recording_#{recording.id}.mp4"sandbox.computer_use.recording.download(id: recording.id, local_path: download_path)// Download recording to local fileerr := sandbox.ComputerUse.Recording().Download(ctx, recording.GetId(), "local_recording.mp4")if err != nil { log.Fatal(err)}fmt.Println("Recording downloaded successfully")
// Or with custom pathdownloadPath := fmt.Sprintf("recordings/recording_%s.mp4", recording.GetId())err = sandbox.ComputerUse.Recording().Download(ctx, recording.GetId(), downloadPath)import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.StandardCopyOption;
// Download returns a temp file from the API client; copy it to a stable pathvar tempFile = sandbox.computerUse.downloadRecording(recording.getId());Files.copy(tempFile.toPath(), Path.of("local_recording.mp4"), StandardCopyOption.REPLACE_EXISTING);System.out.println("Recording saved to local_recording.mp4");
var downloadPath = Path.of("recordings", "recording_" + recording.getId() + ".mp4");Files.createDirectories(downloadPath.getParent());Files.copy(tempFile.toPath(), downloadPath, StandardCopyOption.REPLACE_EXISTING);curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/recordings/{id}/download' \ --output local_recording.mp4Recording Dashboard
Section titled “Recording Dashboard”Every sandbox includes a built-in recording dashboard for managing screen recordings through a web interface. The dashboard allows you to view, download, and delete recordings without writing code.
To access the recording dashboard:
- Navigate to your sandboxes in the Daytona Dashboard
- Click the action menu (three dots) for your sandbox
- Select Screen Recordings from the dropdown menu
The recording dashboard provides:
- List of all recordings with metadata (name, duration, file size, creation time)
- Playback controls for reviewing recordings
- Download functionality to save recordings locally
- Delete options for managing storage
Display operations
Section titled “Display operations”Get info
Section titled “Get info”Get information about the displays.
info = sandbox.computer_use.display.get_info()print(f"Primary display: {info.primary_display.width}x{info.primary_display.height}")print(f"Total displays: {info.total_displays}")for i, display in enumerate(info.displays): print(f"Display {i}: {display.width}x{display.height} at {display.x},{display.y}")const info = await sandbox.computerUse.display.getInfo();console.log(`Primary display: ${info.primary_display.width}x${info.primary_display.height}`);console.log(`Total displays: ${info.total_displays}`);info.displays.forEach((display, index) => { console.log(`Display ${index}: ${display.width}x${display.height} at ${display.x},${display.y}`);});info = sandbox.computer_use.display.infoputs "Primary display: #{info.primary_display.width}x#{info.primary_display.height}"puts "Total displays: #{info.total_displays}"info.displays.each_with_index do |display, i| puts "Display #{i}: #{display.width}x#{display.height} at #{display.x},#{display.y}"endinfo, err := sandbox.ComputerUse.Display().GetInfo(ctx)if err != nil { log.Fatal(err)}
fmt.Printf("Displays: %v\n", info["displays"])var info = sandbox.computerUse.getDisplayInfo();if (info.getDisplays() != null) { for (var display : info.getDisplays()) { System.out.println( "Display " + display.getId() + ": " + display.getWidth() + "x" + display.getHeight() + " at " + display.getX() + "," + display.getY() ); }}curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/display/info'Get windows
Section titled “Get windows”Get the list of open windows.
windows = sandbox.computer_use.display.get_windows()print(f"Found {windows.count} open windows:")for window in windows.windows: print(f"- {window.title} (ID: {window.id})")const windows = await sandbox.computerUse.display.getWindows();console.log(`Found ${windows.count} open windows:`);windows.windows.forEach(window => { console.log(`- ${window.title} (ID: ${window.id})`);});windows = sandbox.computer_use.display.windowsputs "Found #{windows.count} open windows:"windows.windows.each do |window| puts "- #{window.title} (ID: #{window.id})"endresult, err := sandbox.ComputerUse.Display().GetWindows(ctx)if err != nil { log.Fatal(err)}
fmt.Printf("Open windows: %v\n", result["windows"])var windows = sandbox.computerUse.getWindows();var list = windows.getWindows();if (list != null) { System.out.println("Found " + list.size() + " open windows:"); for (var window : list) { System.out.println("- " + window.getTitle() + " (ID: " + window.getId() + ")"); }}curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/display/windows'