computer use linux

Computer Use

Copy for LLMView as MarkdownOpen

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 and Windows through Daytona. For macOS sandboxes and Computer Use, see macOS sandboxes.

# 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.start

puts "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 POST

# Stop 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.stop

puts "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 POST

# Get 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.status

puts "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());
# Status of the computer use system

curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/status'

# Status of all computer use processes

curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/process-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(process_name: "xvfb")

no_vnc_status = sandbox.computer_use.get_process_status(process_name: "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(process_name: "xfce4")

puts "XFCE4 process restarted: #{result.message}"
curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/process/{processName}/restart' \

--request POST

# Get 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(process_name: "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(process_name: "x11vnc")

puts "X11VNC errors: #{errors}"
curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/process/{processName}/errors'

# Mouse operations

Section titled “Mouse operations”

# Click

Section titled “Click”

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 click

result = sandbox.computer_use.mouse.click(100, 200)

# Double click

double_click = sandbox.computer_use.mouse.click(100, 200, "left", True)

# Right click

right_click = sandbox.computer_use.mouse.click(100, 200, "right")
// Single left click

const result = await sandbox.computerUse.mouse.click(100, 200);

// Double click

const doubleClick = await sandbox.computerUse.mouse.click(100, 200, 'left', true);

// Right click

const rightClick = await sandbox.computerUse.mouse.click(100, 200, 'right');
# Single left click

result = sandbox.computer_use.mouse.click(x: 100, y: 200)

# Double click

double_click = sandbox.computer_use.mouse.click(x: 100, y: 200, button: 'left', double: true)

# Right click

right_click = sandbox.computer_use.mouse.click(x: 100, y: 200, button: 'right')
// Single left click

result, err := sandbox.ComputerUse.Mouse().Click(ctx, 100, 200, nil, nil)

if err != nil {

log.Fatal(err)

}

// Double click

doubleClick := true

result, err = sandbox.ComputerUse.Mouse().Click(ctx, 100, 200, nil, &doubleClick)

// Right click

rightButton := "right"

result, err = sandbox.ComputerUse.Mouse().Click(ctx, 100, 200, &rightButton, nil)
// Single left click

sandbox.computerUse.click(100, 200);

// Double click

sandbox.computerUse.doubleClick(100, 200);

// Right click

sandbox.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

Section titled “Move”

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

Section titled “Drag”

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

}'

# Hold and release button

Section titled “Hold and release button”

Press and hold a mouse button, then release it. The button stays held until a matching release call, which lets you compose press-move-release gestures such as marquee selection or drawing strokes. When X and Y coordinates are provided, the cursor moves to that position before the button is pressed or released; when omitted, the action happens at the current cursor position. Button is one of left (default), right, or middle.

To hold a modifier key during the gesture, wrap it with the keyboard hold and release calls.

# Press the left button at (100, 200) and release it at (300, 400)

sandbox.computer_use.mouse.down(100, 200)

result = sandbox.computer_use.mouse.up(300, 400)

print(f"Released at {result.x}, {result.y}")

# Press and release the right button at the current cursor position

sandbox.computer_use.mouse.down(button="right")

sandbox.computer_use.mouse.up(button="right")
// Press the left button at (100, 200) and release it at (300, 400)

await sandbox.computerUse.mouse.down(100, 200);

const result = await sandbox.computerUse.mouse.up(300, 400);

console.log(`Released at ${result.x}, ${result.y}`);

// Press and release the right button at the current cursor position

await sandbox.computerUse.mouse.down(undefined, undefined, 'right');

await sandbox.computerUse.mouse.up(undefined, undefined, 'right');
# Press the left button at (100, 200) and release it at (300, 400)

sandbox.computer_use.mouse.down(x: 100, y: 200)

result = sandbox.computer_use.mouse.up(x: 300, y: 400)

puts "Released at #{result.x}, #{result.y}"

# Press and release the right button at the current cursor position

sandbox.computer_use.mouse.down(button: 'right')

sandbox.computer_use.mouse.up(button: 'right')
// Press the left button at (100, 200) and release it at (300, 400)

startX, startY := 100, 200

if _, err := sandbox.ComputerUse.Mouse().Down(ctx, nil, &startX, &startY); err != nil {

log.Fatal(err)

}

