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

# Platform API

> Changelog and migration steps for the Platform API

export const Separator = () => {
  return <div className="border-t border-white opacity-10 my-2" />;
};

export const DELETE = () => <Badge color="red">DELETE</Badge>;

export const PATCH = () => <Badge color="orange">PATCH</Badge>;

export const POST = () => <Badge color="blue">POST</Badge>;

export const GET = () => <Badge color="green">GET</Badge>;

export const PlatformApiReleaseLinks = ({version}) => {
  const linkVersion = version.split('.')[0];
  return <ul>
      <li>
        API reference:{' '}
        <a href={`/references/platform-api/${linkVersion}`} target="_blank" rel="noopener noreferrer">
          {version}
        </a>
      </li>
      <li>
        OpenAPI spec:{' '}
        <a href={`https://assets.mirurobotics.com/docs/openapi/platform/${linkVersion}.yaml`} target="_blank" rel="noopener noreferrer">
          Download YAML
        </a>
      </li>
    </ul>;
};

export const Dropdown = ({title, defaultOpen = false, children}) => {
  const [isOpen, setIsOpen] = React.useState(defaultOpen);
  function cn(...inputs) {
    return inputs.filter(Boolean).join(' ');
  }
  return <div>
            <button className="w-full flex justify-between items-center py-3 bg-transparent 
                border-none cursor-pointer text-left" onClick={() => setIsOpen(!isOpen)} aria-expanded={isOpen}>
                <span className="font-bold text-gray-100 text-md">
                    {title}
                </span>
                <svg className={cn("transition-transform duration-200 opacity-50 flex-shrink-0", isOpen && 'rotate-90')} width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                    <polyline points="6 4 10 8 6 12"></polyline>
                </svg>
            </button>

            {isOpen && <div className="pb-3 space-y-4">
                    {React.Children.map(children, (child, i) => <div key={i}>{child}</div>)}
                </div>}
        </div>;
};

# 2026-05-06.rainier

*May 12, 2026*

The `rainier` release introduces a provisioning-token flow that replaces the activation-token endpoint, expands supported config-instance content formats, restores the `removing` deployment status, and adds expandable `current_release` / `current_deployment` fields on devices.

<PlatformApiReleaseLinks version="2026-05-06.rainier" />

## New endpoints

<Dropdown title="Provisioning">
  * <POST /> `/provisioning_tokens` — create a provisioning token to add a device to your workspace
</Dropdown>

## Breaking changes

<Dropdown title="Activation tokens replaced by provisioning tokens">
  The `POST /devices/{device_id}/activation_token` endpoint has been removed. Callers should migrate to `POST /provisioning_tokens` instead.

  ```diff theme={null}
  - POST /devices/{device_id}/activation_token
  + POST /provisioning_tokens
  ```

  Provisioning tokens are not scoped to a pre-existing device — create a token first, then use it to provision a new device or activate an existing device. Visit the [provisioning tokens](/cfg-mgmt/provision-devices/provisioning-tokens) documentation for more details.
</Dropdown>

## Additive changes

<Dropdown title="Instance content enum">
  Config instances now support YAML content in addition to JSON.

  ```diff theme={null}
  # Instance Content format enum
    "json"
  + "yaml"
  ```
</Dropdown>

<Separator />

<Dropdown title="Deployment activity status">
  `removing` is added back to the `activity_status` and `status` enums. This is a partial reversal of the tetons change, where deployments transitioned directly from `deployed` to `archived`. Deployments can sit in `removing` while config instances are torn down on the device before reaching `archived`.

  ```diff theme={null}
  # status / activity_status enum
    "staged"
    "drifted"
    "queued"
    "deployed"
  + "removing"
    "archived"
  ```
</Dropdown>

<Separator />

<Dropdown title="Device query parameters">
  Device endpoints now support a few new query parameters:

  1. Expand the `current_deployment` field on a device.

  ```diff theme={null}
    GET /devices
  + GET /devices?expand=current_deployment
  ```

  2. Expand the `current_release` field on a device.

  ```diff theme={null}
    GET /devices
  + GET /devices?expand=current_release
  ```

  3. Filter devices by `current_release_id` when listing devices.

  ```diff theme={null}
    GET /devices
  + GET /devices?current_release_id=rls_123
  ```
</Dropdown>

## Migration steps

