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

# Create

> Stage or deploy a new deployment.

| Scope                | Required                            |
| -------------------- | ----------------------------------- |
| `deployments:write`  | Yes                                 |
| `deployments:stage`  | Required if staging a deployment.   |
| `deployments:deploy` | Required if deploying a deployment. |


## OpenAPI

````yaml /references/platform-api/2026-08-17.yaml post /deployments
openapi: 3.0.3
info:
  title: Miru Platform API
  description: The API between Miru and any external client
  version: 2026-08-17.everglades
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
  x-release-version: 2026-08-17.everglades
  x-git-commit:
    sha: b0d008b18d840e3f7ad65ae4beb60b19863b665e
    url: >-
      https://github.com/mirurobotics/openapi/commit/b0d008b18d840e3f7ad65ae4beb60b19863b665e
    message: >-
      refactor(platform): remove bulk device move (#251)


      ## What


      Removes device→group *movement* from the platform audience. Two things

      go, together:


      1. **`POST /devices/move/bulk` (`bulkMoveDevices`)** — the path item in

      `apis/apps/backend-server/platform/paths/devices.yaml`, its entry in

      `platform/openapi.yaml`, and the `devices.bulk_move` method in

      `tools/stainless/platform.yml`.

      2. **`group_id` on the platform `CreateDeviceRequest`** — the only place

      `group_id` appeared in a platform request body.


      Device→group membership is now **fully read-only** on the platform API.


      ## What deliberately stays


      Nothing on the *read* side moved, and group structure stays writable:


      | Kept | Why |

      |---|---|

      | `group_id` on the `Device` schema | read field, unaffected |

      | `expand=group` on `Device`, and `group` in `DeviceExpansion` /

      `DeviceListExpansion` | read surface |

      | `group_id` filter on `GET /devices` (`device_search_group_id`) | read

      surface |

      | `GET /groups`, `GET /groups/{group_id}`, `POST /groups`, `PATCH

      /groups/{group_id}` | group CRUD is orthogonal to device membership |

      | **`POST /groups/{group_id}/move` (`moveGroup`)** | reparents a

      **group** in the tree, not devices between groups — different resource,

      different scope, and reversible by another reparent |

      | `apis/configs/components/requests/device.yaml#/BulkMoveDevicesRequest`

      | still referenced by `frontend` and `cli`, which keep their `bulk_move`

      methods |


      `moveGroup` surviving is the thing worth double-checking in review,

      since "move" appears on both resources. Verification below gates on it

      explicitly.


      ## Why create-time `group_id` goes with the endpoint


      This is the load-bearing part, not an incidental tidy-up.


      Without a move operation, a create-time `group_id` is a **one-way

      door**. A device could be placed into a group at provision time and then

      never moved out, reassigned, or relocated in the tree — through the API,

      ever. Shipping a write that can be exercised exactly once per resource

      lifetime is worse than shipping no write at all, because it hands

      customers a state they cannot get out of without the dashboard.


      So both go together, and the result is coherent: you can *see* which

      group a device is in, expand the group object, and filter a device list

      by group. You cannot set or change it.


      ## Not breaking


      `platform/2026-05-06.rainier` — the last **stable** platform release —

      has **no bulk-move endpoint and no groups resource at all**. `POST

      /devices/move/bulk` and create-time `group_id` existed only in the

      prereleases `platform/2026-08-17.everglades-beta.3` and

      `everglades-beta.4`.


      Withdrawing beta-only surface before everglades goes stable is free;

      after it goes stable it would not be. Same reasoning as #244 (upload

      collections) and #250 (the `devices:move` scope).


      ## Verification


      `./scripts/regen.sh`, `./scripts/lint.sh`, and `./scripts/preflight.sh`

      (`=== All checks passed ===`) all clean; `./scripts/is-stale.sh` reports

      `All generated specs are up to date.`


      - **Platform route count 25 → 24.**

      - **Scope histogram: `devices:write` 3 → 2**, `groups:write` unchanged

      at **3**, everything else unchanged.

      - Zero hits for `move/bulk`, `bulkMoveDevices`, or `BulkMoveDevices`

      anywhere in the platform tree or bundle; zero `bulk` in

      `tools/stainless/platform.yml`.

      - `CreateDeviceRequest` in the bundle is down to `name` alone — no

      `group_id`.

      - The generated `Device` block still carries `group_id` (required +

      property) and the `group` expandable; `group` present in **both**

      expansion enums; two `name: group_id` query params still in the bundle.

      - All five group routes present, `moveGroup` included.

      - Platform bundle diff is `0 55` — a pure deletion. No other audience's

      bundle changed and `apis/configs/` is untouched.


      A bare `grep group_id` is useless here — it matches the group path

      param, the `Device` read field, the `DvcSearch` enum member, and the

      list filter, all of which survive. Every check above is scoped to a

      specific schema block or uses a precise pattern.


      Plan: `plans/active/20260817-remove-platform-bulk-device-move.md`.


      ## Follow-ups


      **Release.** A new `platform/2026-08-17.everglades-beta.5` must be cut

      after merge — **tag the squash-merge commit on `main`**, not the branch

      head. Tagging a branch head makes the release job skip silently and

      publish nothing.


      **Backend.** Three changes:

      - Remove the `bulkMoveDevices` HTTP wiring.

      - Re-stub `CreateDevice.GetGroupID()` back to `optnull.None[string]()`.

      - Revert `Perms.Devices.Move` out of **both** `devices:write` and

      `devices:manage` — it was added to `devices:write` in #624 solely for

      this endpoint.


      **Docs.** docs#158 must drop the endpoint from the everglades changelog

      and from `authz.mdx`.


      <!-- codesmith:footer -->

      ---

      <a

      href="https://app.blacksmith.sh/mirurobotics/codesmith/openapi/pr/251"><picture><source

      media="(prefers-color-scheme: dark)"

      srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source

      media="(prefers-color-scheme: light)"

      srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img

      alt="View with [code]smith"

      src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a>

      <a

      href="https://backend.blacksmith.sh/track/enable-autofix?expires=1789530880&installation_model_id=425273&pr_number=251&repository=mirurobotics%2Fopenapi&return_to=https%3A%2F%2Fgithub.com%2Fmirurobotics%2Fopenapi%2Fpull%2F251&signature=2eb2605a3305593f4e312c9f2a422d741a1a5991955adf57e51041a329830e09"><picture><source

      media="(prefers-color-scheme: dark)"

      srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source

      media="(prefers-color-scheme: light)"

      srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img

      alt="Autofix with [code]smith"

      src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a>

      <sup>Need help on this PR? Tag <code>@codesmith</code> with what you

      need. Autofix is disabled.</sup>


      <!-- codesmith:autofix:disabled -->

      <!-- /codesmith:footer -->


      ---------


      Co-authored-by: Claude <noreply@anthropic.com>
    author: ben-miru
    branch: HEAD
    dirty: false
  x-build:
    built_at: '2026-08-17T04:08:03.448835+00:00'