endX, endY := 300, 400

result, err := sandbox.ComputerUse.Mouse().Up(ctx, nil, &endX, &endY)

if err != nil {

log.Fatal(err)

}

fmt.Printf("Released at %v, %v\n", result["x"], result["y"])

// Press and release the right button at the current cursor position

rightButton := "right"

_, err = sandbox.ComputerUse.Mouse().Down(ctx, &rightButton, nil, nil)

_, err = sandbox.ComputerUse.Mouse().Up(ctx, &rightButton, nil, nil)
// Press the left button at (100, 200) and release it at (300, 400)

sandbox.computerUse.mouseDown(100, 200);

var result = sandbox.computerUse.mouseUp(300, 400);

System.out.println("Released at " + result.getX() + ", " + result.getY());

// Press and release the right button at the current cursor position

sandbox.computerUse.mouseDown("right");

sandbox.computerUse.mouseUp("right");
curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/mouse/down' \

--request POST \

--header 'Content-Type: application/json' \

--data '{

"button": "left",

"x": 100,

"y": 200

}'

curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/mouse/up' \

--request POST \

--header 'Content-Type: application/json' \

--data '{

"button": "left",

"x": 300,

"y": 400

}'

# 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 up

scroll_up = sandbox.computer_use.mouse.scroll(100, 200, "up", 3)

# Scroll down

scroll_down = sandbox.computer_use.mouse.scroll(100, 200, "down", 5)
// Scroll up

const scrollUp = await sandbox.computerUse.mouse.scroll(100, 200, 'up', 3);

// Scroll down

const scrollDown = await sandbox.computerUse.mouse.scroll(100, 200, 'down', 5);
# Scroll up

scroll_up = sandbox.computer_use.mouse.scroll(x: 100, y: 200, direction: 'up', amount: 3)

# Scroll down

scroll_down = sandbox.computer_use.mouse.scroll(x: 100, y: 200, direction: 'down', amount: 5)
// Scroll up

amount := 3

success, err := sandbox.ComputerUse.Mouse().Scroll(ctx, 100, 200, "up", &amount)

if err != nil {

log.Fatal(err)

}

// Scroll down

amount = 5

success, 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 down

sandbox.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.position

puts "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”

# Type

Section titled “Type”

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 characters

sandbox.computer_use.keyboard.type("Slow typing", 100)
await sandbox.computerUse.keyboard.type('Hello, World!');

// With delay between characters

await sandbox.computerUse.keyboard.type('Slow typing', 100);
sandbox.computer_use.keyboard.type(text: "Hello, World!")

# With delay between characters

sandbox.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 characters

delay := 100

err = 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

Section titled “Press”

Press a key with optional modifiers.

# Press Enter

sandbox.computer_use.keyboard.press("enter")

# Press Ctrl+C

sandbox.computer_use.keyboard.press("c", ["ctrl"])

# Press Ctrl+Shift+T

sandbox.computer_use.keyboard.press("t", ["ctrl", "shift"])
// Press Enter

await sandbox.computerUse.keyboard.press('enter');

// Press Ctrl+C

await sandbox.computerUse.keyboard.press('c', ['ctrl']);

// Press Ctrl+Shift+T

await sandbox.computerUse.keyboard.press('t', ['ctrl', 'shift']);
# Press Enter

sandbox.computer_use.keyboard.press(key: "enter")

# Press Ctrl+C

sandbox.computer_use.keyboard.press(key: "c", modifiers: ["ctrl"])

# Press Ctrl+Shift+T

sandbox.computer_use.keyboard.press(key: "t", modifiers: ["ctrl", "shift"])
// Press Enter

err := sandbox.ComputerUse.Keyboard().Press(ctx, "enter", nil)

if err != nil {

log.Fatal(err)

}

// Press Ctrl+C

err = sandbox.ComputerUse.Keyboard().Press(ctx, "c", []string{"ctrl"})

// Press Ctrl+Shift+T

err = sandbox.ComputerUse.Keyboard().Press(ctx, "t", []string{"ctrl", "shift"})
// Press Enter

sandbox.computerUse.pressKey("enter");

// Press Ctrl+C

sandbox.computerUse.pressHotkey("ctrl", "c");

// Press Ctrl+Shift+T

