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

# Update computer

> Rename a computer, set its mascot, or set, move, or clear when it ends.

Changes a computer's name, its mascot, or when it ends. Every field is optional. Send only what you want to change.

Renaming and the mascot need you to **own** the workspace. Setting, moving, or clearing the end needs write access to it, so a member with write access can change the end as long as the request does not also rename the computer or change its mascot.

> [!NOTE]
>
> On a computer that runs by the hour, the prepay moves with the end. A later end holds more of your credits, an earlier one gives some back, and taking the end off gives back what the computer has not used. [How a change of the end is billed](#how-a-change-of-the-end-is-billed) has the rules.

## Path parameters

**id** `string` *required*

Computer UUID or `instance_id`. Both resolve to the same computer.

## Body parameters

**name** `string`

New computer name, 80 characters at most. Omitted leaves the name alone. An empty, non-string, or longer value returns `400`. Workspace owner only.

**bot\_mascot** `object`

The computer's mascot look, with all fields optional: `color` (`stone`, `pearl`, `graphite`, `ink`, `green`, `blue`, `red`, `orange`, `purple`, `cyan`, `pink`, `yellow`, `teal`, `coral`), `expression` (`deadpan`, `friendly`, `focused`, `thinking`, `excited`, `sleepy`, `surprised`, `skeptical`, `worried`, `mischievous`), and `accessory` (`none`, `beanie`, `tophat`, `party`, `glasses`, `sunglasses`, `bow`). Unrecognised fields and values are dropped rather than rejected, so a field you send with an unknown value falls back to the default. `null` clears the mascot; omitting the field leaves it alone; any other non-object value returns `400`. Workspace owner only.

**ends\_at** `string | null`

When the computer ends, as an ISO 8601 time: in the future, and at most 720 hours (30 days) from now. `null` takes the end off, so the computer is kept until you stop or delete it. Omitted leaves the end alone. Sending back the `ends_at` the computer already has, as [Get computer](https://docs.orgo.ai/api-reference/computers/get.md) returned it, changes nothing, even when that time has passed. Send `ends_at` or `ends_in_hours`, not both.

**ends\_in\_hours** `integer | null`

When the computer ends, as a whole number of hours from now: `1` to `720`. `null` takes the end off, as `ends_at: null` does. Omitted leaves the end alone.

Only Linux and Windows computers can have an end. Taking an end off works on any computer.

## How a change of the end works

When `ends_at` passes, Orgo stops the computer and marks it ended, then deletes it 7 days later unless it is started. [Computers with an end](https://docs.orgo.ai/api-reference/computers/create.md#computers-with-an-end) describes that in full.

Any change of the end clears `ended_at`. A computer whose time ran out and that you give a new end runs out that time instead. One you keep with `null` becomes an ordinary computer and is not deleted. Either way it stays stopped until you [start](https://docs.orgo.ai/api-reference/computers/start.md) it.

## How a change of the end is billed

A computer on the plan is paid for by the plan. Only its end changes, and nothing is prepaid.

On a computer that runs by the hour and is running, the prepay follows the new end in the same step:

* **A later end** holds the run to the new end. What the old prepay has not used comes back in the same step, so it needs only the extra. When your credit cannot cover the extra plus an hour of your other hourly computers billed by the minute, the request returns `402` and nothing changes.
* **An earlier end** holds the run to it and gives back the rest.
* **`null`** gives back what the computer has not used, and it is billed by the minute again.
* **A first end** on a computer billed by the minute prepays the run to it. When your credit cannot cover it, the end is still set, the time to it is billed by the minute, and the answer carries `prepay_warning`. A first or earlier end is never refused for credit, so you can always set a sooner stop.

On an hourly computer that is stopped, any prepay left comes back and the computer stays billed by the minute. One that is still being made returns `409` with code `COMPUTER_BUSY`.

### Who can prepay

Only the workspace owner can prepay an end from their credits. On a paid plan, or an account Orgo has set to pay for every computer from credits, the owner must also be signed in, or use a key with full access or Billing write. An MCP sign-in or a key without Billing write does not prepay there.

A caller who may not prepay, but has write access, still sets the end. Nothing more is held: an old prepay runs to its old time, the time past it is billed by the minute, and the answer carries `prepay_warning`. Moving the end earlier or taking it off only gives credit back, so anyone who may change the end may do those.

## Response

**id** `string`

Computer identifier (UUID).

**name** `string`

Computer name, after the change.

**bot\_mascot** `object | null`

Present unless the body sent only an end. The stored mascot, or `null` when none is set.

**updated\_at** `string`

Present alongside `bot_mascot`. ISO 8601 timestamp.

**ends\_at** `string | null`

Present when the body changed the end, or sent only the end the computer already has. When the computer ends now, or `null` when it never ends.

**ended\_at** `string | null`

Present alongside `ends_at`. `null` after any change of the end.

**deletes\_at** `string | null`

Present alongside `ends_at`. `null` after any change of the end.

**prepaid\_until** `string | null`

Present when the end of a computer that runs by the hour changed. When its prepaid run ends now, or `null` when it is billed by the minute.

**prepaid\_cents** `integer | null`

Present alongside `prepaid_until`. What is held from your credits for the run now, in cents. `null` when `prepaid_until` is.

**prepay\_returned\_cents** `integer`

Present when some of an earlier prepay came back to your credits, in cents.

**prepay\_warning** `string`

Present when the end was set but its time was not prepaid, so it is billed by the minute. `The new time is billed by the minute. Only the account owner can prepay it, signed in or with a key that has Billing write.` when you may not prepay, or `The new end is set, and the time to it is billed by the minute: your credit does not cover prepaying all of it.` when the credit is short.

## Example

Move the end of an hourly Medium (\$0.055 an hour) to 8 hours from now. It had 2 hours left of a 4 hour prepay.

```bash cURL theme={null}
curl -X PATCH https://www.orgo.ai/api/computers/$COMPUTER_ID \
  -H "Authorization: Bearer $ORGO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ends_in_hours": 8}'
```

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

response = requests.patch(
    f"https://www.orgo.ai/api/computers/{computer_id}",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    },
    json={"ends_in_hours": 8}
)

computer = response.json()
print(f"Ends at: {computer['ends_at']}")
```

```javascript JavaScript theme={null}
const response = await fetch(`https://www.orgo.ai/api/computers/${computerId}`, {
  method: 'PATCH',
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ ends_in_hours: 8 })
});

const computer = await response.json();
console.log(`Ends at: ${computer.ends_at}`);
```

### Response

```json theme={null}
{
  "id": "a3bb189e-8bf9-3888-9912-ace4e6543002",
  "name": "agent-1",
  "ends_at": "2026-04-07T19:35:00.000Z",
  "ended_at": null,
  "deletes_at": null,
  "prepaid_until": "2026-04-07T19:35:00.000Z",
  "prepaid_cents": 44,
  "prepay_returned_cents": 11
}
```

### Keep a computer forever

```bash theme={null}
curl -X PATCH https://www.orgo.ai/api/computers/$COMPUTER_ID \
  -H "Authorization: Bearer $ORGO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ends_at": null}'