<Steps>
  <Step title="Update the Miru-Version header">
    Set `Miru-Version: 2026-05-06.rainier` on all API requests. [Python SDK](/developers/platform-api/sdks#python) `v0.10.0` marks the major version rollout of the `2026-05-06.rainier` API. For the latest SDK version compatibility information, visit the [Platform SDKs](/developers/platform-api/sdks) page.
  </Step>

  <Step title="Migrate from activation tokens to provisioning tokens">
    Migrate install workflows to use [provisioning tokens](/cfg-mgmt/provision-devices/provisioning-tokens) instead of activation tokens.
  </Step>

  <Step title="Optionally adopt new additive surface">
    * Handle `yaml` content format where needed
    * Handle `removing` deployment status or activity status where needed.
    * Implement or migrate to `expand=current_release` and/or `expand=current_deployment` for retrieving the current release or deployment on a device.
  </Step>
</Steps>

***

# 2026-03-09.tetons

*March 13, 2026*

The `tetons` release introduces API versioning and overhauls the representation of deployments, config instances, and config schemas. It introduces management of more configuration resources (config types, schemas, and instances), release creation, git commit tracking, and explicit deployment lifecycle actions.

<PlatformApiReleaseLinks version="2026-03-09.tetons" />

## New endpoints

<Dropdown title="Auth">
  * <GET /> `/principal` — retrieve the current principal
</Dropdown>

<Separator />

<Dropdown title="Config types">
  * <GET /> `/config_types` — list config types
  * <GET /> `/config_types/{id}` — retrieve a config type
  * <POST /> `/config_types` — create a config type
  * <PATCH /> `/config_types/{id}` — update a config type
</Dropdown>

<Separator />

<Dropdown title="Config schemas">
  * <GET /> `/config_schemas` — list config schemas<br />
  * <GET /> `/config_schemas/{id}` — retrieve a config schema
  * <POST /> `/config_schemas` — create a config schema<br />
</Dropdown>

<Separator />

<Dropdown title="Config instances">
  * <POST /> `/config_instances` — create a config instance
  * <GET /> `/config_instances/{id}/content` - download config instance content
</Dropdown>

<Separator />

<Dropdown title="Deployments">
  * <POST /> `/deployments/{id}/deploy` — deploy a deployment
  * <POST /> `/deployments/{id}/archive` — archive a deployment
  * <GET /> `/deployments/{id}/drifts` — list deployment drifts
</Dropdown>

<Separator />

<Dropdown title="Devices">
  * <POST /> `/devices/{id}/ping` — ping a device
</Dropdown>

<Separator />

<Dropdown title="Git commits">
  * <GET /> `/git_commits` — list git commits
  * <GET /> `/git_commits/{id}` — retrieve a git commit
  * <POST /> `/git_commits` — create a git commit
</Dropdown>

<Separator />

<Dropdown title="Releases">
  * <POST /> `/releases` — create a release
</Dropdown>

## Breaking changes

<Dropdown title="Miru-Version header">
  Requests require the `Miru-Version` header.

  ```diff theme={null}
    curl --request GET \
      --url 'https://api.mirurobotics.com/beta/devices' \
      --header 'X-API-Key: <api-key>' \
  +   --header 'Miru-Version: 2026-03-09.tetons'
  ```
</Dropdown>

<Separator />

<Dropdown title="Optional total_count">
  When listing resources, the `total_count` field is now omitted from the response if not expanded (i.e. `expand=total_count`) instead of being set to `-1`.

  ```diff theme={null}
    {
      "object": "list",
  -   "total_count": -1,
      ...
    }
  ```
</Dropdown>

<Separator />

<Dropdown title="Optional instead of nullable expansions">
  If an expansion is not included in the response, the field is omitted instead of being set to `null`. For example, the config instance response previously included `content`, `config_schema`, and `config_type` fields as null if not expanded. Now these fields are omitted if not expanded.

  ```diff theme={null}
    {
      "object": "config_instance",
      "id": "cfg_inst_123",
      ...
  -   "content": null,
  -   "config_schema": null,
  -   "config_type": null
    }
  ```

  Most resources are affected by this change, including config instances, config schemas, config types, releases, and deployments. Devices are unaffected.
</Dropdown>

<Separator />

<Dropdown title="Deployment activity status">
  * Renamed `needs_review` to `drifted`.
  * Removed `removing` and `validating`—deployments now transition directly from `deployed` to `archived`.

  ```diff theme={null}
  # activity_status enum values
  - "validating"
    "staged"
  - "needs_review"
  + "drifted"
    "queued"
    "deployed"
  - "removing"
    "archived"
  ```

  These changes are also reflected in the deployment's [status](/primitives/deployments#status) field.
</Dropdown>

<Separator />

<Dropdown title="Create deployment request">
  * Replaced inline config instance creation with explicit config instance IDs. Create config instances separately via `POST /config_instances` first, then reference them by ID.
  * Renamed `patch_source_id` to `parent_id`.

  ```diff theme={null}
  # POST /deployments request body
    {
      "release_id": "rls_123",
      "target_status": "staged",
  -   "new_config_instances": [
  -     {
  -       "content": { "speed": 100 },
  -       "relative_filepath": "/v1/motion-control.json"
  -     }
  -   ],
  +   "config_instance_ids": ["cfg_inst_123"],
  -   "patch_source_id": "dpl_456"
  +   "parent_id": "dpl_456"
    }
  ```
</Dropdown>

<Separator />

<Dropdown title="Config instance response">
  * Renamed `relative_filepath` to `filepath`.
  * Removed `device_id`, `activity_status`, `error_status`, `target_status`, and `status` fields. These fields now exclusively exist in the deployment resource.
  * Removed `updated_at` field. Config instances are immutable.

  ```diff theme={null}
    {
      "object": "config_instance",
      "id": "cfg_inst_123",
      "config_schema_id": "cfg_sch_123",
      "config_type_id": "cfg_type_123",
      "created_at": "2025-10-21T00:00:00Z"
  -   "relative_filepath": "/v1/motion-control.json",
  +   "filepath": "/v1/motion-control.json",
  -   "activity_status": "deployed",
  -   "device_id": "dev_123",
  -   "device": null,
  -   "error_status": "none",
  -   "status": "deployed",
  -   "target_status": "deployed",
  -   "updated_at": "2025-10-21T00:00:00Z",
      ...
    }
  ```

  * `content` now returns a string and its data format (e.g. `json`, `yaml`) instead of a raw JSON object.

  ```diff theme={null}
    {
  -   "content": "{...}",
  +   "content": {
  +     "format": "json",
  +     "data": "<stringified JSON>",
      }
    }
  ```
</Dropdown>

<Separator />

<Dropdown title="Config schema response">
  * Renamed `relative_filepath` to `instance_filepath`.
  * Removed `version`

  ```diff theme={null}
    {
      "id": "cfg_sch_123",
      "config_type_id": "cfg_type_123",
  -   "relative_filepath": "/v1/motion-control.json",
  +   "instance_filepath": "/v1/motion-control.json",
  -   "version": 1,
      ...
    }
  ```

  * `content` is replaced by `documents`, which supports schema languages that can be defined across multiple files.

  ```diff theme={null}
    {
  -   "content": "{...}",
  +   "documents": [
  +      {
  +        "id": "doc_123",
  +        "name": "main.json",
  +        "data": "<stringified JSON, YAML, CUE, etc.>",
  +      }
  +    ]
    }
  ```
</Dropdown>

<Separator />

<Dropdown title="Config instance query parameters">
  Listing config instances no longer supports the `device_id`, `activity_status`, `error_status`, and `target_status` filters since these fields no longer exist in the config instance resource.
</Dropdown>

<Separator />

<Dropdown title="Device query parameters">
  Listing devices no longer supports the `current_release_id` filter.
</Dropdown>

<Separator />

<Dropdown title="Removed endpoints">
  Deleting devices is no longer supported.

  * <DELETE /> `/devices/{device_id}`
</Dropdown>

## Additive changes

<Dropdown title="Expansion Query Parameter">
  Expansions can now be specified using the `expand` query parameter in addition to the `expand[]` query parameter.

  ```diff theme={null}
  curl --request GET \
    --url 'https://api.mirurobotics.com/beta/config_instances?expand=content' \
    --header 'X-API-Key: <api-key>' \
    --header 'Miru-Version: 2026-03-09.tetons'
  ```
</Dropdown>

<Separator />

<Dropdown title="Config instance response">
  Added the `config_type_name` field, allowing you to retrieve the name of the config type without expanding the config type resource.

  ```diff theme={null}
    {
      "id": "cfg_inst_123",
      "config_schema_id": "cfg_sch_123",
      "config_type_id": "cfg_type_123",
  +   "config_type_name": "motion-control",
      ...
      "created_at": "2025-10-21T00:00:00Z"
    }
  ```
</Dropdown>

<Separator />

<Dropdown title="Config schema response">
  * Added the `config_type_name` field, allowing you to retrieve the name of the config type without expanding the config type resource.
  * Added the `format` and `language` fields, supporting multiple schema formats and languages.

  ```diff theme={null}
    {
      "id": "cfg_sch_123",
      "config_type_id": "cfg_type_123",
  +   "config_type_name": "motion-control",
  +   "format": "json",
  +   "language": "jsonschema",
      ...
      "created_at": "2025-10-21T00:00:00Z"
    }
  ```
</Dropdown>

<Separator />

<Dropdown title="Device response">
  Added `agent_version` field, indicating the version of the Miru Agent running on the device.

  ```diff theme={null}
    {
      "id": "dev_123",
      "name": "Robot 11",
      "status": "online",
  +   "agent_version": "v0.7.0",
      ...
      "created_at": "2025-10-21T00:00:00Z"
    }
  ```
</Dropdown>

<Separator />

<Dropdown title="Release response">
  Added `git_commit_id` linking releases to their source commit.

  ```diff theme={null}
    {
      "id": "rls_123",
      "version": "v1.0.0",
  +   "git_commit_id": "git_cmt_123",
      "created_at": "2025-10-21T00:00:00Z"
    }
  ```
</Dropdown>

## Python SDK

Beginning with the `2026-03-09.tetons` release, the Python SDK is published from [python-platform-sdk](https://github.com/mirurobotics/python-platform-sdk) and uses the `miru_platform_sdk` import path.

```diff theme={null}
- from miru_server_sdk import Miru
+ from miru_platform_sdk import Miru
```

The previous Python SDK was published to [python-server-sdk](https://github.com/mirurobotics/python-server-sdk) and used the `miru_server_sdk` import path.

Furthermore, SDK `v0.7.0` marks the major version rollout of the `2026-03-09.tetons` API. For the latest SDK version compatibility information, see the [Platform SDKs](/developers/platform-api/sdks) page.

## Migration steps

<Steps>
  <Step title="Set the Miru-Version header">
    Set the `Miru-Version: 2026-03-09.tetons` header on all API requests. If you are using the [Python SDK](/developers/platform-api/sdks#python), this is done automatically.
  </Step>

  <Step title="Migrate breaking changes">
    Migrate your client application according to the breaking changes listed above.

    If you are using the [Python SDK](/developers/platform-api/sdks#python), migrate from the legacy repository [python-server-sdk](https://github.com/mirurobotics/python-server-sdk) to [python-platform-sdk](https://github.com/mirurobotics/python-platform-sdk) and update imports from `miru_server_sdk` to `miru_platform_sdk`.
  </Step>

  <Step title="Optionally integrate new endpoints">
    Optionally integrate the new endpoints listed above.
  </Step>
</Steps>

***

# 2025-10-21.zion

*October 21, 2025*

<Danger>
  The `2025-10-21.zion` API version is no longer supported. See [supported versions](/developers/platform-api/versioning#supported-versions).
</Danger>

Initial release of the Platform API. This version establishes core API endpoints for managing the deployment pipeline—from defining configurations through releasing and deploying to devices.

<PlatformApiReleaseLinks version="2025-10-21.zion" />

## Endpoints

<Dropdown title="Devices">
  * <GET /> `/devices` — list devices
  * <GET /> `/devices/{device_id}` — retrieve a device
  * <POST /> `/devices` — create a device
  * <PATCH /> `/devices/{device_id}` — update a device
  * <DELETE /> `/devices/{device_id}` — delete a device
  * <POST /> `/devices/{device_id}/activation_token` — create an activation token
</Dropdown>

<Separator />

<Dropdown title="Releases">
  * <GET /> `/releases` — list releases
  * <GET /> `/releases/{release_id}` — retrieve a release
</Dropdown>

<Separator />

<Dropdown title="Deployments">
  * <GET /> `/deployments` — list deployments
  * <GET /> `/deployments/{deployment_id}` — retrieve a deployment
  * <POST /> `/deployments` — create a deployment
</Dropdown>

<Separator />

<Dropdown title="Config instances">
  * <GET /> `/config_instances` — list config instances
  * <GET /> `/config_instances/{config_instance_id}` — retrieve a config instance
</Dropdown>

## Query parameters

<Dropdown title="Filters">
  Filtering allows you to narrow list results by resource fields like `id`, `device_id`, `status`, and more. Check out the [Filtering](/developers/platform-api/query-params/filtering) documentation for more details.
</Dropdown>

<Separator />

<Dropdown title="Sorting">
  Sort list results with `order_by=<field_name>:<direction>`. Most endpoints default to `order_by=created_at:desc`. Check out the [Sorting](/developers/platform-api/query-params/sorting) documentation for more details.
</Dropdown>

<Separator />

<Dropdown title="Expansions">
  Include related resources in responses with `expand[]` (e.g. `expand[]=config_schema`). See [Expansions](/developers/platform-api/query-params/expansions) documentation for more details.
</Dropdown>

<Separator />

<Dropdown title="Pagination">
  All list endpoints support offset-based pagination with `offset` and `limit`. Check out the [Pagination](/developers/platform-api/query-params/pagination) documentation for more details.
</Dropdown>

## Python SDK

`2025-10-21.zion` comes with an official Python SDK published to [python-server-sdk](https://github.com/mirurobotics/python-server-sdk). For more details on usage, visit the [python-server-sdk](https://github.com/mirurobotics/python-server-sdk) repository.

<Danger>
  The [python-server-sdk](https://github.com/mirurobotics/python-server-sdk) repository is no longer supported. Please migrate to the [python-platform-sdk](https://github.com/mirurobotics/python-platform-sdk) repository for the latest version of the Platform API.
</Danger>

***