sandbox.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.

# Copy

sandbox.computer_use.keyboard.hotkey("ctrl+c")

# Paste

sandbox.computer_use.keyboard.hotkey("ctrl+v")

# Alt+Tab

sandbox.computer_use.keyboard.hotkey("alt+tab")
// Copy

await sandbox.computerUse.keyboard.hotkey('ctrl+c');

// Paste

await sandbox.computerUse.keyboard.hotkey('ctrl+v');

// Alt+Tab

await sandbox.computerUse.keyboard.hotkey('alt+tab');
# Copy

sandbox.computer_use.keyboard.hotkey(keys: "ctrl+c")

# Paste

sandbox.computer_use.keyboard.hotkey(keys: "ctrl+v")

# Alt+Tab

sandbox.computer_use.keyboard.hotkey(keys: "alt+tab")
// Copy

err := sandbox.ComputerUse.Keyboard().Hotkey(ctx, "ctrl+c")

if err != nil {

log.Fatal(err)

}

// Paste

err = sandbox.ComputerUse.Keyboard().Hotkey(ctx, "ctrl+v")

// Alt+Tab

err = sandbox.ComputerUse.Keyboard().Hotkey(ctx, "alt+tab")
// Copy

sandbox.computerUse.pressHotkey("ctrl", "c");

// Paste

sandbox.computerUse.pressHotkey("ctrl", "v");

// Alt+Tab

sandbox.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"

}'

# Hold and release key

Section titled “Hold and release key”

Press and hold a key, then release it. The key stays held until a matching release call, which lets you hold a modifier such as shift across several mouse or keyboard actions. Keys use the same names as press, listed in supported keys. Release the key in a finally block (or the language equivalent) so a failed action does not leave the key held.

# Hold Shift while clicking two points, then release it

sandbox.computer_use.keyboard.down("shift")

try:

sandbox.computer_use.mouse.click(100, 200)

sandbox.computer_use.mouse.click(100, 300)

finally:

sandbox.computer_use.keyboard.up("shift")
// Hold Shift while clicking two points, then release it

await sandbox.computerUse.keyboard.down('shift');

try {

await sandbox.computerUse.mouse.click(100, 200);

await sandbox.computerUse.mouse.click(100, 300);

} finally {

await sandbox.computerUse.keyboard.up('shift');

}
# Hold Shift while clicking two points, then release it

sandbox.computer_use.keyboard.down(key: 'shift')

begin

sandbox.computer_use.mouse.click(x: 100, y: 200)

sandbox.computer_use.mouse.click(x: 100, y: 300)

ensure

sandbox.computer_use.keyboard.up(key: 'shift')

end
// Hold Shift while clicking two points, then release it

keyboard := sandbox.ComputerUse.Keyboard()

if err := keyboard.KeyDown(ctx, "shift"); err != nil {

log.Fatal(err)

}

defer keyboard.KeyUp(ctx, "shift")

if _, err := sandbox.ComputerUse.Mouse().Click(ctx, 100, 200, nil, nil); err != nil {

log.Fatal(err)

}

if _, err := sandbox.ComputerUse.Mouse().Click(ctx, 100, 300, nil, nil); err != nil {

log.Fatal(err)

}
// Hold Shift while clicking two points, then release it

sandbox.computerUse.keyDown("shift");

try {

sandbox.computerUse.click(100, 200);

sandbox.computerUse.click(100, 300);

} finally {

sandbox.computerUse.keyUp("shift");

}
curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/keyboard/down' \

--request POST \

--header 'Content-Type: application/json' \

--data '{

"key": "shift"

}'

curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/keyboard/up' \

--request POST \

--header 'Content-Type: application/json' \

--data '{

"key": "shift"

}'

# Supported keys

Section titled “Supported keys”

keyboard.press(), keyboard.hotkey(), keyboard.down(), and keyboard.up() 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.

# Accessibility operations

Section titled “Accessibility operations”

Use Linux accessibility operations to inspect the AT-SPI tree and interact with UI elements by node ID. Start Computer Use before calling accessibility methods.

# Get tree

Section titled “Get tree”

Read an accessibility tree for the focused app, a specific process, or all apps.

# Focused app

focused_tree = sandbox.computer_use.accessibility.get_tree(scope="focused", max_depth=2)