```

A computer on the plan answers with `id`, `name`, and the end fields, all `null`. An hourly computer that had an end also carries `prepaid_until` and `prepaid_cents` (both `null`), and `prepay_returned_cents` when some of its prepay came back.

### Rename a computer

```bash theme={null}
curl -X PATCH https://www.orgo.ai/api/computers/$COMPUTER_ID \
  -H "Authorization: Bearer $ORGO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "agent-1-renamed", "bot_mascot": {"color": "teal", "expression": "focused"}}'
```

```json theme={null}
{
  "id": "a3bb189e-8bf9-3888-9912-ace4e6543002",
  "name": "agent-1-renamed",
  "bot_mascot": { "color": "teal", "expression": "focused" },
  "updated_at": "2026-04-07T11:02:14.000Z"
}
```

## Errors

| Status | Body | When |
| - | - | - |
| `400` | `{ "error": "Computer name cannot be empty" }` | `name` is present but empty or not a string. |
| `400` | `{ "error": "Computer name must be 80 characters or fewer" }` | `name` is longer than 80 characters. |
| `400` | `{ "error": "bot_mascot must be an object or null" }` | `bot_mascot` is neither an object nor `null`. |
| `400` | `{ "error": "Device ID is assigned by Orgo and can't be changed" }` | The body changes `device_tag`. Orgo assigns the Device ID, so it is read-only. Sending back the value you read changes nothing. |
| `400` | `{ "error": "Send ends_at or ends_in_hours, not both.", "code": "INVALID_ENDS" }` | The body sends both. |
| `400` | `{ "error": "ends_in_hours must be a whole number of hours from 1 to 720, or null for never.", "code": "INVALID_ENDS" }` | `ends_in_hours` is not a whole number from 1 to 720 or `null`. |
| `400` | `{ "error": "ends_at must be an ISO 8601 time, or null for never.", "code": "INVALID_ENDS" }` | `ends_at` is not a time. |
| `400` | `{ "error": "ends_at must be in the future.", "code": "INVALID_ENDS" }` | `ends_at` has passed, and is not the end the computer already has. |
| `400` | `{ "error": "ends_at can be at most 720 hours (30 days) from now.", "code": "INVALID_ENDS" }` | `ends_at` is more than 720 hours away. |
| `400` | `{ "error": "Only Linux and Windows computers can have an end.", "code": "ENDS_NOT_SUPPORTED" }` | The body gives an end to a computer that cannot have one: an operating system other than Linux or Windows, a trial computer, a Bops computer, or one paid by its own subscription or reservation. |
| `401` | `{ "error": "Invalid API key" }` | The Bearer token starts with `sk_` but is not a known Orgo key. |
| `401` | `{ "error": "Authentication required" }` | No `Authorization` header, or a Bearer token that is not an `sk_` key. |
| `401`, `403` | `key_expired`, `key_permission`, `computer_key`, and others | The key itself was refused before the update ran. A computer's own key, its identity token, and a key for one computer cannot call this endpoint. Listed in [Codes any endpoint can return to a key](https://docs.orgo.ai/api-reference/api-keys/manage.md#codes-any-endpoint-can-return-to-a-key). |
| `402` | `{ "error": "Choose a plan to continue." }` | The computer is a trial computer whose trial has ended. |
| `402` | `{ "error": "…", "code": "COMPUTER_LOCKED", "lock": { … } }` | The computer is a Mac, iPhone, or Android phone that Orgo locked because its account is over capacity, and the body sends anything other than `name`. |
| `402` | `{ "error": "Moving the end needs $0.22 more credit. You have $0.10.", "code": "insufficient_credit", "needed_cents": 22, "available_cents": 10 }` | A later end on a running hourly computer, by someone who may prepay, needs more credit than there is. Nothing changed. With other hourly computers billed by the minute, `needed_cents` includes `keep_cents` and the message names both: `Moving the end needs $0.33 more credit: $0.22 for the extra time and $0.11 for an hour of your other computers. You have $0.10.` When the body also renamed the computer, the rename applied: `error` starts with `Renamed.` and the body carries `name`. |
| `403` | `{ "error": "You do not have access to this workspace." }` | You are neither the owner nor a member of the workspace. |
| `403` | `{ "error": "This workspace is view-only. Ask the owner for write access (workspace_read_only).", "code": "workspace_read_only" }` | You are a view-only member. |
| `403` | `{ "error": "This API key cannot access this workspace (workspace_scope_mismatch).", "code": "workspace_scope_mismatch" }` | The API key is scoped to a different workspace. |
| `404` | `{ "error": "Computer not found (computer_not_found).", "code": "computer_not_found" }` | No computer matches the id. Signed in with a session, the body is `{ "error": "Desktop not found" }`. |
| `404` | `{ "error": "Access denied" }` | You are a member with write access but not the workspace owner, and the body sends `name` or `bot_mascot`. Nothing changed. Send the end on its own. |
| `409` | `{ "error": "This computer is busy right now, so its end did not change. Try again in a minute.", "code": "COMPUTER_BUSY", "retryable": true }` | A stop, a start, or Orgo's own stop or delete at the end holds the computer, or an hourly computer is still being made. When the body also renamed the computer, the rename applied: `error` starts with `Renamed.` and the body carries `name`. |
| `500` | `{ "error": "…" }` | The update failed, for example because another computer in the workspace already has that `name`, or the body is not valid JSON. |
| `503` | `{ "error": "Ends aren’t set up on this server yet. Try again later, or leave the end out.", "code": "ENDS_UNAVAILABLE", "retryable": true }` | The body sends `ends_at` or `ends_in_hours` where ends are not set up yet. Nothing changed. |
| `503` | `{ "error": "Service temporarily unavailable. …" }` | Orgo could not verify the credential because of a server-side fault. The response carries `Retry-After: 5`. Retry after that delay. |


## OpenAPI

````yaml PATCH /computers/{id}
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: contact@orgo.ai
    url: https://orgo.ai
servers:
  - url: https://www.orgo.ai/api
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Support
    description: >-
      Orgo’s support agent, for programs: ask how to do something in Orgo and
      get an answer with full URLs and copyable commands.
  - name: Account
    description: >-
      Account capacity: how many computers an account may run, and adding or
      giving back more.
  - name: Agent accounts
    description: >-
      Accounts an AI agent makes for itself, and the claim link a person uses to
      take one over.
  - 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
  - name: Chat
    description: Run an agent on a computer through OpenAI-compatible chat completions.
paths:
  /computers/{id}:
    patch:
      tags:
        - Computers
      summary: Update computer
      description: >-
        Renames a computer, sets its mascot, or sets, moves or clears when it
        ends. Fields you omit are left alone. Renaming and the mascot need you
        to own the workspace; the end needs write access to it. The end is
        `ends_at` (in the future, at most 720 hours away) or `ends_in_hours` (1
        to 720), not both; `null` for either takes the end off. Only Linux and
        Windows computers can have an end. Any change of the end clears
        `ended_at`. On a running computer that runs by the hour the prepay moves
        with the end: a later end holds the extra (`402` when the credit cannot
        cover it plus an hour of your other hourly computers, nothing changed),
        an earlier end gives back what is past it, and `null` gives back what it
        has not used and bills it by the minute again. A first end the credit
        cannot prepay is still set and billed by the minute, with
        `prepay_warning`. Only the workspace owner prepays, and on a paid plan
        only signed in or with a key that has full access or Billing write;
        anyone else with write access still sets the end, nothing more is held,
        and the answer carries `prepay_warning`. A computer on the plan prepays
        nothing.
      operationId: updateComputer
      parameters:
        - name: id
          in: path
          required: true
          description: Computer ID. Accepts the computer's UUID or its `instance_id`.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  minLength: 1
                  description: >-
                    New name, 80 characters at most. Omitted, the name is left
                    alone. An empty, whitespace-only, or longer name is refused
                    with `400`.
                  example: agent-1
                  maxLength: 80
                bot_mascot:
                  description: >-
                    The computer's mascot appearance. Omitted, the mascot is
                    left alone; `null` clears it. Any value that is neither an
                    object nor `null` is refused with `400`.
                  oneOf:
                    - $ref: '#/components/schemas/BotMascot'
                    - type: 'null'
                ends_at:
                  type:
                    - string
                    - 'null'
                  format: date-time
                  description: >-
                    When the computer ends: in the future, at most 720 hours (30
                    days) from now. `null` takes the end off, so the computer is
                    kept until you stop or delete it. Omitted, the end is left
                    alone. Sending back the `ends_at` the computer already has
                    changes nothing, even when that time has passed. Send
                    `ends_at` or `ends_in_hours`, not both.
                ends_in_hours:
                  type:
                    - integer
                    - 'null'
                  minimum: 1
                  maximum: 720
                  description: >-
                    When the computer ends, in whole hours from now. `null`
                    takes the end off. Omitted, the end is left alone.
            examples:
              rename:
                summary: Rename
                value:
                  name: agent-1
              mascot:
                summary: Set the mascot
                value:
                  bot_mascot:
                    color: teal
                    expression: focused
                    accessory: glasses
              clear-mascot:
                summary: Clear the mascot
                value:
                  bot_mascot: null
              end-in-hours:
                summary: End 8 hours from now
                value:
                  ends_in_hours: 8
              end-at:
                summary: End at a time
                value:
                  ends_at: '2026-04-08T09:00:00Z'
              keep:
                summary: Keep it forever
                value:
                  ends_at: null
      responses:
        '200':
          description: >-
            Computer updated. A rename or mascot change carries `bot_mascot` and
            `updated_at`; a change of the end carries the end fields, and for a
            computer that runs by the hour the prepay after the change.
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    example: a3bb189e-8bf9-3888-9912-ace4e6543002
                  name:
                    type: string
                    example: agent-1
                  bot_mascot:
                    description: >-
                      Present unless the body sent only an end. The stored
                      mascot, or `null` when none is set.
                    oneOf:
                      - $ref: '#/components/schemas/BotMascot'
                      - type: 'null'
                  updated_at:
                    type: string
                    format: date-time
                    description: Present alongside `bot_mascot`.
                  ends_at:
                    type:
                      - string
                      - 'null'
                    format: date-time
                    description: >-
                      Present when the body changed the end, or sent only the
                      end the computer already has. When the computer ends.
                      `null` when it never ends.
                  ended_at:
                    type:
                      - string
                      - 'null'
                    format: date-time
                    description: >-
                      Present when the body changed the end, or sent only the
                      end the computer already has. When Orgo stopped the
                      computer because its time ran out, or marked it ended if
                      it was already off. `null` when it has not ended, and
                      after any change of the end.
                  deletes_at:
                    type:
                      - string
                      - 'null'
                    format: date-time
                    description: >-
                      Present when the body changed the end, or sent only the
                      end the computer already has. When Orgo deletes an ended
                      computer: 7 days after `ended_at`. Starting it before then
                      keeps it. `null` when it has not ended.
                  prepaid_until:
                    type:
                      - string
                      - 'null'
                    format: date-time
                    description: >-
                      Present when the end of a computer that runs by the hour
                      changed. A computer that runs by the hour: when its
                      prepaid run ends. `null` when it is billed by the minute.
                  prepaid_cents:
                    type:
                      - integer
                      - 'null'
                    description: >-
                      Present when the end of a computer that runs by the hour
                      changed. What is held from your credits for the prepaid
                      run, in cents. `null` when `prepaid_until` is.
                  prepay_returned_cents:
                    type: integer
                    description: >-
                      Present when some of an earlier prepay came back to your
                      credits, in cents.
                  prepay_warning:
                    type: string
                    description: >-
                      Present when the end was set but its time was not prepaid,
                      so it is billed by the minute: `The new time is billed by
                      the minute. Only the account owner can prepay it, signed
                      in or with a key that has Billing write.` when you may not
                      prepay, or `The new end is set, and the time to it is
                      billed by the minute: your credit does not cover prepaying
                      all of it.` when the credit is short.
              examples:
                rename:
                  summary: Rename
                  value:
                    id: a3bb189e-8bf9-3888-9912-ace4e6543002
                    name: agent-1
                    bot_mascot:
                      color: teal
                      expression: focused
                      accessory: glasses
                    updated_at: '2026-04-07T11:02:00Z'
                end:
                  summary: Moved the end of an hourly computer later
                  value:
                    id: a3bb189e-8bf9-3888-9912-ace4e6543002
                    name: agent-1
                    ends_at: '2026-04-07T19:35:00.000Z'
                    ended_at: null
                    deletes_at: null
                    prepaid_until: '2026-04-07T19:35:00.000Z'
                    prepaid_cents: 48
                    prepay_returned_cents: 18
                not-prepaid:
                  summary: End set by someone who may not prepay
                  value:
                    id: a3bb189e-8bf9-3888-9912-ace4e6543002
                    name: agent-1
                    ends_at: '2026-04-07T19:35:00.000Z'
                    ended_at: null
                    deletes_at: null
                    prepaid_until: '2026-04-07T14:35:00.000Z'
                    prepaid_cents: 24
                    prepay_warning: >-
                      The new time is billed by the minute. Only the account
                      owner can prepay it, signed in or with a key that has
                      Billing write.
        '400':
          description: >-
            `name` is empty, not a string, or longer than 80 characters,
            `bot_mascot` is neither an object nor `null`, or the body changes
            the read-only `device_tag`. An end that breaks the rules returns
            `INVALID_ENDS`; an end on a computer that cannot have one (not Linux
            or Windows, a trial computer, a Bops computer, or one paid by its
            own subscription or reservation) returns `ENDS_NOT_SUPPORTED`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                empty-name:
                  summary: Empty name
                  value:
                    error: Computer name cannot be empty
                bad-mascot:
                  summary: Bad mascot
                  value:
                    error: bot_mascot must be an object or null
                long-name:
                  summary: Name too long
                  value:
                    error: Computer name must be 80 characters or fewer
                both:
                  summary: Both end fields
                  value:
                    error: Send ends_at or ends_in_hours, not both.
                    code: INVALID_ENDS
                hours:
                  summary: '`ends_in_hours` out of range'
                  value:
                    error: >-
                      ends_in_hours must be a whole number of hours from 1 to
                      720, or null for never.
                    code: INVALID_ENDS
                not-a-time:
                  summary: '`ends_at` is not a time'
                  value:
                    error: ends_at must be an ISO 8601 time, or null for never.
                    code: INVALID_ENDS
                past:
                  summary: '`ends_at` has passed'
                  value:
                    error: ends_at must be in the future.
                    code: INVALID_ENDS
                too-far:
                  summary: '`ends_at` more than 720 hours away'
                  value:
                    error: ends_at can be at most 720 hours (30 days) from now.
                    code: INVALID_ENDS
                ends-not-supported:
                  summary: A computer that cannot have an end
                  value:
                    error: Only Linux and Windows computers can have an end.
                    code: ENDS_NOT_SUPPORTED
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          description: >-
            The computer is a trial computer whose trial is no longer active, or
            its own payment has lapsed; it is a Mac, iPhone, or Android phone
            locked for its account being over capacity and the body sends
            anything other than `name` (`COMPUTER_LOCKED`, with `lock`); or a
            later end on a running hourly computer needs more credit than there
            is (`insufficient_credit`, with `needed_cents`, `available_cents`,
            and `keep_cents` when there is any). Nothing changed. When the body
            also renamed the computer, the rename applied: `error` starts with
            `Renamed.` and the body carries `name`.
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
                  code:
                    type: string
                  lock:
                    type: object
                    description: 'With `COMPUTER_LOCKED`: `reason`, `locked_at`, and `cap`.'
                  name:
                    type: string
                    description: Present when the rename applied.
                  needed_cents:
                    type: integer
                    description: >-
                      The prepay (for a moved end, the extra) plus `keep_cents`,
                      rounded up.
                  available_cents:
                    type: integer
                    description: What your credit has, rounded down.
                  keep_cents:
                    type: integer
                    description: >-
                      Present when other hourly computers of yours are billed by
                      the minute: an hour of their rates, which a prepay always
                      leaves.
              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.
                locked:
                  summary: >-
                    A locked device computer, and the body sends more than
                    `name`
                  value:
                    error: >-
                      This computer is locked because your account is over its
                      plan of 3 computers. It keeps running and its files stay
                      on it. Delete a computer you no longer need, or contact
                      us, to unlock it.
                    code: COMPUTER_LOCKED
                    lock:
                      reason: over_capacity
                      locked_at: '2026-04-07T10:00:00.000Z'
                      cap: 3
                prepay:
                  summary: Not enough credit to move the end later
                  value:
                    error: Moving the end needs $0.22 more credit. You have $0.10.
                    code: insufficient_credit
                    needed_cents: 22
                    available_cents: 10
                prepay-keep:
                  summary: >-
                    Not enough credit for the extra and an hour of your other
                    hourly computers
                  value:
                    error: >-
                      Moving the end needs $0.33 more credit: $0.22 for the
                      extra time and $0.11 for an hour of your other computers.
                      You have $0.10.
                    code: insufficient_credit
                    needed_cents: 33
                    available_cents: 10
                    keep_cents: 11
        '403':
          $ref: '#/components/responses/AccessDenied'
        '404':
          description: >-
            No computer with this id, or you have write access to the workspace
            but do not own it.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                no-computer:
                  summary: Unknown computer
                  value:
                    error: Desktop not found
                not-owner:
                  summary: Member with write access, not the owner
                  value:
                    error: Access denied
        '409':
          description: >-
            An operation holds the computer (a stop, a start, or Orgo's own stop
            or delete at the end), or an hourly computer is still being made, so
            its end did not change. Retry in a minute. When the body also
            renamed the computer, the rename applied: `error` starts with
            `Renamed.` and the body carries `name`.
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
                  code:
                    type: string
                    enum:
                      - COMPUTER_BUSY
                  retryable:
                    type: boolean
                  name:
                    type: string
              example:
                error: >-
                  This computer is busy right now, so its end did not change.
                  Try again in a minute.
                code: COMPUTER_BUSY
                retryable: true
        '500':
          description: >-
            The update failed, for example because another computer in the
            workspace already has that `name`, or the body is not valid JSON.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                duplicate-name:
                  summary: Name already used in the workspace
                  value:
                    error: >-
                      Failed to update computer: duplicate key value violates
                      unique constraint "desktops_project_name_unique"
                other:
                  summary: Any other failure
                  value:
                    error: …
        '503':
          description: >-
            Ends are not set up on this server yet (`ENDS_UNAVAILABLE`,
            `retryable: true`), and the body sent an end: nothing changed. Also
            returned, with `Retry-After: 5`, when Orgo could not verify the
            credential because of a server-side fault. Retry.
          headers:
            Retry-After:
              description: 'Present on the credential fault: `5`.'
              schema:
                type: string
                example: '5'
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
                  code:
                    type: string
                  retryable:
                    type: boolean
              examples:
                ends-unavailable:
                  summary: Ends not set up yet
                  value:
                    error: >-
                      Ends aren’t set up on this server yet. Try again later, or
                      leave the end out.
                    code: ENDS_UNAVAILABLE
                    retryable: true
                auth:
                  summary: Credential could not be verified
                  value:
                    error: >-
                      Service temporarily unavailable. The database is not
                      accepting requests. Retry shortly.
components:
  schemas:
    BotMascot:
      type: object
      description: >-
        The computer's mascot appearance. Every field is optional; an omitted
        field falls back to the app default. An unrecognised field or value is
        dropped rather than rejected, so a client one release ahead of the API
        degrades one field instead of failing the whole write.
      properties:
        color:
          type: string
          enum:
            - stone
            - pearl
            - graphite
            - ink
            - green
            - blue
            - red
            - orange
            - purple
            - cyan
            - pink
            - yellow
            - teal
            - coral
        expression:
          type: string
          enum:
            - deadpan
            - friendly
            - focused
            - thinking
            - excited
            - sleepy
            - surprised
            - skeptical
            - worried
            - mischievous
        accessory:
          type: string
          enum:
            - none
            - beanie
            - tophat
            - party
            - glasses
            - sunglasses
            - bow
    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.
  responses:
    Unauthorized:
      description: 'No usable credential. Send `Authorization: Bearer $ORGO_API_KEY`.'
      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
    AccessDenied:
      description: >-
        You are not the owner or a member of the computer's workspace, you have
        view-only access, or the API key is scoped to another workspace.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            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).
                code: 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).
                code: workspace_scope_mismatch
  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.