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

# Build template

> Bake a template version into a golden snapshot.

Builds the [golden snapshot](/guides/templates/introduction#golden-snapshots) for a version: Orgo boots a computer, runs the build steps and app installs, then captures a paused snapshot. A built template launches in seconds; an unbuilt one cannot launch at all.

This call is **asynchronous** and returns immediately with `202 Accepted`. The build is queued for a dedicated build runner. Track progress by polling [Get build status](/api-reference/templates/build-status).

Requests are idempotent while a build is in flight: if a job for the same content is already queued or running, you get that job back instead of a second one. At most 10 of your builds can be queued or running at once.

<Note>
  Building templates requires a [Scale plan](https://orgo.ai/pricing) or higher. You can also build at publish time with [`POST /templates?auto_build=true`](/api-reference/templates/publish). Reading the build status is not gated.
</Note>

<Tip>
  The build is where `on_first_boot` runs, and it never runs again on a launch. `on_every_boot` runs during the build and again on any launch that cold-boots, such as one that injects secrets. See [hooks](/guides/templates/schema#hooks).
</Tip>

## Path parameters

<ParamField path="namespace" type="string" required>Template namespace.</ParamField>
<ParamField path="name" type="string" required>Template name.</ParamField>
<ParamField path="version" type="string" required>Version (semver) to build.</ParamField>

## Query parameters

<ParamField query="tier" type="string">
  Build runner to use: `standard` (2 vCPU, 8 GB), `fast` (4 vCPU, 16 GB), or `turbo` (8 vCPU, 32 GB). Omitted, Orgo picks the smallest runner that holds the template's `hardware`. Any other value returns `400`. A runner smaller than the template's hardware returns `422`.
</ParamField>

<ParamField query="launch" type="boolean" default="false">
  Set to `true` to create a computer from the template as soon as the build is ready. Only the exact string `true` enables it. The launch goes through the same plan and quota checks as [Create computer](/api-reference/computers/create).
</ParamField>

<ParamField query="project" type="string">
  Workspace ID for the computer that `launch=true` creates. You must belong to the workspace, or the call returns `403`. Omitted, Orgo picks one of your workspaces.
</ParamField>

## Response

<ResponseField name="ref" type="string">Template ref.</ResponseField>
<ResponseField name="digest" type="string">Content-addressed digest being built.</ResponseField>

<ResponseField name="status" type="string">
  `queued` while the job waits for a runner, `building` once a runner has claimed it.
</ResponseField>

<ResponseField name="jobId" type="string">Build job ID.</ResponseField>
<ResponseField name="phase" type="string">Current job phase, e.g. `queued`.</ResponseField>
<ResponseField name="tier" type="string">Build runner tier: `standard`, `fast`, or `turbo`.</ResponseField>
<ResponseField name="ahead" type="integer">Queued jobs across all accounts that will run before this one.</ResponseField>
<ResponseField name="launchOnReady" type="boolean">Whether a computer is created when the build is ready. For a job that was already in flight, this is that job's setting, not this request's.</ResponseField>

The shape above comes from the build queue. Production runs with the queue on, so this is the shape you get from `www.orgo.ai`. The queue is off by default in a deployment that does not enable it, and there the call still returns `202`, but with the older build-result shape: `ref`, `digest`, and `status` (`building`, or `ready` when a golden snapshot for this content already exists), without `jobId`, `phase`, `tier`, `ahead`, or `launchOnReady`. The `tier`, `launch`, and `project` query parameters are ignored in that mode.

## Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://www.orgo.ai/api/templates/default/claude-code/1.0.0/build \
    -H "Authorization: Bearer $ORGO_API_KEY"
  ```

  ```python Python theme={null}
  import os, requests, time

  ref = "default/claude-code/1.0.0"
  base = f"https://www.orgo.ai/api/templates/{ref}/build"
  hdr = {"Authorization": f"Bearer {os.environ['ORGO_API_KEY']}"}

  requests.post(base, headers=hdr)                 # kick off
  while True:                                       # poll to ready
      status = requests.get(base, headers=hdr).json()["status"]
      print(status)
      if status in ("ready", "failed", "not_built"):
          break
      time.sleep(5)
  ```

  ```javascript JavaScript theme={null}
  const base =
    "https://www.orgo.ai/api/templates/default/claude-code/1.0.0/build";
  const hdr = { Authorization: `Bearer ${process.env.ORGO_API_KEY}` };

  await fetch(base, { method: "POST", headers: hdr });
  let status = "building";
  while (status === "building") {
    await new Promise((r) => setTimeout(r, 5000));
    status = (await (await fetch(base, { headers: hdr })).json()).status;
  }
  console.log(status);
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "ref": "default/claude-code@1.0.0",
  "digest": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2",
  "status": "queued",
  "jobId": "9f1c2d3e-4b5a-4c6d-8e7f-0a1b2c3d4e5f",
  "phase": "queued",
  "tier": "standard",
  "ahead": 0,
  "launchOnReady": false
}
```

## Cancel a build

Send a `DELETE` to the same build path to cancel a build that no runner has claimed yet. It returns `202` with `{ "status": "cancelled" }`, and the version's status reads `not_built` afterwards. A build a runner has already claimed runs to completion. When nothing is queued, Orgo falls back to cancelling on the template registry host: if that host had a build to cancel, the call returns `202` with `{ "status": "cancelling" }`. Otherwise, including for a build a runner has already claimed, it returns `404` with `{ "status": "idle" }`.

```bash theme={null}
curl -X DELETE https://www.orgo.ai/api/templates/default/claude-code/1.0.0/build \
  -H "Authorization: Bearer $ORGO_API_KEY"
```

## Errors

| Status | Body | Meaning |
| - | - | - |
| `400` | `{ "error": "unknown build tier \"<tier>\"" }` | `tier` is not `standard`, `fast`, or `turbo`. |
| `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` | `{ "error": "This endpoint requires an account-wide credential (workspace_scope_mismatch)." }` | The key is workspace-scoped. Template endpoints need an account-wide key. This route answers with `401`, not `403`. |
| `401` | `{ "error": "Service temporarily unavailable. …" }` | Orgo could not verify the key because of a server-side fault. The key is fine. Retry. |
| `403` | `{ "error": string, "code": "UPGRADE_REQUIRED", "upgradeTier": "scale_v2" }` | Below Scale, or your plan could not be verified. The gate fails closed, and no build starts. |
| `403` | `{ "error": string, "code": "PLAN_LIMIT", "upgradeTier": "enterprise" }` | Your account is on a custom plan that does not include templates. No build starts. |
| `403` | `{ "error": "you do not have access to that workspace" }` | `project` names a workspace you do not belong to. |
| `409` | `{ "error": string }` | No such version is published in your namespaces, so there is nothing to build. Publish it first. |
| `422` | `{ "error": string, "code": "HARDWARE_EXCEEDS_BUILD_RUNNER" }` | The template's `hardware` does not fit the requested `tier`, or any runner. The message names the smallest runner that fits. |
| `429` | `{ "error": string }` | You already have 10 builds queued or running. Wait for one to finish. |
| `500` | `{ "error": "internal error" }` | Unexpected server error. |

`DELETE` (cancel) is not plan-gated and takes no query parameters. Its `404` body is `{ "status": "idle" }`, not an `error` object.


## OpenAPI

````yaml POST /templates/{namespace}/{name}/{version}/build
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:
  /templates/{namespace}/{name}/{version}/build:
    post:
      tags:
        - Templates
      summary: Build template
      description: >-
        Queues a golden-snapshot build for a dedicated build runner and returns
        `202` immediately. Poll `GET` on the same path. Idempotent while a build
        for the same content is in flight: you get that job back. At most 10 of
        your builds can be queued or running at once. Requires a Scale plan.
      operationId: buildTemplate
      parameters:
        - name: namespace
          in: path
          required: true
          schema:
            type: string
        - name: name
          in: path
          required: true
          schema:
            type: string
        - name: version
          in: path
          required: true
          schema:
            type: string
        - name: tier
          in: query
          required: false
          description: >-
            Build runner: `standard` (2 vCPU, 8 GB), `fast` (4 vCPU, 16 GB), or
            `turbo` (8 vCPU, 32 GB). Omitted, the smallest runner that holds the
            template's `hardware`. Any other value returns `400`; a runner
            smaller than the template's hardware returns `422`.
          schema:
            type: string
            enum:
              - standard
              - fast
              - turbo
        - name: launch
          in: query
          required: false
          description: >-
            `true` creates a computer from the template as soon as the build is
            ready, with the same plan and quota checks as `POST /computers`.
            Only the exact string `true` enables it.
          schema:
            type: string
            default: 'false'
        - name: project
          in: query
          required: false
          description: >-
            Workspace ID for the computer that `launch=true` creates. You must
            belong to it, or the call returns `403`. Omitted, Orgo picks one of
            your workspaces.
          schema:
            type: string
      responses:
        '202':
          description: Build queued, or the in-flight job for the same content
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BuildJob'
              example:
                ref: default/claude-code@1.0.0
                digest: >-
                  a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2
                status: queued
                jobId: 9f1c2d3e-4b5a-4c6d-8e7f-0a1b2c3d4e5f
                phase: queued
                tier: standard
                ahead: 0
                launchOnReady: false
        '400':
          description: '`tier` is not `standard`, `fast`, or `turbo`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateError'
              examples:
                tier:
                  summary: Unknown tier
                  value:
                    error: unknown build tier "huge"
        '401':
          $ref: '#/components/responses/UnauthorizedTemplates'
        '403':
          description: >-
            Below Scale, or your plan could not be verified (the gate fails
            closed and no build starts), your account is on a custom plan that
            does not include templates (`PLAN_LIMIT`), or `project` names a
            workspace you do not belong to.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/TemplateError'
                  - $ref: '#/components/schemas/QuotaError'
              examples:
                upgrade:
                  summary: Below Scale
                  value:
                    error: …
                    code: UPGRADE_REQUIRED
                    upgradeTier: scale_v2
                plan-limit:
                  summary: A custom plan that does not include templates
                  value:
                    error: >-
                      Your plan doesn't include building templates. Contact us
                      to add them to your plan.
                    code: PLAN_LIMIT
                    upgradeTier: enterprise
                workspace:
                  summary: Not your workspace
                  value:
                    error: you do not have access to that workspace
        '409':
          description: >-
            No such version is published in your namespaces, so there is nothing
            to build. Publish it first.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateError'
              example:
                error: …
        '422':
          description: >-
            The template's `hardware` does not fit the requested `tier`, or any
            runner. The message names the smallest runner that fits.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateError'
              example:
                error: …
                code: HARDWARE_EXCEEDS_BUILD_RUNNER
        '429':
          description: >-
            You already have 10 builds queued or running. Wait for one to
            finish.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateError'
              example:
                error: …
        '500':
          $ref: '#/components/responses/TemplateInternalError'
components:
  schemas:
    BuildJob:
      type: object
      description: A build queued for a dedicated build runner.
      properties:
        ref:
          type: string
          example: default/claude-code@1.0.0
        digest:
          type: string
          description: Content-addressed digest being built.
        status:
          type: string
          enum:
            - queued
            - building
          description: >-
            `queued` while the job waits for a runner, `building` once a runner
            has claimed it.
        jobId:
          type: string
          description: Build job ID.
        phase:
          type: string
          description: Current job phase, such as `queued`.
        tier:
          type: string
          enum:
            - standard
            - fast
            - turbo
          description: Build runner tier.
        ahead:
          type: integer
          description: Queued jobs across all accounts that will run before this one.
        launchOnReady:
          type: boolean
          description: >-
            Whether a computer is created when the build is ready. For a job
            already in flight, that job's setting, not this request's.
    TemplateError:
      type: object
      description: >-
        A failure from the template registry, relayed with the registry's own
        status and code.
      required:
        - error
      properties:
        error:
          type: string
        code:
          type: string
          description: Machine-readable reason, when the registry supplied one.
        details:
          description: >-
            Per-field validation errors, or the raw upstream body when it was
            not JSON.
          oneOf:
            - type: array
              items:
                $ref: '#/components/schemas/ValidationError'
            - type: string
    QuotaError:
      type: object
      description: >-
        The request was refused by the plan the workspace owner is on rather
        than by ownership. See https://orgo.ai/pricing for what each plan
        includes.
      required:
        - error
      properties:
        error:
          type: string
        code:
          type: string
          description: >-
            Machine-readable reason. Values this API emits: `UPGRADE_REQUIRED`,
            `DESKTOP_LIMIT`, `VM_SLOT_ADDON`, `RAM_ADDON`,
            `PER_COMPUTER_RAM_CAP`, `VCPU_ADDON`, `PER_COMPUTER_CPU_CAP`,
            `DISK_QUOTA_EXCEEDED`, `disk_exceeds_quota`,
            `WINDOWS_REQUIRES_SCALE`, `GUEST_RESTRICTED`, `NOT_A_MEMBER`,
            `CHANGE_PLAN`, `PLAN_LIMIT`, `upgrade_required`.
        upgradeTier:
          type: string
          description: The plan that would allow the request.
        canManageCapacity:
          type: boolean
          description: True when you own the workspace and can raise the limit yourself.
        max_ram_gb:
          type: integer
          description: >-
            On a RAM refusal from resize: the largest RAM a live resize can
            reach for this computer.
        max_disk_gb:
          type: integer
          description: 'On a storage refusal: the largest disk this computer may have.'
    ValidationError:
      type: object
      properties:
        field:
          type: string
          description: Dotted path to the offending field.
          example: hardware.cpu
        code:
          type: string
          example: invalid_enum
        message:
          type: string
        hint:
          type: string
    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:
    UnauthorizedTemplates:
      description: >-
        No usable credential, or a workspace-scoped key. Template endpoints need
        an account-wide key and answer a scoped one 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
            account-wide-required:
              summary: The API key is workspace-scoped
              value:
                error: >-
                  This endpoint requires an account-wide credential
                  (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.
    TemplateInternalError:
      description: >-
        Unexpected server error (`internal error`), or the template registry
        host failed or timed out, with the underlying message in `error`. Retry.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/TemplateError'
          examples:
            internal:
              summary: Unexpected server error
              value:
                error: internal error
            timeout:
              summary: The registry host did not answer in time
              value:
                error: timeout of 30000ms exceeded
  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.