# Specific process

process_tree = sandbox.computer_use.accessibility.get_tree(

scope="pid",

pid=1234,

max_depth=2,

)

# All apps

desktop_tree = sandbox.computer_use.accessibility.get_tree(scope="all", max_depth=2)
// Focused app

const focusedTree = await sandbox.computerUse.accessibility.getTree({

scope: 'focused',

maxDepth: 2,

});

// Specific process

const processTree = await sandbox.computerUse.accessibility.getTree({

scope: 'pid',

pid: 1234,

maxDepth: 2,

});

// All apps

const desktopTree = await sandbox.computerUse.accessibility.getTree({

scope: 'all',

maxDepth: 2,

});
# Focused app

focused_tree = sandbox.computer_use.accessibility.get_tree(scope: "focused", max_depth: 2)

# Specific process

process_tree = sandbox.computer_use.accessibility.get_tree(

scope: "pid",

pid: 1234,

max_depth: 2

)

# All apps

desktop_tree = sandbox.computer_use.accessibility.get_tree(scope: "all", max_depth: 2)
maxDepth := 2

// Focused app

focusedScope := "focused"

focusedTree, err := sandbox.ComputerUse.Accessibility().GetTree(ctx, &daytona.AccessibilityTreeOptions{

Scope:    &focusedScope,

MaxDepth: &maxDepth,

})

if err != nil {

log.Fatal(err)

}

// Specific process

processScope := "pid"

pid := 1234

processTree, err := sandbox.ComputerUse.Accessibility().GetTree(ctx, &daytona.AccessibilityTreeOptions{

Scope:    &processScope,

PID:      &pid,

MaxDepth: &maxDepth,

})

if err != nil {

log.Fatal(err)

}

// All apps

allScope := "all"

desktopTree, err := sandbox.ComputerUse.Accessibility().GetTree(ctx, &daytona.AccessibilityTreeOptions{

Scope:    &allScope,

MaxDepth: &maxDepth,

})

if err != nil {

log.Fatal(err)

}
// Focused app

var focusedTree = sandbox.computerUse.getAccessibilityTree("focused", null, 2);

// Specific process

var processTree = sandbox.computerUse.getAccessibilityTree("pid", 1234, 2);

// All apps

var desktopTree = sandbox.computerUse.getAccessibilityTree("all", null, 2);
# Focused app

curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/a11y/tree?scope=focused&maxDepth=2'

# Specific process

curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/a11y/tree?scope=pid&pid=1234&maxDepth=2'

# All apps

curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/a11y/tree?scope=all&maxDepth=2'

# Find nodes

Section titled “Find nodes”

Search the accessibility tree by role, accessible name, state, and scope.

# Find buttons by accessible name

buttons = sandbox.computer_use.accessibility.find_nodes(

scope="focused",

role="button",

name="Submit",

name_match="substring",

limit=10,

)

# Find text entries in a process

entries = sandbox.computer_use.accessibility.find_nodes(

scope="pid",

pid=1234,

role="entry",

states=["enabled", "focusable"],

limit=10,

)

# Find visible nodes across all apps

visible_nodes = sandbox.computer_use.accessibility.find_nodes(

scope="all",

states=["visible"],

limit=20,

)
// Find buttons by accessible name

const buttons = await sandbox.computerUse.accessibility.findNodes({

scope: 'focused',

role: 'button',

name: 'Submit',

nameMatch: 'substring',

limit: 10,

});

// Find text entries in a process

const entries = await sandbox.computerUse.accessibility.findNodes({

scope: 'pid',

pid: 1234,

role: 'entry',

states: ['enabled', 'focusable'],

limit: 10,

});

// Find visible nodes across all apps

const visibleNodes = await sandbox.computerUse.accessibility.findNodes({

scope: 'all',

states: ['visible'],

limit: 20,

});
# Find buttons by accessible name

buttons = sandbox.computer_use.accessibility.find_nodes(

scope: "focused",

role: "button",

name: "Submit",

name_match: "substring",

limit: 10

)

# Find text entries in a process

entries = sandbox.computer_use.accessibility.find_nodes(

scope: "pid",

pid: 1234,

role: "entry",

states: ["enabled", "focusable"],

limit: 10

)

