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

# Overview

export const Framed = ({image, background, link, alt = "Framed content", borderWidth = "24px", outerRadius = "10px", innerRadius = "6px"}) => {
  const parseShorthand = value => {
    const values = String(value).trim().split(/\s+/);
    switch (values.length) {
      case 1:
        return [values[0], values[0], values[0], values[0]];
      case 2:
        return [values[0], values[1], values[0], values[1]];
      case 3:
        return [values[0], values[1], values[2], values[1]];
      default:
        return values.slice(0, 4);
    }
  };
  const isZero = v => parseFloat(v) === 0;
  const padding = parseShorthand(borderWidth);
  const outer = parseShorthand(outerRadius);
  const cornerMasks = [];
  if (isZero(padding[0]) && isZero(padding[3])) {
    cornerMasks.push(`radial-gradient(circle at 0% 0%, transparent ${outer[0]}, black ${outer[0]})`);
  }
  if (isZero(padding[0]) && isZero(padding[1])) {
    cornerMasks.push(`radial-gradient(circle at 100% 0%, transparent ${outer[1]}, black ${outer[1]})`);
  }
  if (isZero(padding[2]) && isZero(padding[1])) {
    cornerMasks.push(`radial-gradient(circle at 100% 100%, transparent ${outer[2]}, black ${outer[2]})`);
  }
  if (isZero(padding[2]) && isZero(padding[3])) {
    cornerMasks.push(`radial-gradient(circle at 0% 100%, transparent ${outer[3]}, black ${outer[3]})`);
  }
  const backgroundMask = cornerMasks.length > 0 ? cornerMasks.join(", ") : undefined;
  const innerImage = <img src={image} alt={alt} noZoom={link ? true : false} style={{
    display: "block",
    width: "100%",
    margin: 0,
    borderRadius: 0
  }} />;
  return <div style={{
    display: "inline-block",
    position: "relative",
    borderRadius: outerRadius,
    overflow: "hidden"
  }}>
            {}
            {background && <div style={{
    position: "absolute",
    inset: 0,
    backgroundImage: `url(${background})`,
    backgroundSize: "cover",
    maskImage: backgroundMask,
    WebkitMaskImage: backgroundMask,
    maskComposite: "intersect",
    WebkitMaskComposite: "source-in"
  }} />}
            {}
            <div style={{
    position: "relative",
    padding: borderWidth
  }}>
                <div style={{
    borderRadius: innerRadius,
    overflow: "hidden",
    lineHeight: 0
  }}>
                    {link ? <a href={link}>{innerImage}</a> : innerImage}
                </div>
            </div>
        </div>;
};

export const NullableBadge = ({size = "sm"}) => {
  return <Tooltip tip="Property does not need to be set">
            <Badge icon="circle" color="gray" size={size}>nullable</Badge>
        </Tooltip>;
};

export const EditableBadge = ({size = "sm"}) => {
  return <Tooltip tip="Property can be directly modified">
            <Badge icon="pencil" color="blue" size={size}>editable</Badge>
        </Tooltip>;
};

export const MutableBadge = ({size = "sm"}) => {
  return <Tooltip tip="Property is automatically updated by the system; cannot be modified directly">
            <Badge icon="feather" color="orange" size={size}>mutable</Badge>
        </Tooltip>;
};

<Framed background="https://assets.mirurobotics.com/docs/v04/images/devices/background.jpeg" image="https://assets.mirurobotics.com/docs/v04/images/devices/header:list.png" borderWidth={"24px 0 0 36px"} innerRadius={"8px 0 0 0"} />

A **device** is a machine to which config instances are deployed. This could be an NVIDIA Jetson, Raspberry Pi, industrial PC, or any other computer running your robot's application.

Configurations are deployed to devices via the Miru Agent, a lightweight `systemd` service that runs on your devices, handling the deployment lifecycle of configurations. Visit the [Miru Agent](/developers/agent/overview) documentation for more information.

## Properties

<ParamField path="name" type="string">
  <EditableBadge />

  A human-readable display name that can contain most characters, such as spaces, special characters, and punctuation. Must contain between 1 and 48 characters.

  Examples: `Robot 11`, `ArcticBlaze`, `Warehouse Rover`
</ParamField>

<ParamField path="status" type="enum">
  <MutableBadge />

  The [status](#status) of the device.

  Allowed values:

  * `inactive`
  * `activating`
  * `online`
  * `offline`
</ParamField>

<ParamField path="last_connected_at" type="datetime">
  <MutableBadge />

  {' '}

  <NullableBadge />

  The timestamp of when the device last connected to Miru's servers.

  Examples: `2026-05-25T12:00:00Z`
</ParamField>

<ParamField path="last_disconnected_at" type="datetime">
  <MutableBadge />

  {' '}

  <NullableBadge />

  The timestamp of when the device last disconnected from Miru's servers.

  Examples: `2026-05-25T12:00:00Z`
</ParamField>

<ParamField path="agent version" type="string">
  <MutableBadge />

  {' '}

  <NullableBadge />

  The version of the Miru Agent running on the device.

  The agent version exists only if the device has a status of `online` or `offline`. If the device is `inactive` or `activating`, the agent version is `null`.

  Examples: `v0.6.0`
</ParamField>

<ParamField path="current release" type="Release">
  <MutableBadge />

  {' '}

  <NullableBadge />

  The [release](/concepts/releases#properties) to which the device's current deployment belongs.

  If the device is `inactive` or `activating`, the current release id is `null`. If the device is `online` or `offline`, the current release may still be `null` if the device has no deployed config instances.

  Examples: `rls_123`
</ParamField>

<ParamField path="group" type="Group">
  <EditableBadge />

  {' '}

  <NullableBadge />

  The [group](/concepts/groups/overview#properties) to which the device belongs. If the device's group is not set, the group id is `null`.

  Examples: `grp_123`
</ParamField>

## Status

Devices leverage several states to track their registration and connectivity with the Miru control plane.

| Status       | Description                                                 |
| ------------ | ----------------------------------------------------------- |
| `inactive`   | The Miru Agent has not yet been installed and authenticated |
| `activating` | The Miru Agent is registering itself with Miru's servers    |
| `online`     | Device is currently connected to Miru's servers             |
| `offline`    | Device has lost connection to Miru's servers                |
| `archived`   | Device has been archived and can no longer connect to Miru  |

<img src="https://assets.mirurobotics.com/docs/v04/images/devices/status-lifecycle.light.svg" alt="Device status lifecycle" className="block dark:hidden" />

<img src="https://assets.mirurobotics.com/docs/v04/images/devices/status-lifecycle.dark.svg" alt="Device status lifecycle" className="hidden dark:block" />

Devices begin in the `inactive` state. During the Miru Agent install process, devices briefly enter the `activating` state before transitioning to `online`.

Once the Miru Agent has been provisioned on a device, the device remains `online` or `offline` for the remainder of its existence—devices don't transition back to `inactive` or `activating`.

The only exception to this is when a device is [reprovisioned](/provision-devices/reprovision). During reprovisioning, devices briefly enter the `activating` state before transitioning back to `online`.

A device enters the `archived` state when it is [archived](/concepts/devices/manage#archive-a-device), and
leaves it when it is [restored](/concepts/devices/manage#restore-an-archived-device).

To view a device's status, hover over its name on the Devices page.

<Frame>
  ![Device Status Hover](https://assets.mirurobotics.com/docs/v04/images/devices/status-hover.png)
</Frame>
