Skip to content
Raster
Esc
navigateopen⌘Jpreview
On this page

Create your first machine

Install an SDK, boot a machine, and drive it — from nothing to a running, driven computer.

Install

npm install @raster/sdk
uv add raster

The SDK authenticates with an API key, which you create under Keys in the dashboard. The plaintext is shown once, at creation, and never again.

export RASTER_API_KEY=sk_...
export RASTER_BASE_URL=https://api.example.com/v1

There is no default base URL. A wrong-but-plausible hostname baked into a published SDK sends your key somewhere nobody chose, so the deployment names its own API or the constructor refuses.

Create a machine

import { Client } from "@raster/sdk";

const client = new Client();
const machine = await client.machines.create({ name: "research", size: "small" });

// running is not the same as ready: a machine has a working shell before it
// has a working desktop.
const display = await machine.waitForDesktop();
from raster import Client

client = Client()
machine = client.machines.create(name="research", size="small")

# running is not the same as ready: a machine has a working shell before it
# has a working desktop.
display = machine.wait_for_desktop()

Drive its computer

With display resolved, the machine has a working desktop. Drive it the same way a person would:

await machine.browser.open("https://example.com");
await machine.keyboard.type("hello");
await machine.mouse.click({ at: { x: 640, y: 400 } });

const shot = await machine.screen.screenshot({ format: "png" });
const result = await machine.terminal.exec(["uname", "-sr"]);
machine.browser.open("https://example.com")
machine.keyboard.type("hello")
machine.mouse.click(at={"x": 640, "y": 400})

shot = machine.screen.screenshot(format="png")
result = machine.terminal.exec(["uname", "-sr"])

shot is a screenshot of a real desktop your code just drove, and result is the output of a command it just ran. That’s a complete round trip: a machine created, booted, and driven.

Coordinates are the display’s own pixels and nothing is scaled for you, so take a screenshot and read them off it. A coordinate outside the display is refused rather than clamped.

Clean up

await machine.close(); // release the input lease and close the session
await machine.stop(); // keeps the disk; delete() destroys it
machine.close()          # or use `with machine:` and let the block do it
machine.stop()           # keeps the disk; delete() destroys it

Do call close. Without it the machine holds the input lease until it expires, and nobody else can type.

Next

Was this page helpful?