# Find visible nodes across all apps

visible_nodes = sandbox.computer_use.accessibility.find_nodes(

scope: "all",

states: ["visible"],

limit: 20

)
limit := 10

// Find buttons by accessible name

focusedScope := "focused"

buttonRole := "button"

submitName := "Submit"

substringMatch := "substring"

buttons, err := sandbox.ComputerUse.Accessibility().FindNodes(ctx, &daytona.AccessibilityFindOptions{

Scope:     &focusedScope,

Role:      &buttonRole,

Name:      &submitName,

NameMatch: &substringMatch,

Limit:     &limit,

})

if err != nil {

log.Fatal(err)

}

// Find text entries in a process

processScope := "pid"

pid := 1234

entryRole := "entry"

entries, err := sandbox.ComputerUse.Accessibility().FindNodes(ctx, &daytona.AccessibilityFindOptions{

Scope:  &processScope,

PID:    &pid,

Role:   &entryRole,

States: []string{"enabled", "focusable"},

Limit:  &limit,

})

if err != nil {

log.Fatal(err)

}

// Find visible nodes across all apps

allScope := "all"

visibleLimit := 20

visibleNodes, err := sandbox.ComputerUse.Accessibility().FindNodes(ctx, &daytona.AccessibilityFindOptions{

Scope:  &allScope,

States: []string{"visible"},

Limit:  &visibleLimit,

})

if err != nil {

log.Fatal(err)

}
// Find buttons by accessible name

var buttons = sandbox.computerUse.findAccessibilityNodes(

new FindAccessibilityNodesRequest()

.scope("focused")

.role("button")

.name("Submit")

.nameMatch("substring")

.limit(10)

);

// Find text entries in a process

var entries = sandbox.computerUse.findAccessibilityNodes(

new FindAccessibilityNodesRequest()

.scope("pid")

.pid(1234)

.role("entry")

.states(java.util.List.of("enabled", "focusable"))

.limit(10)

);

// Find visible nodes across all apps

var visibleNodes = sandbox.computerUse.findAccessibilityNodes(

new FindAccessibilityNodesRequest()

.scope("all")

.states(java.util.List.of("visible"))

.limit(20)

);
# Find buttons by accessible name

curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/a11y/find' \

--request POST \

--header 'Content-Type: application/json' \

--data '{

"scope": "focused",

"role": "button",

"name": "Submit",

"nameMatch": "substring",

"limit": 10

}'

# Find text entries in a process

curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/a11y/find' \

--request POST \

--header 'Content-Type: application/json' \

--data '{

"scope": "pid",

"pid": 1234,

"role": "entry",

"states": ["enabled", "focusable"],

"limit": 10

}'

# Find visible nodes across all apps

curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/a11y/find' \

--request POST \

--header 'Content-Type: application/json' \

--data '{

"scope": "all",

"states": ["visible"],

"limit": 20

}'

# Focus node

Section titled “Focus node”

Move keyboard focus to a node returned by get_tree or find_nodes.

sandbox.computer_use.accessibility.focus_node("node-id")
await sandbox.computerUse.accessibility.focusNode('node-id');
sandbox.computer_use.accessibility.focus_node(id: "node-id")
if err := sandbox.ComputerUse.Accessibility().FocusNode(ctx, "node-id"); err != nil {

log.Fatal(err)

}
sandbox.computerUse.focusAccessibilityNode("node-id");
curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/a11y/node/focus' \

--request POST \

--header 'Content-Type: application/json' \

--data '{"id":"node-id"}'

# Invoke node

Section titled “Invoke node”

Run a node action, such as pressing a button.

# Invoke the primary action

sandbox.computer_use.accessibility.invoke_node("node-id")

# Invoke a named action

sandbox.computer_use.accessibility.invoke_node("node-id", action="click")
// Invoke the primary action

await sandbox.computerUse.accessibility.invokeNode('node-id');

// Invoke a named action

await sandbox.computerUse.accessibility.invokeNode('node-id', 'click');
# Invoke the primary action

sandbox.computer_use.accessibility.invoke_node(id: "node-id")

# Invoke a named action

sandbox.computer_use.accessibility.invoke_node(id: "node-id", action: "click")
// Invoke the primary action

