Kubi Docs
Concepts

Screens

What a screen is, its two kinds, templates, snapshots, its states, and how power, delete and export work.

A screen is a Linux desktop (Debian 13 in Ubuntu's look, with Chromium, Firefox and the usual tools) in its own virtual machine. It keeps running until you stop it, and its disk is yours: files, browser logins and settings stay between sessions. You have root inside it.

Two kinds

Every screen is the same machine. What differs is how you pay for it and how long it stays.

persistent (the default)disposable
PaidMonthly, one price per screen, running or stoppedFrom usage credit, for the time it runs
StaysUntil you delete itUntil its end time, or 7 days after it stops
DeleteUndo within 7 daysFinal, gone at once
Good forAn agent that lives on its screenRuns, benchmarks, short jobs

Pick the kind when you create the screen:

TerminalCode
curl -X POST https://api.trykubi.com/v1/screens \ -H "Authorization: Bearer $KUBI_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"kind": "disposable", "ends_in_s": 3600}'
  • End time: ends_in_s (5 minutes to 30 days) deletes a disposable screen when the time is up. Move or clear it later with PATCH /screens/{id} and ends_at. The screen's ends_at shows it; null means no end time.
  • Stopped: a stopped disposable screen pays a small fee for its disk, and delete_after says when it goes unless you start it again or make it persistent.
  • Switch kinds with POST /screens/{id}/convert, either way, with no restart. To persistent, it joins the monthly bill and its end time goes; to disposable, it leaves the bill and draws on credit from now.
  • List one kind with GET /screens?kind=disposable. Each screen's created_by says which person, key or app made it.
  • What each kind costs and what happens when credit runs out: Billing and history.

Templates

Save any screen as a template, then start new screens of either kind from it, already set up the way you left it:

TerminalCode
curl -X POST https://api.trykubi.com/v1/templates \ -H "Authorization: Bearer $KUBI_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"screen_id": "scr_7f2kq9w3x8m4b6tzp1ac", "name": "osworld-base"}'

Then pass its id as template_id when you create a screen.

  • Saving returns an operation; the template shows as saving until it is ready. A running screen pauses for a few seconds while it is saved.
  • A template holds the screen's disk. with_memory says whether screens started from it also come back with the windows that were open.
  • It keeps whatever was installed on the screen, browser logins done by hand included, so treat it as you would the screen. It never holds a secret: your organization's secrets are put into a screen at every start and are never written to its disk.
  • Your organization has a template cap; over it, saving gets 402 QUOTA_EXCEEDED. Deleting a template leaves the screens started from it running.

Snapshots and reset

Save a screen's disk as a snapshot before risky work, then reset to it if something breaks:

TerminalCode
curl -X POST https://api.trykubi.com/v1/screens/scr_7f2kq9w3x8m4b6tzp1ac/snapshots \ -H "Authorization: Bearer $KUBI_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name": "before-upgrade"}'
  • A running screen keeps running. The snapshot holds the disk as a sudden power cut would leave it, never memory or a secret.
  • Up to 3 per screen, holding at most 50 GB of changed data, included in the price. Over that, 402 QUOTA_EXCEEDED: delete one first.
  • POST /screens/{id}/reset with a snapshot_id puts the disk back to it and starts the screen; with null, back to how the screen started. Work since then is lost, and so are the snapshots taken after that point. The id, name, kind, bill, proxy and secrets stay.
  • Snapshots live with the screen and go when it is deleted. They are not in backups or exports, so keep your own copies of anything important.
  • API keys need power; agents signed in through MCP can't reset.

States

StateMeaning
provisioningBeing created: a blank screen is ready in seconds, one from a template boots its disk
runningReady for screenshots, actions and commands
stopping, stoppedShut down; the disk is kept
starting, restartingBooting again
deleting, deletedGoing away; a persistent screen sits in the bin for 7 days first
failedSomething broke; state_reason says what

A stopped screen's state_reason says who stopped it: stopped_by_user, stopped_by_billing, stopped_by_credit or stopped_by_admin. New states and reasons may appear later, so treat an unknown state like failed and show an unknown reason as words.

Slow work returns an operation

Create, start, stop, restart, delete, switching kind, saving a template, taking a snapshot and reset answer at once with 202 and an operation. Poll it until it is done:

TerminalCode
curl "https://api.trykubi.com/v1/operations/op_01jb7q0x9v2k8m4n6p3r?wait_s=25" \ -H "Authorization: Bearer $KUBI_API_KEY"

With wait_s, the call holds for up to 25 seconds and returns as soon as something changes, so you never busy-loop. The SDK does it for you with client.operations.wait(op.id).

Deleting

Deleting a persistent screen is soft: it goes to the bin for 7 days and you can restore it from the dashboard. Deleting a disposable screen is final. API keys need the power permission to delete; agents signed in through MCP can never delete.

Taking your data with you

A person can export a screen's disk from the dashboard. The download link shows in the dashboard and arrives by email, and works for 7 days. Your account data downloads as JSON, and invoices come from Stripe.