> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orgo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Press key

> Press a single key or a key combination like ctrl+c.

Presses a key or key combination. Join a combination with `+`, for example `ctrl+shift+t`.

<Note>
  On a Windows computer the response is `{"ok": true}`. Key names are not case-sensitive and follow Windows naming, so `Page_Up` and `Page_Down` are spelled `pageup` and `pagedown`; the other keys in the tables below work as written. A missing or unrecognised key returns `400` rather than `500`, and the error body reads `Request failed with status code 400` rather than saying why. `?screen=` is ignored.
</Note>

## Path parameters

<ParamField path="id" type="string" required>
  Computer ID (UUID). An `instance_id` is not accepted here and fails with `500`.
</ParamField>

## Query parameters

<ParamField query="screen" type="string">
  Which [screen](/api-reference/screens/list) to press the key on. Optional.
  Omit it to act on the screen the computer booted with. An unknown id returns
  `404` rather than falling back to the default screen.
</ParamField>

## Body parameters

<ParamField body="key" type="string" required>
  Key or key combination to press. On Linux the value is passed through to the computer's
  keyboard driver unchanged, so it must be an X11 keysym name. Keysym names are
  case-sensitive. Nothing validates the field before it gets there: a missing or
  misspelled key surfaces as a `500`, not a `400`.
</ParamField>

### Common keys

Use the keysym name, not the label printed on the key. `Return` and `BackSpace`
are the two that most often catch people out.

| Key | Description |
| - | - |
| `Return` | Enter/Return key |
| `Tab` | Tab key |
| `Escape` | Escape key |
| `BackSpace` | Backspace key |
| `Delete` | Forward delete |
| `space` | Space bar |
| `Up`, `Down`, `Left`, `Right` | Arrow keys |
| `Home`, `End` | Home/End keys |
| `Page_Up`, `Page_Down` | Page navigation |
| `F1`-`F12` | Function keys |

### Common combinations

| Combination | Description |
| - | - |
| `ctrl+c` | Copy |
| `ctrl+v` | Paste |
| `ctrl+a` | Select all |
| `ctrl+s` | Save |
| `alt+Tab` | Switch windows |
| `alt+F4` | Close window |
| `ctrl+shift+t` | Reopen closed tab |

The modifier names are `ctrl`, `alt`, `shift`, and `super`.

## Response

<ResponseField name="success" type="boolean">
  Always `true` on a `200`. A key the computer could not press is an error status.
</ResponseField>

<ResponseField name="action" type="string">
  Always `key_press`.
</ResponseField>

<ResponseField name="details" type="object">
  Carries `key`, an echo of what was sent.
</ResponseField>

<ResponseField name="error" type="null">
  Always `null` on a `200`.
</ResponseField>

<ResponseField name="error_type" type="null">
  Always `null` on a `200`.
</ResponseField>

## Example