if err := sandbox.ComputerUse.Accessibility().InvokeNode(ctx, "node-id", nil); err != nil {

log.Fatal(err)

}

// Invoke a named action

action := "click"

if err := sandbox.ComputerUse.Accessibility().InvokeNode(ctx, "node-id", &action); err != nil {

log.Fatal(err)

}
// Invoke the primary action

sandbox.computerUse.invokeAccessibilityNode("node-id");

// Invoke a named action

sandbox.computerUse.invokeAccessibilityNode("node-id", "click");
# Invoke the primary action

curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/a11y/node/invoke' \

--request POST \

--header 'Content-Type: application/json' \

--data '{"id":"node-id"}'

# Invoke a named action

curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/a11y/node/invoke' \

--request POST \

--header 'Content-Type: application/json' \

--data '{"id":"node-id","action":"click"}'

# Set node value

Section titled “Set node value”

Write text or value content to nodes that support value changes.

sandbox.computer_use.accessibility.set_node_value("node-id", "hello")
await sandbox.computerUse.accessibility.setNodeValue('node-id', 'hello');
sandbox.computer_use.accessibility.set_node_value(id: "node-id", value: "hello")
if err := sandbox.ComputerUse.Accessibility().SetNodeValue(ctx, "node-id", "hello"); err != nil {

log.Fatal(err)

}
sandbox.computerUse.setAccessibilityNodeValue("node-id", "hello");
curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/a11y/node/value' \

--request POST \

--header 'Content-Type: application/json' \

--data '{"id":"node-id","value":"hello"}'

# 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 captured, base64 length: {len(screenshot.screenshot)}")

# With cursor visible

with_cursor = sandbox.computer_use.screenshot.take_full_screen(True)
const screenshot = await sandbox.computerUse.screenshot.takeFullScreen();

console.log(`Screenshot captured, base64 length: ${screenshot.screenshot?.length}`);

// With cursor visible

const withCursor = await sandbox.computerUse.screenshot.takeFullScreen(true);
screenshot = sandbox.computer_use.screenshot.take_full_screen

puts "Screenshot captured, base64 length: #{screenshot.screenshot.length}"

# With cursor visible

with_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, base64 length: %d\n", len(screenshot.Image))

// With cursor visible

showCursor := true

withCursor, err := sandbox.ComputerUse.Screenshot().TakeFullScreen(ctx, &showCursor)
var screenshot = sandbox.computerUse.takeScreenshot();

System.out.println("Screenshot captured, base64 length: " + screenshot.getScreenshot().length());

// With cursor visible

var 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.width}x{region.height} region, base64 length: {len(screenshot.screenshot)}")
const region = { x: 100, y: 100, width: 300, height: 200 };

const screenshot = await sandbox.computerUse.screenshot.takeRegion(region);

console.log(`Captured ${region.width}x${region.height} region, base64 length: ${screenshot.screenshot?.length}`);
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.width}x#{region.height} region, base64 length: #{screenshot.screenshot.length}"
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);

System.out.println("Captured 300x200 region, base64 length: " + screenshot.getScreenshot().length());
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 compression

screenshot = sandbox.computer_use.screenshot.take_compressed()

# High quality JPEG

jpeg = sandbox.computer_use.screenshot.take_compressed(

ScreenshotOptions(fmt="jpeg", quality=95, show_cursor=True)

)

# Scaled down PNG

scaled = sandbox.computer_use.screenshot.take_compressed(

ScreenshotOptions(fmt="png", scale=0.5)

)
// Default compression

const screenshot = await sandbox.computerUse.screenshot.takeCompressed();

// High quality JPEG

const jpeg = await sandbox.computerUse.screenshot.takeCompressed({

format: 'jpeg',

quality: 95,

showCursor: true

});

// Scaled down PNG

const scaled = await sandbox.computerUse.screenshot.takeCompressed({

format: 'png',

scale: 0.5

});
# Default compression

screenshot = sandbox.computer_use.screenshot.take_compressed

# High quality JPEG

jpeg = sandbox.computer_use.screenshot.take_compressed(

options: Daytona::ComputerUse::ScreenshotOptions.new(format: "jpeg", quality: 95, show_cursor: true)

)

# Scaled down PNG

scaled = 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 scale

