---
title: "Run an agent on a computer: OpenAI-shaped chat completions that drive the desktop"
method: POST
path: "/api/v1/chat/completions"
tags: ["agent"]
---

# Run an agent on a computer: OpenAI-shaped chat completions that drive the desktop

`POST /api/v1/chat/completions`

## Request

- Base URL: `https://www.orgo.ai`
- URL: `https://www.orgo.ai/api/v1/chat/completions`
- Auth: HTTP bearer

Sends the conversation to a model that operates the computer named by `computer_id` (clicks, types, runs commands) until it answers. The request and response follow OpenAI chat completions, plus `computer_id` and an `orgo` block, so the OpenAI SDKs work with base URL `https://www.orgo.ai/api/v1`. `messages[].content` is a string or OpenAI content parts (`text`, and `image_url` as an https or base64 data URL in user messages). Roles other than user and assistant are dropped, and the first remaining message must be from the user. With `stream: true` the answer arrives as `chat.completion.chunk` Server-Sent Events ending in `data: [DONE]`; only text streams, and the thread id is in the `X-Thread-Id` header. A stream that ends without a chunk carrying a `finish_reason` failed: it ends with an `error` chunk (`message`, `type`, and `code` for a refused own key) before `data: [DONE]`. Closing the connection stops the run at its next step; steps already taken are billed.

A run takes up to 250 model steps. `max_steps` raises that, up to 500; it never lowers it. A run that reaches its limit finishes with `finish_reason: "length"`.

Billed from AI credits by the workspace owner, unless you pay with your own model key: `x-openai-key` for a model OpenAI serves (`orgo-agent`, which runs GPT-6.1 Terra), `x-anthropic-key` for one Anthropic serves (the `claude-*` models and `orgo-agent-opus-5.5`). Then no credits are used, `orgo.cost_cents` is 0, and `orgo.own_key` says whose key paid. With no `model`, the key picks it: `x-openai-key` runs `orgo-agent` (also when you send both keys), `x-anthropic-key` alone runs `claude-sonnet-5`. On a computer `orgo-agent` does not run on, both keys run `claude-sonnet-5` and `x-openai-key` alone is refused (400 own_key_unsupported). `orgo-agent` asks OpenAI for its fast tier, so OpenAI bills your key at its fast tier rates. A key that can't pay for the model you name is refused too (400 own_key_model_mismatch), so a request that sends a key is never billed to credits. When the provider turns your key down, the error says so: 401 invalid_own_key (a bad or unauthorized key), 429 own_key_rate_limited (its rate limit or quota), 400 own_key_model_unavailable (a model the key can't use). Keys are used for the request only, never stored.

## Headers

- `x-openai-key` string
- `x-anthropic-key` string

## Request body

- object
  - `computer_id` string, required: The computer to drive (its id, or its instance id, which changes when the computer wakes from storage; prefer the id). It must be running.
  - `messages` object[], required
    - `role` string, required: user or assistant. Other roles are accepted and dropped.
    - `content` union, required
      - string
      - union[]
        - union
          - object
            - `type` 'text', required
            - `text` string, required
          - object
            - `type` 'image_url', required
            - `image_url` object, required
              - …
  - `model` 'orgo-agent' | 'orgo-agent-opus-5.5' | 'claude-sonnet-5' | 'claude-opus-5.5' | 'claude-opus-5' | 'claude-opus-4.8' | 'claude-sonnet-4.6' | 'claude-opus-4.6': Leave it out to get Orgo’s recommended engine for the computer and your key: `orgo-agent` (Computer Use) on Linux, Windows, macOS and iPhone computers with no key or with `x-openai-key`, Claude Sonnet 5 with only `x-anthropic-key`, or on other computers with no key or both keys (`x-openai-key` alone there is refused, own_key_unsupported). Name one to pin it. `orgo-agent` runs OpenAI’s GPT-6.1 Terra.
  - `stream` boolean
  - `thread_id` string, uuid: A thread to save this run to. It loads no history: send the whole conversation in messages every time, and the thread’s saved messages are replaced with them plus the reply. An unknown or non UUID id, a thread that isn’t yours, or, with a workspace scoped key, a thread on another computer starts a new thread.
  - `max_steps` integer: Raise the step limit. Lower values are treated as 250.

## Response `200`

The final answer. With `stream: true`, an event stream instead.

- object
  - `id` string
  - `object` 'chat.completion'
  - `created` integer
  - `model` string
  - `choices` object[]
  - `usage` object
    - `prompt_tokens` integer
    - `completion_tokens` integer
    - `total_tokens` integer
  - `orgo` object
    - `thread_id` string, nullable
    - `steps` integer
    - `cost_cents` integer
    - `own_key` 'anthropic' | 'openai' | 'null', nullable: Whose own key paid: `openai` (x-openai-key), `anthropic` (x-anthropic-key), or null when Orgo credits did. Also on the final stream chunk.
    - `credit_balance_cents` integer

## Other responses

- `400`: Bad input: missing_computer_id, invalid_model, invalid_messages (with `param`), empty_messages, invalid_message_order, invalid_json, body_missing (no body), body_incomplete (the body broke off before it all arrived: send it again), invalid_body (the body is not a JSON object), model_unsupported_os, or context_overflow. Or your own key: own_key_unsupported (only `x-openai-key`, and no OpenAI model runs on this computer or is open to your account), own_key_model_mismatch (the model you named runs on another provider), own_key_model_unavailable (the provider says your key can't use the model).
- `401`: Invalid API key (invalid_api_key), or the provider rejected your own key (invalid_own_key, with the provider's message).
- `402`: Out of AI credits (credits_exhausted), or a managed account at its monthly AI limit (account_ai_limit).
- `403`: AI is turned off for this account.
- `404`: The computer does not exist or is not yours (computer_not_found).
- `429`: Your plan's agent runs: too many this minute or at once (rate_limited, with `limit` chat_runs_per_minute or chat_runs_concurrent and `retry_after` in the error object, and Retry-After). Or your own key is over its provider's rate limit or out of quota (own_key_rate_limited).
- `500`: The run failed (internal_error). Steps it took are billed.
- `503`: The model is not available right now (model_not_configured).

## Changes

- **2026-10-28** `7b065cad3cdb`: 3 info
  - added the new optional `header` request parameter `x-openai-key`
  - added the non-success response with the status `429`
  - added the optional property `orgo/own_key` to the response with the `200` status
- **2026-10-09** `1b48b72ba024`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/orgo/apis/orgo-api/changes/api/v1/chat/completions/post.md)

---

[API](https://skmtc.dev/orgo/apis/orgo-api.md) - [All operations](https://skmtc.dev/orgo/apis/orgo-api/llms.txt) - [OpenAPI document](https://skmtc.dev/orgo/apis/orgo-api/revisions/e4c1e7379fa5?raw)
