Send input
Moves the pointer, clicks, drags, scrolls, types or presses keys.
Three request shapes are accepted. The flat one below is this API’s own. The second is an Anthropic computer-use tool_use.input block posted verbatim — coordinate: [x, y], start_coordinate, scroll_direction, scroll_amount, duration, and text doing double duty as either the string to type or the modifier keys to hold — so a model’s tool call can be forwarded without translation.
The third is an OpenAI action with type instead of action: click, double_click, drag, move, scroll, keypress, type, wait or screenshot. Send one object or an array of 1–32 OpenAI action objects. Do not mix the two discriminators or dialect-specific fields. OpenAI pointer actions require both x and y, including zero. Click buttons are left, right, wheel (middle), back and forward. A drag path has 2–128 {x,y} points and holds one button through every waypoint. Coordinates are truncated to pixels, bounded to ±10,000,000, then clamped to the screen. OpenAI scroll_x/scroll_y are approximated as wheel notches: round each absolute distance divided by 100, with a minimum of one for a nonzero delta and zero for zero. Each axis is bounded to ±5000 pixels and their combined converted count to 50 notches; vertical then horizontal. Actual movement depends on the application. Optional keys (at most 16) are held around the entire OpenAI pointer gesture, including positioning, and released on failure. Arrow names, META/COMMAND and OPTION map to desktop keys. OpenAI wait lasts one second. OpenAI screenshot acknowledges a marker with ok:true; retrieve image bytes using GET /screenshot after the action(s). Duplicate or unused OpenAI fields, even zero-valued ones, are refused before auto-resume. The following alias/default rules apply to the two legacy action formats.
A batch is fully validated before auto-resume or input. Combined limits are 400 typed Unicode characters, 50 wheel notches, 128 drag points and 10 one-second waits. The whole batch shares one input lane, one QMP connection when needed, and at most 75 seconds of work including cleanup, plus two five-second queues. QMP remains held during waits in a batch containing pointer or keyboard input; wait-only batches do not hold it. VNC and native guest applications are not serialized by this API lock. Execution stops at the first error. completed and results describe finished actions; failed_index is zero-based. The failing action may have partially applied. Inspect a fresh screenshot before retrying; never automatically replay the batch. Static validation/admission failures use the normal error response. A screenshot-only batch acknowledges markers without waking the computer. Optional context is read once after a successful batch. The proxy allows 93 seconds, including context and transport.
Coordinates are absolute, in the screen space resolution reports.
Keys can be held down for the length of a click, a scroll or a drag — ctrl-click, shift-click, shift-drag to extend a selection. Give them as keys (["ctrl", "shift"]), or as a chord string in key or text ("ctrl+shift"), once. On a click or a drag they are pressed before the pointer moves and released after the button. On a scroll with a coordinate the pointer moves FIRST, with no keys held, and the keys are then pressed for the wheel notches and released after them. Either way they are released when the action fails part way.
A body is read strictly. A field this endpoint does not have, a field the action does not read (keys on a move, a coordinate on a type, button on a click), the held keys given in more than one field, and an unknown action each answer 400 naming what was wrong, before anything is sent to the computer and before a suspended one is resumed. A computer tool’s screenshot and zoom are not input: posted here, with or without region, they answer 400 with code: not_an_input_action and say where each is served. Take a screenshot from GET /computers/{id}/screenshot, and serve a zoom as a crop of the screenshot the model is looking at: ?capture= set to that screenshot’s X-GC-Capture header and ?region=x0,y0,x1-x0,y1-y0 from the tool’s [x0, y0, x1, y1], in that screenshot’s pixels. computer_toolset_20260801 turns zoom on unless its configs turn it off, and a model may still call it, so a harness forwarding tool calls verbatim should route zoom itself. It should also spend a key call’s repeat as one input per press (repeat is not a field here), and split a wait longer than 30 seconds. A field at its zero value — "", [], 0 — counts as not sent, except x and y, where 0 is a position: {"action":"key","key":"ctrl+c","x":0,"y":0} is a 400 (key does not take x). Leave them out, or send null.
amount (or scroll_amount) is 1 to 50 notches, 3 when left out or not above 0; more than 50 is a 400. duration is at most 30 seconds, 1 second when left out or not above 0; longer is a 400. Those two, a scroll direction other than up, down, left or right, and a key name this endpoint does not know — in a chord or held during a pointer action — are checked with the rest of the body: a 400 before a suspended computer is resumed, and the same 400 from a stopped one.
type requires non-empty valid Unicode text, at most 400 characters. Plain ASCII is typed as physical key events, about 12 ms a character (each key held 8 ms, then 4 ms before the next). Text containing any other character is typed WHOLE, in request order, by one guest helper: its ASCII at the same physical key positions and shift levels, and every other character by GTK Unicode composition. This works in supported Chromium GTK3 and Xfce Terminal/VTE configurations on Linux X11, including accents, CJK, emoji and combining sequences, without changing the clipboard or keyboard mapping. Tab and LF are keys; CRLF sends one Return. Bare CR and other C0/C1/DEL controls are refused. Malformed or unsupported text is checked before auto-resume or any keys. Unicode typing requires XTEST, XRes process identification, Python Xlib, GTK3, timeout, a neutral supported US keyboard mapping and an effective gtk-im-context-simple input context. A no-key preflight verifies the supported application/configuration before even a mixed request’s ASCII prefix. Firefox, other applications, GTK4, custom input modules, disabled GTK IME, Windows and native Wayland Unicode typing are unsupported. Guest configuration is not changed. The response reports mechanism: physical | unicode | mixed. Use exclusive desktop control and verify the resulting text: delivery does not prove application acceptance. Runtime failure or cancellation can leave partial text or composition state. Cancellation waits for the bounded in-flight helper; cleanup never sends Escape into uncertain focus. Unicode requests share 75 seconds for all work including cleanup, with a 95-second proxy allowance for queues and transport; inspect before retrying and never automatically replay.
For fast text insertion use {"action":"paste","text":"Café — 東京 😀"}. This writes the Linux desktop clipboard and sends Ctrl+V. Use key: "ctrl+shift+v" for terminals that require it, Shift+Insert is refused because it can read the separate primary selection. Text must be non-empty UTF-8 without NUL, at most 8192 bytes. Windows and guests without working clipboard support are refused.
Paste replaces the clipboard and leaves it in place. API input/clipboard writes are serialized through the shortcut, but native guest applications and VNC clients can still change it. Use exclusive desktop control and wait for the target to consume the paste before changing the clipboard again. A 200 means the clipboard write and shortcut were delivered, not that the application accepted or inserted the text. Check the target afterward; paste-disabled fields may ignore it. An interrupted request can have side effects: inspect before retrying, and do not automatically fall back to typing or replay it.
count repeats a left_click, right_click or middle_click up to 10 times, for the applications that read a click count past three.
Add ?context=1 to have the answer carry the desktop’s windows and the focused one as they stand just after the action — on any action, wait included. A query parameter other than context, one given twice or empty, and a context other than 1, true, 0 or false each answer 400 before anything is sent to the computer.
Requires the member role or higher.
Request
- Base URL: https://app.mandala.computer/api/v1
- URL: https://app.mandala.computer/api/v1/computers/{id}/input
- Auth: HTTP bearer
Path parameters
The computer id.
Query parameters
Answer the desktop’s windows after the action — any action, wait included — as context, saving the round trip to GET /computers/{id}/windows, and, when the focused window is Chromium, the page on screen as context.dom. Costs one windows read and at most one page read, bounded at 3 seconds together, after the action. If the windows cannot be read the action still answers ok: true, with context_error saying why and no context; if only the page cannot (any other window focused included), context has no dom and context_error says why. 1 or true asks; 0, false or leaving it out does not.
Request body
Response
Delivered. type reports its mechanism; cursor_position answers where the pointer is and whether that is known. Verify application acceptance.
Changes
No recorded changes to this operation across all 1 revision of this API.