var jpeg = sandbox.computerUse.takeCompressedScreenshot("jpeg", 95, 1.0);

// Scaled down PNG

var 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(fmt="jpeg", 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: 'jpeg',

quality: 80,

showCursor: true

});

console.log(`Compressed size: ${screenshot.sizeBytes} 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: "jpeg", 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::Daytona.new

sandbox = daytona.create(Daytona::CreateSandboxFromSnapshotParams.new(

snapshot: 'daytonaio/sandbox:0.6.0',

env_vars: { 'DAYTONA_RECORDINGS_DIR' => '/home/daytona/my-recordings' }

))
import (

"github.com/daytona/clients/sdk-go/pkg/daytona"

"github.com/daytona/clients/sdk-go/pkg/types"

)

client, err := daytona.NewClient()

if err != nil {

log.Fatal(err)

}

sandbox, err := client.Create(ctx, types.SnapshotParams{

SandboxBaseParams: types.SandboxBaseParams{

Name: "my-sandbox",

EnvVars: map[string]string{

"DAYTONA_RECORDINGS_DIR": "/home/daytona/my-recordings",

},

},

Snapshot: "daytonaio/sandbox:0.6.0",

})

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 label:

# Start recording with a custom label

recording = 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 label

const recording = await sandbox.computerUse.recording.start('test-1');

console.log(`Recording started: ${recording.id}`);

console.log(`File path: ${recording.filePath}`);
# Start recording with a custom label

recording = sandbox.computer_use.recording.start(label: 'test-1')

puts "Recording started: #{recording.id}"

puts "File path: #{recording.file_path}"
// Start recording with a custom label

label := "test-1"

recording, err := sandbox.ComputerUse.Recording().Start(ctx, &label)

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 label

var 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 '{

"label": "test-1"

}'

# Stop Recording

Section titled “Stop Recording”

Stop an active recording session by providing the recording ID:

# Stop the recording

stopped_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 recording

const stoppedRecording = await sandbox.computerUse.recording.stop(recording.id);

console.log(`Recording stopped: ${stoppedRecording.durationSeconds} seconds`);

console.log(`Saved to: ${stoppedRecording.filePath}`);
# Stop the recording

stopped_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 recording

stoppedRecording, 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 recording

var 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.file_name}: {rec.duration_seconds}s ({rec.size_bytes} bytes)")
const recordingsList = await sandbox.computerUse.recording.list();

console.log(`Total recordings: ${recordingsList.recordings.length}`);

recordingsList.recordings.forEach(rec => {

console.log(`- ${rec.fileName}: ${rec.durationSeconds}s (${rec.sizeBytes} bytes)`);

});
recordings_list = sandbox.computer_use.recording.list

puts "Total recordings: #{recordings_list.recordings.length}"

recordings_list.recordings.each do |rec|

puts "- #{rec.file_name}: #{rec.duration_seconds}s (#{rec.size_bytes} bytes)"

end
recordingsList, 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.FileName, rec.GetDurationSeconds(), rec.GetSizeBytes())

}
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.file_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.fileName}`);

console.log(`Status: ${recordingDetail.status}`);

console.log(`Duration: ${recordingDetail.durationSeconds}s`);
recording_detail = sandbox.computer_use.recording.get(id: 'recording-id')

puts "Recording: #{recording_detail.file_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.FileName)

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 DELETE

# Download 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 file

sandbox.computer_use.recording.download(recording.id, "local_recording.mp4")

print("Recording downloaded successfully")

# Or with custom path

import os

download_path = os.path.join("recordings", f"recording_{recording.id}.mp4")

sandbox.computer_use.recording.download(recording.id, download_path)
// Download recording to local file

await sandbox.computerUse.recording.download(recording.id, 'local_recording.mp4');

console.log('Recording downloaded successfully');

// Or with custom path

const downloadPath = `recordings/recording_${recording.id}.mp4`;

await sandbox.computerUse.recording.download(recording.id, downloadPath);
# Download recording to local file

sandbox.computer_use.recording.download(id: recording.id, local_path: 'local_recording.mp4')

puts 'Recording downloaded successfully'

# Or with custom path

download_path = "recordings/recording_#{recording.id}.mp4"

sandbox.computer_use.recording.download(id: recording.id, local_path: download_path)
// Download recording to local file