servers:
  - url: https://api.mirurobotics.com/beta
    description: Miru Platform API
security:
  - ApiKeyAuth: []
paths:
  /deployments:
    parameters:
      - $ref: '#/components/parameters/MiruVersion'
    post:
      tags:
        - Deployments
      summary: Create
      description: Stage or deploy a new deployment.
      operationId: createDeployment
      parameters:
        - $ref: '#/components/parameters/deployment_expansions'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateDeploymentRequest'
      responses:
        '200':
          description: Successfully created the deployment.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Deployment'
components:
  parameters:
    MiruVersion:
      name: Miru-Version
      in: header
      required: true
      schema:
        type: string
        example: 2026-08-17.everglades
      description: The API version the client was built against.
    deployment_expansions:
      name: expand
      in: query
      required: false
      description: Fields to expand on the deployment resource.
      schema:
        type: array
        items:
          $ref: '#/components/schemas/DeploymentExpansion'
        example:
          - device
  schemas:
    CreateDeploymentRequest:
      title: Create Deployment Request
      type: object
      required:
        - target_status
        - description
        - release_id
        - device_id
        - config_instance_ids
      properties:
        target_status:
          $ref: '#/components/schemas/CreateDeploymentTargetStatus'
        description:
          type: string
          example: Deployment for the motion control config instance
          description: The description of the deployment.
        release_id:
          type: string
          description: The release ID which this deployment adheres to.
          example: rls_123
        parent_id:
          type: string
          nullable: true
          description: >
            Parent deployment ID used as an optimistic-concurrency token.
            Tristate:

            - omitted: server fills with the device's current
            `target_deployment_id`; no concurrency check.

            - null: caller asserts the device has no current target; 409 if it
            does.

            - value: caller asserts the device's current target equals this ID;
            409 if it does not match.
          example: dpl_123
        device_id:
          type: string
          description: The ID of the device that the deployment is being created for.
          example: dvc_123
        config_instance_ids:
          type: array
          description: >-
            The IDs of the config instances to deploy. A deployment must include
            config instances according to the config schemas slots defined in
            the release.
          items:
            type: string
            example: cfg_inst_123
    Deployment:
      title: Deployment
      allOf:
        - $ref: '#/components/schemas/BaseDeployment'
        - type: object
          required:
            - parent_id
            - queued_at
            - deployed_at
            - archived_at
          properties:
            parent_id:
              type: string
              nullable: true
              example: dpl_123
              description: >-
                ID of the deployment that this deployment was patched from. Null
                if this deployment has no parent.
            queued_at:
              type: string
              format: date-time
              example: '2021-01-01T00:00:00Z'
              nullable: true
              description: Timestamp of when the deployment was queued.
            deployed_at:
              type: string
              format: date-time
              example: '2021-01-01T00:00:00Z'
              nullable: true
              description: Timestamp of when the deployment was deployed.
            archived_at:
              type: string
              format: date-time
              example: '2021-01-01T00:00:00Z'
              nullable: true
              description: Timestamp of when the deployment was archived.
            device:
              allOf:
                - $ref: '#/components/schemas/Device'
              description: Expand the device using 'expand=device' in the query string.
            release:
              allOf:
                - $ref: '#/components/schemas/Release'
              description: Expand the release using 'expand=release' in the query string.
            parent:
              allOf:
                - $ref: '#/components/schemas/Deployment'
              nullable: true
              description: >-
                The parent deployment that this deployment was patched from.
                Null if this deployment has no parent. Expand the parent using
                'expand=parent' in the query string.
            config_instances:
              type: array
              items:
                $ref: '#/components/schemas/ConfigInstance'
              description: >-
                Expand the config instances using 'expand=config_instances' in
                the query string.
              example:
                - object: config_instance
                  id: cfg_inst_123
                  config_type_name: Motion Control
                  filepath: /srv/miru/configs/v1/motion-control.json
                  slot_key: default
                  created_at: '2021-01-01T00:00:00Z'
                  config_schema_id: cfg_sch_123
                  config_type_id: cfg_typ_123
                - object: config_instance
                  id: cfg_inst_124
                  config_type_name: Localization
                  filepath: /srv/miru/configs/v1/localization/primary.json
                  slot_key: primary
                  created_at: '2021-01-01T00:00:00Z'
                  config_schema_id: cfg_sch_124
                  config_type_id: cfg_typ_124
      example:
        object: deployment
        id: dpl_123
        description: Deployment for the motion control config instance
        status: staged
        activity_status: staged
        error_status: none
        target_status: staged
        device_id: dvc_123
        release_id: rls_123
        parent_id: null
        created_at: '2024-01-01T00:00:00Z'
        updated_at: '2024-01-01T00:00:00Z'
        queued_at: null
        deployed_at: null
        archived_at: null
    DeploymentExpansion:
      type: string
      enum:
        - device
        - release
        - parent
        - config_instances
      x-enum-varnames:
        - DEPLOYMENT_EXPAND_DEVICE
        - DEPLOYMENT_EXPAND_RELEASE
        - DEPLOYMENT_EXPAND_PARENT
        - DEPLOYMENT_EXPAND_CONFIG_INSTANCES
    CreateDeploymentTargetStatus:
      type: string
      description: >
        Desired state of the deployment.


        `staged` means the deployment is ready for deployment. Deployments can
        only be staged if their release is not the device's current release.


        `deployed` means the deployment should be deployed to the device.
        Deployments can only be deployed if their release is the device's
        current release.
      enum:
        - staged
        - deployed
      x-enum-varnames:
        - CREATE_STAGED_DEPLOYMENT
        - CREATE_DEPLOYED_DEPLOYMENT
    BaseDeployment:
      title: Base Deployment
      type: object
      required:
        - object
        - id
        - description
        - status
        - activity_status
        - error_status
        - target_status
        - device_id
        - release_id
        - created_at
        - updated_at
      properties:
        object:
          type: string
          enum:
            - deployment
          example: deployment
          x-stainless-const: true
          description: The object type, which is always `deployment`.
        id:
          type: string
          example: dpl_123
          description: ID of the deployment.
        description:
          type: string
          example: Deployment for the motion control config instance
          description: The description of the deployment.
        status:
          $ref: '#/components/schemas/DeploymentStatus'
        activity_status:
          $ref: '#/components/schemas/DeploymentActivityStatus'
        error_status:
          $ref: '#/components/schemas/DeploymentErrorStatus'
        target_status:
          $ref: '#/components/schemas/DeploymentTargetStatus'
        device_id:
          type: string
          example: dvc_123
          description: ID of the device.
        release_id:
          type: string
          example: rls_123
          description: ID of the release.
        created_at:
          type: string
          format: date-time
          example: '2024-01-01T00:00:00Z'
          description: Timestamp of when the device release was created.
        updated_at:
          type: string
          format: date-time
          example: '2024-01-01T00:00:00Z'
          description: Timestamp of when the device release was last updated.
    Device:
      allOf:
        - $ref: '#/components/schemas/BaseDevice'
        - type: object
          required:
            - group_id
          properties:
            group_id:
              type: string
              nullable: true
              example: grp_123
              description: >-
                ID of the group this device belongs to. Null if the device is
                unassigned.
            current_deployment:
              allOf:
                - $ref: '#/components/schemas/Deployment'
              nullable: true
              description: The current deployment for the device.
            current_release:
              allOf:
                - $ref: '#/components/schemas/Release'
              nullable: true
              description: The current release for the device.
            group:
              allOf:
                - $ref: '#/components/schemas/Group'
              nullable: true
              description: >-
                The group this device belongs to. Null if the device is
                unassigned.
      example:
        object: device
        id: dvc_123
        name: My Device
        description: Welder on line 3
        status: online
        agent_version: v1.0.0
        last_connected_at: '2021-01-01T00:00:00Z'
        last_disconnected_at: null
        created_at: '2021-01-01T00:00:00Z'
        updated_at: '2021-01-01T00:00:00Z'
        group_id: grp_123
    Release:
      title: Release
      allOf:
        - $ref: '#/components/schemas/BaseRelease'
        - type: object
          properties:
            config_schemas:
              type: array
              items:
                $ref: '#/components/schemas/ConfigSchema'
              description: >-
                Expand the config schemas using 'expand=config_schemas' in the
                query string.
              example:
                - object: config_schema
                  id: cfg_sch_123
                  digest: sha256:1234567890
                  config_type_name: Motion Control
                  instance_slots:
                    - key: default
                      name: Default
                      filepath: /srv/miru/configs/v1/motion-control.json
                      required: true
                  instance_format: json
                  created_at: '2021-01-01T00:00:00Z'
                  updated_at: '2021-01-01T00:00:00Z'
                  config_type_id: cfg_typ_123
                  language: jsonschema
                  format: json
                - object: config_schema
                  id: cfg_sch_124
                  digest: sha256:1234567890
                  config_type_name: Localization
                  instance_slots:
                    - key: primary
                      name: Primary
                      filepath: /srv/miru/configs/v1/localization/primary.json
                      required: true
                    - key: secondary
                      name: Secondary
                      filepath: /srv/miru/configs/v1/localization/secondary.json
                      required: false
                  instance_format: json
                  created_at: '2021-01-01T00:00:00Z'
                  updated_at: '2021-01-01T00:00:00Z'
                  config_type_id: cfg_typ_124
                  language: jsonschema
                  format: json
      example:
        object: release
        id: rls_123
        version: v1.0.0
        git_commit_id: git_commit_123
        created_at: '2024-01-01T00:00:00Z'
        updated_at: '2024-01-01T00:00:00Z'
    ConfigInstance:
      title: Config Instance
      allOf:
        - $ref: '#/components/schemas/BaseConfigInstance'
        - type: object
          properties:
            config_schema:
              allOf:
                - $ref: '#/components/schemas/ConfigSchema'
              description: >-
                Expand the config schema using 'expand=config_schema' in the
                query string.
            config_type:
              allOf:
                - $ref: '#/components/schemas/ConfigType'
              description: >-
                Expand the config type using 'expand=config_type' in the query
                string.
            content:
              allOf:
                - $ref: '#/components/schemas/InstanceContent'
              description: >-
                The configuration values associated with the config instance.
                Expand the content using 'expand=content' in the query string.
      example:
        object: config_instance
        id: cfg_inst_123
        config_type_name: Motion Control
        filepath: /srv/miru/configs/v1/motion-control.json
        slot_key: default
        created_at: '2021-01-01T00:00:00Z'
        config_schema_id: cfg_sch_123
        config_type_id: cfg_typ_123
    DeploymentStatus:
      type: string
      description: >
        This status merges the 'activity_status' and 'error_status' fields, with
        error states taking precedence over activity states when errors are
        present. For example, if the activity status is 'deployed' but the error
        status is 'failed', the status is 'failed'. However, if the error status
        is 'none' and the activity status is 'deployed', the status is
        'deployed'.
      enum:
        - drifted
        - staged
        - queued
        - deployed
        - removing
        - archived
        - failed
        - retrying
      x-enum-varnames:
        - DEPLOYMENT_STATUS_DRIFTED
        - DEPLOYMENT_STATUS_STAGED
        - DEPLOYMENT_STATUS_QUEUED
        - DEPLOYMENT_STATUS_DEPLOYED
        - DEPLOYMENT_STATUS_REMOVING
        - DEPLOYMENT_STATUS_ARCHIVED
        - DEPLOYMENT_STATUS_FAILED
        - DEPLOYMENT_STATUS_RETRYING
    DeploymentActivityStatus:
      type: string
      description: >
        Last known activity state of the deployment.


        `drifted` means the device's configurations have drifted since this
        deployment was staged, and the deployment needs to be reviewed before it
        can be deployed.


        `staged` means the deployment is ready to be deployed.


        `queued` means the deployment's config instances are waiting to be
        received by the device and will be deployed as soon as the device is
        online.


        `deployed` means the deployment's config instances are currently
        available for consumption on the device.


        `removing` means the deployment's config instances are being removed
        from the device.


        `archived` means the deployment is available for historical reference
        but cannot be deployed and is not active on the device.
      enum:
        - drifted
        - staged
        - queued
        - deployed
        - removing
        - archived
      x-enum-varnames:
        - DEPLOYMENT_ACTIVITY_STATUS_DRIFTED
        - DEPLOYMENT_ACTIVITY_STATUS_STAGED
        - DEPLOYMENT_ACTIVITY_STATUS_QUEUED
        - DEPLOYMENT_ACTIVITY_STATUS_DEPLOYED
        - DEPLOYMENT_ACTIVITY_STATUS_REMOVING
        - DEPLOYMENT_ACTIVITY_STATUS_ARCHIVED
    DeploymentErrorStatus:
      type: string
      description: >
        Last known error state of the deployment.


        `none` means there are no errors.


        `retrying` means an error has been encountered and the agent is retrying
        to reach the target status.


        `failed` means a fatal error has been encountered; the deployment is
        archived and, if deployed, removed from the device.
      enum:
        - none
        - failed
        - retrying
      x-enum-varnames:
        - DEPLOYMENT_ERROR_STATUS_NONE
        - DEPLOYMENT_ERROR_STATUS_FAILED
        - DEPLOYMENT_ERROR_STATUS_RETRYING
    DeploymentTargetStatus:
      type: string
      description: >
        Desired state of the deployment.


        `staged` means the deployment is ready to be deployed.


        `deployed` means all config instances in the deployment are available
        for consumption on the device.


        `archived` means the deployment is available for historical reference
        but cannot be deployed and is not active on the device.
      enum:
        - staged
        - deployed
        - archived
      x-enum-varnames:
        - DEPLOYMENT_TARGET_STATUS_STAGED
        - DEPLOYMENT_TARGET_STATUS_DEPLOYED
        - DEPLOYMENT_TARGET_STATUS_ARCHIVED
    BaseDevice:
      title: Base Device
      type: object
      required:
        - object
        - id
        - name
        - description
        - status
        - agent_version
        - last_connected_at
        - last_disconnected_at
        - created_at
        - updated_at
      properties:
        object:
          type: string
          enum:
            - device
          example: device
          x-stainless-const: true
          description: The object type, which is always `device`.
        id:
          type: string
          example: dvc_123
          description: ID of the device.
        name:
          type: string
          example: My Device
          description: Name of the device.
        description:
          type: string
          nullable: true
          example: Welder on line 3
          description: A free-form description of the device.
        status:
          $ref: '#/components/schemas/DeviceStatus'
        agent_version:
          type: string
          example: v1.0.0
          description: The version of the agent the device is running.
          nullable: true
        last_connected_at:
          type: string
          format: date-time
          example: '2021-01-01T00:00:00Z'
          nullable: true
          description: >-
            Timestamp of when the device was last made an initial connection
            (this is not the same as the last time the device was seen).
        last_disconnected_at:
          type: string
          format: date-time
          example: '2021-01-01T00:00:00Z'
          nullable: true
          description: >-
            Timestamp of when the device was last disconnected (this is not the
            same as the last time the device was seen).
        created_at:
          type: string
          format: date-time
          example: '2021-01-01T00:00:00Z'
          description: Timestamp of when the device was created.
        updated_at:
          type: string
          format: date-time
          example: '2021-01-01T00:00:00Z'
          description: Timestamp of when the device was last updated.
    Group:
      title: Group
      allOf:
        - $ref: '#/components/schemas/BaseGroup'
        - type: object
          properties:
            parent:
              allOf:
                - $ref: '#/components/schemas/Group'
              nullable: true
              description: >-
                The parent group. Null for top-level groups. Expand using
                `expand=parent` in the query string.
      example:
        object: group
        id: grp_789
        name: line-3
        parent_id: grp_456
        created_at: '2026-01-01T00:00:00Z'
        updated_at: '2026-01-01T00:00:00Z'
    BaseRelease:
      title: Base Release
      type: object
      required:
        - object
        - id
        - version
        - git_commit_id
        - created_at
        - updated_at
      properties:
        object:
          type: string
          enum:
            - release
          example: release
          x-stainless-const: true
          description: The object type, which is always `release`.
        id:
          type: string
          example: rls_123
          description: ID of the release.
        version:
          type: string
          example: v1.0.0
          description: The version of the release.
        git_commit_id:
          type: string
          nullable: true
          example: git_commit_123
          description: The ID of the git commit associated with this release.
        created_at:
          type: string
          format: date-time
          example: '2024-01-01T00:00:00Z'
          description: Timestamp of when the release was created.
        updated_at:
          type: string
          format: date-time
          example: '2024-01-01T00:00:00Z'
          description: Timestamp of when the release was last updated.
    ConfigSchema:
      title: Config Schema
      allOf:
        - $ref: '#/components/schemas/BaseConfigSchema'
        - type: object
          properties:
            config_type:
              allOf:
                - $ref: '#/components/schemas/ConfigType'
              description: >-
                Expand the config type using 'expand=config_type' in the query
                string.
      example:
        object: config_schema
        id: cfg_sch_123
        digest: sha256:1234567890
        config_type_name: Motion Control
        instance_slots:
          - key: default
            name: Default
            filepath: /srv/miru/configs/v1/motion-control.json
            required: true
        instance_format: json
        created_at: '2021-01-01T00:00:00Z'
        updated_at: '2021-01-01T00:00:00Z'
        config_type_id: cfg_typ_123
        language: jsonschema
        format: json
    BaseConfigInstance:
      title: Base Config Instance
      type: object
      required:
        - object
        - id
        - config_type_name
        - filepath
        - created_at
        - config_schema_id
        - config_type_id
        - slot_key
      properties:
        object:
          type: string
          enum:
            - config_instance
          example: config_instance
          x-stainless-const: true
          description: The object type, which is always `config_instance`.
        id:
          type: string
          example: cfg_inst_123
          description: ID of the config instance.
        config_type_name:
          type: string
          example: Motion Control
          description: The name of the config type.
        filepath:
          type: string
          example: /srv/miru/configs/v1/motion-control.json
          description: The absolute file system path where this config instance is written.
        slot_key:
          type: string
          example: controller_2
          description: >-
            The key of the config schema slot this instance is bound to. Must
            match the `key` of one of the slots declared by this instance's
            config schema.
        created_at:
          type: string
          format: date-time
          example: '2021-01-01T00:00:00Z'
          description: The timestamp of when the config instance was created.
        config_schema_id:
          type: string
          example: cfg_sch_123
          description: ID of the config schema which the config instance must adhere to.
        config_type_id:
          type: string
          example: cfg_type_123
          description: >-
            ID of the config type which the config instance (and its schema) is
            a part of.
    ConfigType:
      allOf:
        - $ref: '#/components/schemas/BaseConfigType'
      example:
        object: config_type
        id: cfg_typ_123
        name: Motion Control
        slug: motion-control
        created_at: '2021-01-01T00:00:00Z'
        updated_at: '2021-01-01T00:00:00Z'
        created_by_id: usr_123
        updated_by_id: usr_123
    InstanceContent:
      title: Instance Content
      type: object
      required:
        - format
        - data
      properties:
        format:
          $ref: '#/components/schemas/InstanceFormat'
        data:
          type: string
          description: The configuration values associated with the config instance.
          example: |
            {
              "enable_autonomy": true,
              "enable_remote_control": true,
              "max_payload_kg": 10.0
            }
      example:
        format: json
        data: |
          {
            "enable_autonomy": true,
            "enable_remote_control": true,
            "max_payload_kg": 10.0
          }
    DeviceStatus:
      type: string
      description: >
        The status of the device.

        - Inactive: The miru agent has not yet been installed / authenticated

        - Activating: The miru agent is currently being installed /
        authenticated (should only last for a few seconds)

        - Online: The miru agent has successfully pinged the server within the
        last 60 seconds.

        - Offline: The miru agent has not successfully pinged the server within
        the last 60 seconds (e.g. network issues, device is powered off, etc.)

        - Archived: The device has been archived. The agent's session has been
        revoked and the device no longer participates in workspace operations.
        See `archived_at` for when this occurred.
      enum:
        - inactive
        - activating
        - online
        - offline
        - archived
      x-enum-varnames:
        - DEVICE_STATUS_INACTIVE
        - DEVICE_STATUS_ACTIVATING
        - DEVICE_STATUS_ONLINE
        - DEVICE_STATUS_OFFLINE
        - DEVICE_STATUS_ARCHIVED
    BaseGroup:
      title: Base Group
      type: object
      required:
        - object
        - id
        - name
        - parent_id
        - created_at
        - updated_at
      properties:
        object:
          type: string
          enum:
            - group
          example: group
          x-stainless-const: true
          description: The object type, which is always `group`.
        id:
          type: string
          example: grp_123
          description: ID of the group.
        name:
          type: string
          example: production
          description: Name of the group.
        parent_id:
          type: string
          nullable: true
          example: grp_456
          description: ID of the parent group. Null for top-level groups.
        created_at:
          type: string
          format: date-time
          example: '2026-01-01T00:00:00Z'
          description: Timestamp of when the group was created.
        updated_at:
          type: string
          format: date-time
          example: '2026-01-01T00:00:00Z'
          description: Timestamp of when the group was last updated.
    BaseConfigSchema:
      title: Base Config Schema
      type: object
      required:
        - object
        - id
        - digest
        - config_type_name
        - instance_format
        - created_at
        - updated_at
        - config_type_id
        - language
        - format
        - instance_slots
      properties:
        object:
          type: string
          enum:
            - config_schema
          example: config_schema
          x-stainless-const: true
          description: The object type, which is always `config_schema`.
        id:
          type: string
          example: cfg_sch_123
          description: ID of the config schema.
        digest:
          type: string
          example: sha256:1234567890
          description: The digest of the config schema.
        config_type_name:
          type: string
          example: Motion Control
          description: The name of the config type.
        instance_slots:
          type: array
          minItems: 1
          description: >-
            The file system destinations this config schema writes to. Every
            config schema has at least one slot. Slots share the schema's
            validation and differ only in where the file is written; a file
            needing different validation is a different config type, not a slot.
            Slot keys and filepaths must each be unique within the schema, and
            slot filepaths must be unique across every config schema in a
            release.
          items:
            $ref: '#/components/schemas/InstanceSlot'
          example:
            - key: default
              name: Default
              filepath: /srv/miru/configs/v1/motion-control.json
              required: true
        instance_format:
          $ref: '#/components/schemas/InstanceFormat'
        created_at:
          type: string
          format: date-time
          example: '2021-01-01T00:00:00Z'
          description: Timestamp of when the config schema was created.
        updated_at:
          type: string
          format: date-time
          example: '2021-01-01T00:00:00Z'
          description: Timestamp of when the config schema was last updated.
        config_type_id:
          type: string
          example: cfg_typ_123
          description: ID of the config type.
        language:
          $ref: '#/components/schemas/SchemaLanguage'
        format:
          $ref: '#/components/schemas/SchemaFormat'
        documents:
          allOf:
            - $ref: '#/components/schemas/SchemaDocuments'
          description: >-
            Expand the config schema documents using `expand=documents` in the
            query string.
          example:
            - id: doc_123
              name: main.json
              data: |
                {
                  "$schema": "https://json-schema.org/draft/2020-12/schema",
                  "type": "object"
                }
    BaseConfigType:
      title: Config Type
      type: object
      required:
        - object
        - id
        - name
        - slug
        - created_at
        - updated_at
      properties:
        object:
          type: string
          enum:
            - config_type
          example: config_type
          x-stainless-const: true
          description: The object type, which is always `config_type`.
        id:
          type: string
          example: cfg_123
          description: ID of the config type.
        name:
          type: string
          example: My Config Type
          description: Name of the config type.
        slug:
          type: string
          example: my-config-type
          description: An immutable, code-friendly name for the config type.
        created_at:
          type: string
          format: date-time
          example: '2021-01-01T00:00:00Z'
          description: Timestamp of when the config type was created.
        updated_at:
          type: string
          format: date-time
          example: '2021-01-01T00:00:00Z'
          description: Timestamp of when the config type was last updated.
    InstanceFormat:
      title: Instance Format
      type: string
      description: >
        The on-disk format used when a config instance is written to the device
        filesystem.

        - `json`: standard JSON.

        - `yaml`: YAML 1.2.

        - `jsonc`: JSON with comments (JSON plus `//` and `/* */` comment
        syntax).

        - `xml`: XML.

        - `text`: plain, unstructured text with no specific format.
      enum:
        - json
        - yaml
        - jsonc
        - xml
        - text
      x-enum-varnames:
        - INSTANCE_FORMAT_JSON
        - INSTANCE_FORMAT_YAML
        - INSTANCE_FORMAT_JSONC
        - INSTANCE_FORMAT_XML
        - INSTANCE_FORMAT_TEXT
    InstanceSlot:
      title: Instance Slot
      type: object
      required:
        - key
        - name
        - filepath
        - required
      properties:
        key:
          type: string
          pattern: ^[a-z0-9][a-z0-9_-]*$
          maxLength: 128
          example: controller_2
          description: >-
            An immutable, code-friendly identifier for this slot, unique within
            the schema. Lowercase alphanumerics, underscores, and hyphens; must
            start with an alphanumeric; at most 128 characters.
        name:
          type: string
          example: Controller 2
          description: The human-readable name of this slot.
        filepath:
          type: string
          example: >-
            /var/local/forge/configuration/robot_drivers/controller_2/topic_list.yaml
          description: >-
            The absolute file system path where instances bound to this slot are
            written. Must be unique within the schema, and unique across every
            config schema in a release.
        required:
          type: boolean
          example: true
          description: >-
            Whether every deployment of a release containing this schema must
            include an instance for this slot. A deployment includes at most one
            config instance per slot.
        description:
          type: string
          example: Topic list for the second motor controller.
          description: An optional human-readable description of this slot.
      example:
        key: controller_2
        name: Controller 2
        filepath: >-
          /var/local/forge/configuration/robot_drivers/controller_2/topic_list.yaml
        required: true
        description: Topic list for the second motor controller.
    SchemaLanguage:
      title: Schema Language
      type: string
      example: jsonschema
      enum:
        - jsonschema
        - cue
        - opaque
      x-enum-varnames:
        - JSONSCHEMA
        - CUE
        - OPAQUE
    SchemaFormat:
      title: Schema Format
      type: string
      enum:
        - json
        - yaml
        - cue
      x-enum-varnames:
        - SCHEMA_FORMAT_JSON
        - SCHEMA_FORMAT_YAML
        - SCHEMA_FORMAT_CUE
    SchemaDocuments:
      type: array
      items:
        $ref: '#/components/schemas/SchemaDocument'
      example:
        - id: doc_123
          name: main.json
          data: |
            {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "type": "object"
            }
    SchemaDocument:
      title: Schema Document
      type: object
      required:
        - id
        - name
        - data
      properties:
        id:
          type: string
          description: The unique identifier for this document.
          example: doc_123
        name:
          type: string
          description: The document filename.
          example: main.json
        data:
          type: string
          description: The raw document content.
      example:
        id: doc_123
        name: main.json
        data: |
          {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object"
          }
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: The API key to use for authentication.

````