<CodeGroup>
  ```bash cURL theme={null}
  # Press Return
  curl -X POST https://www.orgo.ai/api/computers/$COMPUTER_ID/key \
    -H "Authorization: Bearer $ORGO_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"key": "Return"}'

  # Ctrl+C
  curl -X POST https://www.orgo.ai/api/computers/$COMPUTER_ID/key \
    -H "Authorization: Bearer $ORGO_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"key": "ctrl+c"}'
  ```

  ```python Python theme={null}
  import requests

  url = f"https://www.orgo.ai/api/computers/{computer_id}/key"
  headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}

  # Press Return
  requests.post(url, headers=headers, json={"key": "Return"})

  # Ctrl+C
  requests.post(url, headers=headers, json={"key": "ctrl+c"})
  ```

  ```javascript JavaScript theme={null}
  const url = `https://www.orgo.ai/api/computers/${computerId}/key`;
  const headers = {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json'
  };

  // Press Return
  await fetch(url, { method: 'POST', headers, body: JSON.stringify({ key: 'Return' }) });

  // Ctrl+C
  await fetch(url, { method: 'POST', headers, body: JSON.stringify({ key: 'ctrl+c' }) });
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "success": true,
  "action": "key_press",
  "details": { "key": "Return" },
  "error": null,
  "error_type": null
}
```

## Errors

| Status | Meaning |
| - | - |
| `400` | The computer has no VM attached: `{"error": "Desktop instance not available"}`. Also returned by the computer agent when `key` is not a JSON string. A missing or unrecognised `key` is **not** a `400`: it is a `500`. |
| `401` | Invalid API key: `{"error": "Invalid API key"}`. A request with no `Authorization` header returns `{"error": "Authentication required"}`. Access failures also return `401` on this endpoint, not `403`: `{"error": "You do not have access to this workspace."}` when you are neither the owner nor a member of the computer's workspace, `{"error": "This workspace is view-only. Ask the owner for write access (workspace_read_only)."}` for a view-only member, and `{"error": "This API key cannot access this workspace (workspace_scope_mismatch)."}` for a workspace-scoped key used outside its workspace. A server-side fault while verifying the credential also returns `401`, with `{"error": "Service temporarily unavailable. The database is not accepting requests. Retry shortly."}`. Retry that one; the key is fine. |
| `402` | The computer was created as a free trial that is no longer active: `{"error": "Choose a plan to continue."}`. |
| `404` | No computer with this id: `{"error": "Desktop not found"}`. Also returned by the computer agent when `?screen=` names a screen this computer does not have, as in `{"error": "no screen \"2\"", "request_id": "…", "upstream_status": 404}`. |
| `500` | The computer could not press the key. A missing, misspelled, or non-keysym value lands here. Also returned when the request body is not valid JSON, with the parser's message in `error`. |
| `503` | The computer could not be reached: `{"error": "Could not reach the desktop. Try again in a moment.", "code": "ECONNREFUSED"}`. Safe to retry. Also returned when the computer never finished provisioning: `{"error": "Computer not ready"}`. |

Every failure raised after the request leaves the API layer also carries a
`request_id`. Quote it in support requests. When the computer agent itself
answered non-2xx, the body additionally carries `upstream_status`.

```json theme={null}
{
  "error": "pressing key \"Enter\": exit status 1",
  "request_id": "9f2b7c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
  "upstream_status": 500
}
```


## OpenAPI

````yaml POST /computers/{id}/key
openapi: 3.1.0
info:
  title: Orgo API
  description: >-
    Launch cloud computers that AI agents can control and interact with. Create
    workspaces, provision computers, and control them programmatically.
  version: 2.0.0
  contact:
    name: Orgo Support
    email: spencer@orgo.ai
    url: https://orgo.ai
servers:
  - url: https://www.orgo.ai/api
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Account
    description: >-
      Account capacity: how many computers an account may run, and adding or
      giving back more.
  - name: Clients
    description: >-
      Run Orgo for your clients from your own app: a workspace and scoped key
      each, billed to you or to them.
  - name: Workspaces
    description: Organize computers into named workspaces
  - name: Computers
    description: Provision and manage virtual computers
  - name: Computer Lifecycle
    description: Start, stop, and restart computers
  - name: Computer Actions
    description: Control mouse, keyboard, and execute commands
  - name: Screens
    description: >-
      More than one desktop on a single computer. Each screen is its own X
      server with its own cursor and window manager, so an agent working on one
      cannot disturb another.
  - name: Files
    description: Upload and download files
  - name: Templates
    description: Author, build, and launch reproducible computers from templates
paths:
  /computers/{id}/key:
    post:
      tags:
        - Computer Actions
      summary: Press key
      description: >-
        Presses a key or key combination (e.g., Enter, Tab, ctrl+c).


        On an iPhone computer (os `ios`): `home` presses the Home button and
        `app_switcher` opens the App Switcher (`cmd+tab` and `recents` do the
        same). `Return`, `BackSpace` and `space` type into the focused field. A
        phone has no modifier keys, so other chords return 501. A drag from the
        bottom edge only ever goes Home; use `app_switcher` for the App
        Switcher. From the App Switcher, `home` once goes back to the app that
        was open; press it again for the Home Screen.
      operationId: pressKey
      parameters:
        - name: id
          in: path
          required: true
          description: Computer ID
          schema:
            type: string
        - name: screen
          in: query
          required: false
          description: >-
            Which screen to act on. Omit for the boot screen. An unknown id
            returns 404 rather than falling back.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/KeyRequest'
            examples:
              enter:
                summary: Press Enter, whose keysym name is Return
                value:
                  key: Return
              shortcut:
                summary: Ctrl+C shortcut
                value:
                  key: ctrl+c
              iphone_home:
                summary: 'iPhone: Home button'
                value:
                  key: home
              iphone_app_switcher:
                summary: 'iPhone: open the App Switcher'
                value:
                  key: app_switcher
      responses:
        '200':
          description: Key pressed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActionResponse'
              example:
                success: true
                action: key_press
                details:
                  key: Return
                error: null
                error_type: null
        '400':
          description: >-
            The computer has no VM attached, or `key` is not a JSON string. A
            missing or unrecognised `key` is a `500`, not a `400`.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/UpstreamError'
              examples:
                no-instance:
                  summary: The computer has no VM attached. Start it first.
                  value:
                    error: Desktop instance not available
                wrong-type:
                  summary: >-
                    The computer agent rejected a body field of the wrong JSON
                    type, such as `key` sent as a string
                  value:
                    error: 'invalid JSON: …'
                    request_id: 7c1e0f4a-9b2d-4a51-8f0c-2d6b1e93a4c7
                    upstream_status: 400
        '401':
          $ref: '#/components/responses/UnauthorizedWithAccess'
        '402':
          $ref: '#/components/responses/TrialInactive'
        '404':
          description: >-
            No computer with this id, or `?screen=` names a screen this computer
            does not have.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/UpstreamError'
              examples:
                no-computer:
                  summary: Unknown computer
                  value:
                    error: Desktop not found
                no-screen:
                  summary: Unknown screen
                  value:
                    error: no screen "2"
                    request_id: 7c1e0f4a-9b2d-4a51-8f0c-2d6b1e93a4c7
                    upstream_status: 404
        '500':
          description: >-
            The computer could not press the key. A missing, misspelled, or
            non-keysym value lands here. Also returned when the request body is
            not valid JSON, with the parser's message in `error`.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/UpstreamError'
                  - $ref: '#/components/schemas/InternalError'
              examples:
                bad-key:
                  summary: Unrecognised key
                  value:
                    error: 'pressing key "Enter": exit status 1'
                    request_id: 7c1e0f4a-9b2d-4a51-8f0c-2d6b1e93a4c7
                    upstream_status: 500
        '503':
          description: >-
            The computer could not be reached. It may be resuming, or its host
            may be unhealthy. Retry in a moment. Also returned when the computer
            never finished provisioning.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/UnreachableError'
                  - $ref: '#/components/schemas/InternalError'
              examples:
                unreachable:
                  summary: Unreachable
                  value:
                    error: Could not reach the desktop. Try again in a moment.
                    request_id: 7c1e0f4a-9b2d-4a51-8f0c-2d6b1e93a4c7
                    code: ECONNREFUSED
                not-ready:
                  summary: The computer never finished provisioning
                  value:
                    error: Computer not ready
                    request_id: 7c1e0f4a-9b2d-4a51-8f0c-2d6b1e93a4c7
components:
  schemas:
    KeyRequest:
      type: object
      required:
        - key
      properties:
        key:
          type: string
          description: >-
            Key or key combination (e.g., Enter, Tab, ctrl+c, alt+F4). On an
            iPhone: home, app_switcher, Return, BackSpace, space.
          example: Return
    ActionResponse:
      type: object
      properties:
        success:
          type: boolean
          description: Always `true` on a `200`. A failed action is an error status.
          example: true
        action:
          type: string
          description: >-
            The action performed: `click`, `mouse_move`, `drag`, `type`,
            `key_press`, `scroll`, or `wait`.
        details:
          type: object
          additionalProperties: true
          description: Echo of what was performed. Its fields depend on the action.
        error:
          type: 'null'
          description: Always `null` on a `200`.
        error_type:
          type: 'null'
          description: Always `null` on a `200`.
    Error:
      type: object
      description: >-
        The base error body. Every failure carries `error`; individual endpoints
        add the fields named in the schemas below.
      required:
        - error
      properties:
        error:
          type: string
          description: Human-readable message.
          example: Access denied
        code:
          type: string
          description: >-
            Machine-readable reason. Present on the failures that define one,
            absent otherwise.
    UpstreamError:
      type: object
      description: >-
        A failure the computer itself returned, relayed with the computer's own
        status.
      required:
        - error
        - request_id
        - upstream_status
      properties:
        error:
          type: string
          description: The message the computer returned.
        request_id:
          type: string
          description: >-
            Correlation id for this failure. The server logged the failure under
            it, so quote it in a support report.
          example: 7c1e0f4a-9b2d-4a51-8f0c-2d6b1e93a4c7
        upstream_status:
          type: integer
          description: >-
            The status the computer returned. Mirrors the status of this
            response.
          example: 409
    InternalError:
      type: object
      description: >-
        An unexpected failure. Retrying is reasonable; if it persists, quote
        `request_id`.
      required:
        - error
      properties:
        error:
          type: string
        request_id:
          type: string
          description: >-
            Present on failures raised by a route that talks to a computer.
            Absent on the others.
          example: 7c1e0f4a-9b2d-4a51-8f0c-2d6b1e93a4c7
    UnreachableError:
      type: object
      description: >-
        The computer could not be reached. The diagnostic fields, present on the
        command endpoints, say how far the request got.
      required:
        - error
        - request_id
        - code
      properties:
        error:
          type: string
          example: Could not reach the desktop. Try again in a moment.
        request_id:
          type: string
          example: 7c1e0f4a-9b2d-4a51-8f0c-2d6b1e93a4c7
        code:
          type: string
          description: >-
            The socket-level error code, or `network_error` when none was
            reported.
          example: ECONNREFUSED
        vm_status:
          type:
            - string
            - 'null'
          description: The computer's recorded status when the request failed.
        desired_status:
          type:
            - string
            - 'null'
          description: >-
            The status the computer was being driven towards, when one was
            recorded.
        host_reachable:
          type:
            - boolean
            - 'null'
          description: Whether the host running the computer answered.
        desktop_api_reachable:
          type:
            - boolean
            - 'null'
          description: Whether the computer's own API answered.
        hint:
          type: string
          description: What to do next, given the two reachability results.
  responses:
    UnauthorizedWithAccess:
      description: >-
        No usable credential, or an access check failed. This endpoint runs its
        workspace access checks during authentication, so it answers a missing
        membership, view-only access, or a key scoped to another workspace with
        `401`, not `403`. A server-side fault while verifying the credential
        also returns `401`, with a `Service temporarily unavailable` message.
        Retry that one; the key is fine.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            invalid-key:
              summary: The key is not one of yours
              value:
                error: Invalid API key
            no-credential:
              summary: No key and no session
              value:
                error: Authentication required
            no-access:
              summary: Not the owner or a member of the workspace
              value:
                error: You do not have access to this workspace.
            view-only:
              summary: View-only member, and the request changes something
              value:
                error: >-
                  This workspace is view-only. Ask the owner for write access
                  (workspace_read_only).
            scope-mismatch:
              summary: The API key is scoped to another workspace
              value:
                error: >-
                  This API key cannot access this workspace
                  (workspace_scope_mismatch).
            service-unavailable:
              summary: Server-side fault while verifying the credential. Retry.
              value:
                error: >-
                  Service temporarily unavailable. The database is not accepting
                  requests. Retry shortly.
    TrialInactive:
      description: >-
        The computer is a free trial computer whose trial is no longer active,
        or it is paid for by its own subscription or dedicated purchase and that
        payment has lapsed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            trial:
              summary: Trial no longer active
              value:
                error: Choose a plan to continue.
            payment:
              summary: The computer's own payment has lapsed
              value:
                error: Manage this computer’s payment in Account → Usage.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API key authentication. Get your key at orgo.ai/workspaces

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.