err := sandbox.ComputerUse.Recording().Download(ctx, recording.GetId(), "local_recording.mp4")

if err != nil {

log.Fatal(err)

}

fmt.Println("Recording downloaded successfully")

// Or with custom path

downloadPath := 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 path

var 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.mp4

# Recording 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:

  1. Navigate to your sandboxes in the Daytona Dashboard
  2. Click the action menu (three dots) for your sandbox
  3. Select Screen Recordings from the dropdown menu

The recording dashboard provides:

# Display operations

Section titled “Display operations”

# Configure desktop resolution

Section titled “Configure desktop resolution”

By default, the virtual desktop runs at 1024x768. Choose a different resolution by passing the VNC_RESOLUTION environment variable when creating a sandbox. Use the <width>x<height> format; widths from 640 to 7680 pixels and heights from 480 to 4320 pixels are supported.

from daytona import Daytona, CreateSandboxFromSnapshotParams

daytona = Daytona()

sandbox = daytona.create(

CreateSandboxFromSnapshotParams(

env_vars={"VNC_RESOLUTION": "1920x1080"}

)

)
import { Daytona } from '@daytona/sdk';

const daytona = new Daytona();

const sandbox = await daytona.create({

envVars: { VNC_RESOLUTION: '1920x1080' }

});
require 'daytona'

daytona = Daytona::Daytona.new

sandbox = daytona.create(Daytona::CreateSandboxFromSnapshotParams.new(

env_vars: { 'VNC_RESOLUTION' => '1920x1080' }

))
import (

"github.com/daytona/clients/sdk-go/pkg/daytona"

"github.com/daytona/clients/sdk-go/pkg/types"

)

client, err := daytona.NewClient()

if err != nil {

log.Fatal(err)

}

sandbox, err := client.Create(ctx, types.SnapshotParams{

SandboxBaseParams: types.SandboxBaseParams{

EnvVars: map[string]string{

"VNC_RESOLUTION": "1920x1080",

},

},

})

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.setEnvVars(Map.of("VNC_RESOLUTION", "1920x1080"));

Sandbox sandbox = daytona.create(params);

}

You can also bake a resolution into a snapshot image with ENV VNC_RESOLUTION=1920x1080 in its Dockerfile. A value passed at creation takes precedence over the image’s ENV, which takes precedence over the 1024x768 default. Invalid values fall back to the default.

The virtual display’s framebuffer is allocated when the X server starts, so the resolution can only be set when creating the sandbox. Restarting display processes or stopping and starting the sandbox keeps the original geometry; create a new sandbox to use a different resolution.

Pick the resolution to match what your agent assumes. Agents that emit normalized coordinates scale them by an assumed screen size, so a desktop that differs from that assumption displaces every click. Verify the live geometry with Get info below.

# Get info

Section titled “Get info”

Get information about the displays.

info = sandbox.computer_use.display.get_info()

displays = info.displays or []

print(f"Total displays: {len(displays)}")

for i, display in enumerate(displays):

print(f"Display {i}: {display.width}x{display.height} at {display.x},{display.y}")
const info = await sandbox.computerUse.display.getInfo();

const displays = info.displays ?? [];

console.log(`Total displays: ${displays.length}`);

displays.forEach((display, index) => {

console.log(`Display ${index}: ${display.width}x${display.height} at ${display.x},${display.y}`);

});
info = sandbox.computer_use.display.info

displays = info.displays || []

puts "Total displays: #{displays.length}"

displays.each_with_index do |display, i|

puts "Display #{i}: #{display.width}x#{display.height} at #{display.x},#{display.y}"

end
info, 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()

window_list = windows.windows or []

print(f"Found {len(window_list)} open windows:")

for window in window_list:

print(f"- {window.title} (ID: {window.id})")
const windows = await sandbox.computerUse.display.getWindows();

const windowList = windows.windows ?? [];

console.log(`Found ${windowList.length} open windows:`);

windowList.forEach(window => {

console.log(`- ${window.title} (ID: ${window.id})`);

});
windows = sandbox.computer_use.display.windows

window_list = windows.windows || []

puts "Found #{window_list.length} open windows:"

window_list.each do |window|

puts "- #{window.title} (ID: #{window.id})"

end
result, 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'